<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[24520] trunk: Cleanup of the revisions screen, both on the PHP API side, and the JS.</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://core.trac.wordpress.org/changeset/24520">24520</a></dd>
<dt>Author</dt> <dd>markjaquith</dd>
<dt>Date</dt> <dd>2013-06-26 21:06:50 +0000 (Wed, 26 Jun 2013)</dd>
</dl>
<h3>Log Message</h3>
<pre>Cleanup of the revisions screen, both on the PHP API side, and the JS.
* Much simpler PHP API
* Cleaner and more Backbone-y JS API
* Consequently, does batch queries; this now scales up to hundreds of revisions
Currently missing, but much easier considering the cleaned up base:
* Compare two mode
* RTL
props koopersmith, nacin, adamsilverstein, ocean90. see <a href="http://core.trac.wordpress.org/ticket/24425">#24425</a></pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkwpadminadminajaxphp">trunk/wp-admin/admin-ajax.php</a></li>
<li><a href="#trunkwpadmincsswpadmincss">trunk/wp-admin/css/wp-admin.css</a></li>
<li><a href="#trunkwpadminincludesajaxactionsphp">trunk/wp-admin/includes/ajax-actions.php</a></li>
<li><a href="#trunkwpadminjsrevisionsjs">trunk/wp-admin/js/revisions.js</a></li>
<li><a href="#trunkwpadminrevisionphp">trunk/wp-admin/revision.php</a></li>
<li><a href="#trunkwpincludesrevisionphp">trunk/wp-includes/revision.php</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkwpadminincludesrevisionphp">trunk/wp-admin/includes/revision.php</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkwpadminadminajaxphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-admin/admin-ajax.php (24519 => 24520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-admin/admin-ajax.php 2013-06-26 20:42:01 UTC (rev 24519)
+++ trunk/wp-admin/admin-ajax.php 2013-06-26 21:06:50 UTC (rev 24520)
</span><span class="lines">@@ -42,7 +42,7 @@
</span><span class="cx">
</span><span class="cx"> $core_actions_get = array(
</span><span class="cx"> 'fetch-list', 'ajax-tag-search', 'wp-compression-test', 'imgedit-preview', 'oembed-cache',
</span><del>- 'autocomplete-user', 'dashboard-widgets', 'logged-in', 'revisions-data'
</del><ins>+ 'autocomplete-user', 'dashboard-widgets', 'logged-in',
</ins><span class="cx"> );
</span><span class="cx">
</span><span class="cx"> $core_actions_post = array(
</span><span class="lines">@@ -56,7 +56,7 @@
</span><span class="cx"> 'save-widget', 'set-post-thumbnail', 'date_format', 'time_format', 'wp-fullscreen-save-post',
</span><span class="cx"> 'wp-remove-post-lock', 'dismiss-wp-pointer', 'upload-attachment', 'get-attachment',
</span><span class="cx"> 'query-attachments', 'save-attachment', 'save-attachment-compat', 'send-link-to-editor',
</span><del>- 'send-attachment-to-editor', 'save-attachment-order', 'heartbeat',
</del><ins>+ 'send-attachment-to-editor', 'save-attachment-order', 'heartbeat', 'get-revision-diffs',
</ins><span class="cx"> );
</span><span class="cx">
</span><span class="cx"> // Register core Ajax calls.
</span></span></pre></div>
<a id="trunkwpadmincsswpadmincss"></a>
<div class="modfile"><h4>Modified: trunk/wp-admin/css/wp-admin.css (24519 => 24520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-admin/css/wp-admin.css 2013-06-26 20:42:01 UTC (rev 24519)
+++ trunk/wp-admin/css/wp-admin.css 2013-06-26 21:06:50 UTC (rev 24520)
</span><span class="lines">@@ -3481,7 +3481,49 @@
</span><span class="cx"> /*------------------------------------------------------------------------------
</span><span class="cx"> 11.2 - Post Revisions
</span><span class="cx"> ------------------------------------------------------------------------------*/
</span><ins>+.revisions .spinner {
+ float: none;
+ margin: 100px auto;
+}
</ins><span class="cx">
</span><ins>+.revisions.loading .spinner {
+ display: block;
+}
+
+.revisions-control-frame,
+.revisions-diff-frame {
+ position: relative;
+}
+
+.revisions-controls {
+ height: 60px;
+ padding: 40px 0 20px;
+ border-bottom: 1px solid #dfdfdf;
+ margin-bottom: 10px;
+}
+
+.revisions-meta {
+ margin-top: 15px;
+}
+.revision-toggle-compare-mode {
+ position: absolute;
+ top: 0;
+ right: 0;
+}
+
+.revisions-previous {
+ float: left;
+}
+
+.revisions-next {
+ float: right;
+}
+
+.wp-slider {
+ width: 70%;
+ margin: 6px auto 0;
+}
+
</ins><span class="cx"> /* Revision meta box */
</span><span class="cx"> .post-revisions li img,
</span><span class="cx"> #revisions-meta-restored img {
</span><span class="lines">@@ -3527,13 +3569,6 @@
</span><span class="cx"> position: relative;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-#toggle-revision-compare-mode {
- position: absolute;
- top: 0;
- right: 0;
- padding: 9px 9px 0 0;
-}
-
</del><span class="cx"> #loading-status {
</span><span class="cx"> display: none;
</span><span class="cx"> position: absolute;
</span><span class="lines">@@ -3551,24 +3586,6 @@
</span><span class="cx"> padding: 20px 0;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-#diff-next-revision,
-#diff-previous-revision {
- margin-top: -.4em; /* Same line as the slider (height: .8em) */
-}
-
-#diff-next-revision {
- float: right;
-}
-
-#diff-previous-revision {
- float: left;
-}
-
-#diff-slider {
- width: 70%;
- margin: 0 auto;
-}
-
</del><span class="cx"> .comparetwo #diff-slider {
</span><span class="cx"> width: 95%;
</span><span class="cx"> }
</span><span class="lines">@@ -3588,7 +3605,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> #diff-title-to strong {
</span><del>- display: none;
</del><ins>+ display: inline;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> .comparing-two-revisions #diff-title-to strong {
</span><span class="lines">@@ -3605,6 +3622,7 @@
</span><span class="cx"> -webkit-border-radius: 3px;
</span><span class="cx"> border-radius: 3px;
</span><span class="cx"> padding: 5px 200px 5px 5px;
</span><ins>+ clear: both;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> .diff-header {
</span></span></pre></div>
<a id="trunkwpadminincludesajaxactionsphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-admin/includes/ajax-actions.php (24519 => 24520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-admin/includes/ajax-actions.php 2013-06-26 20:42:01 UTC (rev 24519)
+++ trunk/wp-admin/includes/ajax-actions.php 2013-06-26 21:06:50 UTC (rev 24520)
</span><span class="lines">@@ -2082,219 +2082,31 @@
</span><span class="cx"> wp_send_json($response);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-function wp_ajax_revisions_data() {
- check_ajax_referer( 'revisions-ajax-nonce', 'nonce' );
</del><ins>+function wp_ajax_get_revision_diffs() {
+ require ABSPATH . 'wp-admin/includes/revision.php';
</ins><span class="cx">
</span><del>- $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;
</del><ins>+ // check_ajax_referer( 'revisions-ajax-nonce', 'nonce' );
</ins><span class="cx">
</span><del>- $all_the_revisions = array();
- if ( ! $post_id )
- $post_id = $compare_to;
</del><ins>+ if ( ! $post = get_post( (int) $_REQUEST['post_id'] ) )
+ wp_send_json_error();
</ins><span class="cx">
</span><del>- if ( ! current_user_can( 'read_post', $post_id ) )
- continue;
</del><ins>+ if ( ! current_user_can( 'read_post', $post->ID ) )
+ wp_send_json_error();
</ins><span class="cx">
</span><del>- if ( ! $revisions = wp_get_post_revisions( $post_id ) )
- return;
</del><ins>+ // Really just pre-loading the cache here.
+ if ( ! $revisions = wp_get_post_revisions( $post->ID ) )
+ wp_send_json_error();
</ins><span class="cx">
</span><del>- $left_revision = get_post( $compare_to );
</del><ins>+ $return = array();
+ @set_time_limit( count( $_REQUEST['compare'] ) );
</ins><span class="cx">
</span><del>- // single model fetch mode
- // return the diff of a single revision comparison
- if ( $single_revision_id ) {
- $right_revision = get_post( $single_revision_id );
</del><ins>+ foreach ( $_REQUEST['compare'] as $compare_key ) {
+ list( $compare_from, $compare_to ) = explode( ':', $compare_key ); // from:to
</ins><span class="cx">
</span><del>- if ( ! $compare_to )
- $left_revision = get_post( $post_id );
-
- // 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
</del><ins>+ $return[] = array(
+ 'id' => $compare_key,
+ 'fields' => wp_get_revision_ui_diff( $post, $compare_from, $compare_to ),
</ins><span class="cx"> );
</span><del>-
- 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();
</del><ins>+ }
+ wp_send_json_success( $return );
</ins><span class="cx"> }
</span></span></pre></div>
<a id="trunkwpadminincludesrevisionphp"></a>
<div class="addfile"><h4>Added: trunk/wp-admin/includes/revision.php (0 => 24520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-admin/includes/revision.php (rev 0)
+++ trunk/wp-admin/includes/revision.php 2013-06-26 21:06:50 UTC (rev 24520)
</span><span class="lines">@@ -0,0 +1,100 @@
</span><ins>+<?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 && strtotime( $compare_from->post_date_gmt ) > strtotime( $compare_to->post_date_gmt ) ) {
+ $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' );
+
+ $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[] = array(
+ 'id' => $field,
+ 'name' => $name,
+ 'diff' => $diff,
+ );
+ }
+ }
+ return $return;
+}
+
+function wp_prepare_revisions_for_js( $post, $selected_revision_id ) {
+ $post = get_post( $post );
+ $revisions = array();
+ $current = current_time( 'timestamp' );
+
+ $revisions = wp_get_post_revisions( $post->ID );
+
+ cache_users( wp_list_pluck( $revisions, 'post_author' ) );
+
+ foreach ( $revisions as $revision ) {
+ $modified_gmt = strtotime( $revision->post_modified_gmt );
+ $restore_link = wp_nonce_url(
+ add_query_arg(
+ array( 'revision' => $revision->ID,
+ 'action' => 'restore' ),
+ admin_url( 'revision.php' )
+ ),
+ "restore-post_{$revision->ID}"
+ );
+ $revisions[ $revision->ID ] = array(
+ 'id' => $revision->ID,
+ 'title' => get_the_title( $post->ID ),
+ 'author' => array(
+ 'id' => (int) $revision->post_author,
+ 'avatar' => get_avatar( $revision->post_author, 24 ),
+ 'name' => get_the_author_meta( 'display_name', $revision->post_author ),
+ ),
+ 'date' => date_i18n( __( 'M j, Y @ G:i' ), $modified_gmt ),
+ 'dateShort' => date_i18n( _x( 'j M @ G:i', 'revision date short format' ), $modified_gmt ),
+ 'timeAgo' => human_time_diff( $modified_gmt, $current ),
+ 'autosave' => wp_is_post_autosave( $revision ),
+ 'current' => $revision->post_modified_gmt === $post->post_modified_gmt,
+ 'restoreUrl' => urldecode( $restore_link ),
+ );
+ }
+
+ return array(
+ 'postId' => $post->ID,
+ 'nonce' => wp_create_nonce( 'revisions-ajax-nonce' ),
+ 'revisionData' => array_values( $revisions ),
+ 'selectedRevision' => $selected_revision_id,
+ );
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkwpadminjsrevisionsjs"></a>
<div class="modfile"><h4>Modified: trunk/wp-admin/js/revisions.js (24519 => 24520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-admin/js/revisions.js 2013-06-26 20:42:01 UTC (rev 24519)
+++ trunk/wp-admin/js/revisions.js 2013-06-26 21:06:50 UTC (rev 24520)
</span><span class="lines">@@ -1,283 +1,207 @@
</span><span class="cx"> window.wp = window.wp || {};
</span><span class="cx">
</span><span class="cx"> (function($) {
</span><del>- var Revision, Revisions, Diff, revisions;
</del><ins>+ var revisions;
</ins><span class="cx">
</span><del>- revisions = wp.revisions = function() {
- Diff = revisions.Diff = new Diff();
- };
</del><ins>+ revisions = wp.revisions = { model: {}, view: {}, controller: {} };
</ins><span class="cx">
</span><del>- _.extend( revisions, { model: {}, view: {}, controller: {} } );
-
</del><span class="cx"> // Link settings.
</span><del>- revisions.model.settings = typeof wpRevisionsSettings === 'undefined' ? {} : wpRevisionsSettings;
</del><ins>+ revisions.settings = typeof _wpRevisionsSettings === 'undefined' ? {} : _wpRevisionsSettings;
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> /**
</span><span class="cx"> * ========================================================================
</span><del>- * CONTROLLERS
</del><ins>+ * MODELS
</ins><span class="cx"> * ========================================================================
</span><span class="cx"> */
</span><ins>+ revisions.model.Slider = Backbone.Model.extend({
+ defaults: {
+ value: 0,
+ min: 0,
+ max: 1,
+ step: 1
+ }
+ });
</ins><span class="cx">
</span><del>- /**
- * wp.revisions.controller.Diff
- *
- * Controlls the diff
- */
- Diff = revisions.controller.Diff = Backbone.Model.extend( {
- rightDiff: 1,
- leftDiff: 1,
- revisions: null,
- leftHandleRevisions: null,
- rightHandleRevisions: null,
- revisionsInteractions: null,
- autosaves: true,
- showSplitView: true,
- singleRevision: true,
- leftModelLoading: false, // keep track of model loads
- rightModelLoading: false, // disallow slider interaction, also repeat loads, while loading
- tickmarkView: null, // the slider tickmarks
- slider: null, // the slider instance
</del><ins>+ revisions.model.Revision = Backbone.Model.extend({});
</ins><span class="cx">
</span><del>- constructor: function() {
- var self = this;
- this.slider = new revisions.view.Slider();
</del><ins>+ revisions.model.Revisions = Backbone.Collection.extend({
+ model: revisions.model.Revision,
</ins><span class="cx">
</span><del>- if ( null === this.revisions ) {
- this.revisions = new Revisions(); // set up collection
- this.startRightModelLoading();
-
- this.revisions.fetch({ // load revision data
- success: function() {
- self.stopRightModelLoading();
- self.completeApplicationSetup();
- }
- });
- }
</del><ins>+ comparator: function( revision ) {
+ return revision.id;
</ins><span class="cx"> },
</span><ins>+ });
</ins><span class="cx">
</span><del>- loadDiffs: function( models ) {
- var self = this,
- revisionsToLoad = models.where( { completed: false } ),
- delay = 0,
- totalChanges;
</del><ins>+ revisions.model.Field = Backbone.Model.extend({});
</ins><span class="cx">
</span><del>- // match slider to passed revision_id
- _.each( revisionsToLoad, function( revision ) {
- if ( revision.get( 'ID' ) == revisions.model.settings.revision_id )
- self.rightDiff = self.revisions.indexOf( revision ) + 1;
- });
</del><ins>+ revisions.model.Fields = Backbone.Collection.extend({
+ model: revisions.model.Field
+ });
</ins><span class="cx">
</span><del>- _.each( revisionsToLoad, function( revision ) {
- _.delay( function() {
- revision.fetch( {
- update: true,
- add: false,
- remove: false,
- success: function( model ) {
- model.set( 'completed', true );
</del><ins>+ revisions.model.Diff = Backbone.Model.extend({
+ initialize: function(attributes, options) {
+ var fields = this.get('fields');
+ this.unset('fields');
</ins><span class="cx">
</span><del>- // stop spinner when all models are loaded
- if ( 0 === models.where( { completed: false } ).length )
- self.stopModelLoadingSpinner();
</del><ins>+ this.fields = new revisions.model.Fields( fields );
+ }
+ });
</ins><span class="cx">
</span><del>- totalChanges = model.get( 'linesAdded' ) + model.get( 'linesDeleted' ),
- scopeOfChanges = 'vsmall';
</del><ins>+ revisions.model.Diffs = Backbone.Collection.extend({
+ initialize: function(models, options) {
+ this.revisions = options.revisions;
+ this.requests = {};
+ },
</ins><span class="cx">
</span><del>- // Note: hard coded scope of changes
- // TODO change to dynamic based on range of values
- if ( totalChanges > 1 && totalChanges <= 3 ) {
- scopeOfChanges = 'small';
- } else if ( totalChanges > 3 && totalChanges <= 5 ) {
- scopeOfChanges = 'med';
- } else if ( totalChanges > 5 && totalChanges <= 10 ) {
- scopeOfChanges = 'large';
- } else if ( totalChanges > 10 ) {
- scopeOfChanges = 'vlarge';
- }
- model.set( 'scopeOfChanges', scopeOfChanges );
- if ( 0 !== self.rightDiff &&
- model.get( 'ID' ) === self.revisions.at( self.rightDiff - 1 ).get( 'ID' ) ) {
- // reload if current model refreshed
- self.revisionView.render();
- }
- self.tickmarkView.render();
- }
- } );
- }, delay ) ;
- delay = delay + 150; // stagger model loads to avoid hammering server with requests
</del><ins>+ model: revisions.model.Diff,
+
+ ensure: function( id, context ) {
+ var diff = this.get( id );
+ var request = this.requests[ id ];
+ var deferred = $.Deferred();
+ var ids = {};
+
+ if ( diff ) {
+ deferred.resolveWith( context, [ diff ] );
+ } else {
+ this.trigger( 'ensure:load', ids );
+ _.each( ids, _.bind( function(id) {
+ // Remove anything that has an ongoing request
+ if ( this.requests[ id ] )
+ delete ids[ id ];
+ }, this ) );
+ if ( ! request ) {
+ // Always include the ID that started this ensure
+ ids[ id ] = true;
+ request = this.load( _.keys( ids ) );
</ins><span class="cx"> }
</span><del>- );
- },
</del><span class="cx">
</span><del>- startLeftModelLoading: function() {
- this.leftModelLoading = true;
- $('#revision-diff-container').addClass('left-model-loading');
- },
</del><ins>+ request.done( _.bind( function() {
+ deferred.resolveWith( context, [ this.get( id ) ] );
+ }, this ) );
+ }
</ins><span class="cx">
</span><del>- stopLeftModelLoading: function() {
- this.leftModelLoading = false;
</del><ins>+ return deferred.promise();
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- startRightModelLoading: function() {
- this.rightModelLoading = true;
- $('#revision-diff-container').addClass('right-model-loading');
</del><ins>+ loadNew: function( comparisons ) {
+ comparisons = _.object( comparisons, comparisons );
+ _.each( comparisons, _.bind( function( id ) {
+ // Exists
+ if ( this.get( id ) )
+ delete comparisons[ id ];
+ }, this ) );
+ comparisons = _.toArray( comparisons );
+ return this.load( comparisons );
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- stopRightModelLoading: function() {
- this.rightModelLoading = false;
</del><ins>+ load: function( comparisons ) {
+ // Our collection should only ever grow, never shrink, so remove: false
+ return this.fetch({ data: { compare: comparisons }, remove: false });
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- stopModelLoadingSpinner: function() {
- $('#revision-diff-container').removeClass('right-model-loading');
- $('#revision-diff-container').removeClass('left-model-loading');
- },
</del><ins>+/**/
+ loadLast: function( num ) {
+ num = num || 1;
+ var ids = this.getProximalDiffIds();
+ ids = _.last( ids, num );
</ins><span class="cx">
</span><del>- reloadModel: function() {
- if ( this.singleRevision ) {
- this.reloadModelSingle();
- } else {
- this.reloadLeftRight();
</del><ins>+ if ( ids.length ) {
+ return this.loadNew( ids );
</ins><span class="cx"> }
</span><span class="cx"> },
</span><span class="cx">
</span><del>- // load the models for the single handle mode
- reloadModelSingle: function() {
- var self = this;
</del><ins>+ loadLastUnloaded: function( num ) {
+ num = num || 1;
+ var ids = this.getUnloadedProximalDiffIds();
+ ids = _.last( ids, num );
</ins><span class="cx">
</span><del>- self.startRightModelLoading();
</del><ins>+ if ( ids.length ) {
+ return this.loadNew( ids );
+ }
+ },
</ins><span class="cx">
</span><del>- self.revisions.reload({
- options: {
- 'showAutosaves': self.autosaves,
- 'showSplitView': self.showSplitView
- },
</del><ins>+ getProximalDiffIds: function() {
+ var previous = 0, ids = [];
+ this.revisions.each( _.bind( function(revision) {
+ ids.push( previous + ':' + revision.id );
+ previous = revision.id;
+ }, this ) );
+ return ids;
+ },
</ins><span class="cx">
</span><del>- success: function() {
- var revisionCount = self.revisions.length;
- self.revisionView.model = self.revisions;
- self.revisionView.render();
- self.loadDiffs( self.revisions );
- self.tickmarkView.model = self.revisions;
- self.tickmarkView.render();
- self.slider.refresh({
- 'max': revisionCount - 1, // slider starts at 0 in single handle mode
- 'value': self.rightDiff - 1 // slider starts at 0 in single handle mode
- }, true);
- },
</del><ins>+ getUnloadedProximalDiffIds: function() {
+ var comparisons = this.getProximalDiffIds();
+ comparisons = _.object( comparisons, comparisons );
+ _.each( comparisons, _.bind( function( id ) {
+ // Exists
+ if ( this.get( id ) )
+ delete comparisons[ id ];
+ }, this ) );
+ return _.toArray( comparisons );
+ },
</ins><span class="cx">
</span><del>- error: function() {
- self.stopRightModelLoading();
- }
- });
</del><ins>+ loadAllBy: function( chunkSize ) {
+ chunkSize = chunkSize || 20;
+ var unloaded = this.getUnloadedProximalDiffIds();
+ if ( unloaded.length ) {
+ return this.loadLastUnloaded( chunkSize ).always( _.bind( function() {
+ this.loadAllBy( chunkSize );
+ }, this ) );
+ }
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- // load the models for the left handle (the right handler has moved)
- reloadLeft: function() {
- var self = this;
- self.startLeftModelLoading();
- self.leftHandleRevisions = new Revisions( {}, {
- 'compareTo': self.revisions.at( self.rightDiff - 1 ).get( 'ID' ), // diff and model count off by 1
- 'showAutosaves': self.autosaves,
- 'showSplitView': self.showSplitView,
- 'rightHandleAt': self.rightDiff
- });
</del><ins>+ sync: function( method, model, options ) {
+ if ( 'read' === method ) {
+ options = options || {};
+ options.context = this;
+ options.data = _.extend( options.data || {}, {
+ action: 'get-revision-diffs',
+ post_id: revisions.settings.postId
+ });
</ins><span class="cx">
</span><del>- self.leftHandleRevisions.fetch({
- success: function(){
- self.stopLeftModelLoading();
- self.loadDiffs( self.leftHandleRevisions );
- self.tickmarkView.model = self.leftHandleRevisions;
- self.slider.refresh({
- 'max': self.revisions.length
</del><ins>+ var deferred = wp.xhr.send( options );
+ var requests = this.requests;
+
+ // Record that we're requesting each diff.
+ if ( options.data.compare ) {
+ _.each( options.data.compare, function( id ) {
+ requests[ id ] = deferred;
</ins><span class="cx"> });
</span><del>- // ensure right handle not beyond length
- if ( self.rightDiff > self.revisions.length )
- self.rightDiff = self.revisions.length;
- },
-
- error: function() {
- self.stopLeftModelLoading();
</del><span class="cx"> }
</span><del>- });
- },
</del><span class="cx">
</span><del>- // load the models for the right handle (the left handle has moved)
- reloadRight: function() {
- var self = this;
- self.startRightModelLoading();
- self.rightHandleRevisions = new Revisions( {}, {
- 'compareTo': self.revisions.at( self.leftDiff - 1 ).get( 'ID' ), // diff and model count off by 1
- 'showAutosaves': self.autosaves,
- 'showSplitView': self.showSplitView,
- 'leftHandleAt': self.leftDiff
- });
</del><ins>+ // When the request completes, clear the stored request.
+ deferred.always( function() {
+ if ( options.data.compare ) {
+ _.each( options.data.compare, function( id ) {
+ delete requests[ id ];
+ });
+ }
+ });
</ins><span class="cx">
</span><del>- self.rightHandleRevisions.fetch({
- success: function(){
- self.stopRightModelLoading();
- self.loadDiffs( self.rightHandleRevisions );
- self.tickmarkView.model = self.rightHandleRevisions;
- self.slider.refresh({
- 'max': self.revisions.length
- }, true);
- },
</del><ins>+ return deferred;
</ins><span class="cx">
</span><del>- error: function( response ) {
- self.stopRightModelLoading();
- }
- });
</del><ins>+ // Otherwise, fall back to `Backbone.sync()`.
+ } else {
+ return Backbone.Model.prototype.sync.apply( this, arguments );
+ }
+ }
+ });
</ins><span class="cx">
</span><del>- },
</del><span class="cx">
</span><del>- /**
- * reloadLeftRight reload models for both the left and right handles
- */
- reloadLeftRight: function() {
- this.startRightModelLoading();
- this.startLeftModelLoading();
- this.reloadLeft();
- this.reloadRight();
- },
</del><ins>+ revisions.model.FrameState = Backbone.Model.extend({
+ initialize: function( attributes, options ) {
+ this.revisions = options.revisions;
+ this.diffs = new revisions.model.Diffs( [], {revisions: this.revisions} );
</ins><span class="cx">
</span><del>- disabledButtonCheck: function( val ) {
- var maxVal = this.revisions.length - 1,
- next = ! isRtl ? $( '#next' ) : $( '#previous' ),
- prev = ! isRtl ? $( '#previous' ) : $( '#next' );
-
- // Disable "Next" button if you're on the last node
- if ( maxVal === val )
- next.prop( 'disabled', true );
- else
- next.prop( 'disabled', false );
-
- // Disable "Previous" button if you're on the 0 node
- if ( 0 === val )
- prev.prop( 'disabled', true );
- else
- prev.prop( 'disabled', false );
</del><ins>+ this.listenTo( this, 'change:from change:to', this.updateDiffId );
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- /**
- * completeApplicationSetup finishes loading all views once the initial model load is complete
- */
- completeApplicationSetup: function() {
- this.revisionView = new revisions.view.Diff({
- model: this.revisions
- });
- this.revisionView.render(); // render the revision view
-
- this.loadDiffs( this.revisions ); // get the actual revisions data
-
- this.revisionsInteractions = new revisions.view.Interact({
- model: this.revisions
- });
- this.revisionsInteractions.render(); // render the interaction view
-
- this.tickmarkView = new revisions.view.Tickmarks({
- model: this.revisions
- });
- this.tickmarkView.render(); // render the tickmark view
</del><ins>+ updateDiffId: function() {
+ var from = this.get( 'from' );
+ var to = this.get( 'to' );
+ this.set( 'diffId', (from ? from.id : '0') + ':' + to.id );
</ins><span class="cx"> }
</span><span class="cx"> });
</span><span class="cx">
</span><span class="lines">@@ -288,534 +212,286 @@
</span><span class="cx"> * ========================================================================
</span><span class="cx"> */
</span><span class="cx">
</span><del>- /**
- * wp.revisions.view.Slider
- *
- * The slider
- */
- revisions.view.Slider = Backbone.View.extend({
- el: $( '#diff-slider' ),
- singleRevision: true,
</del><ins>+ // The frame view. This contains the entire page.
+ revisions.view.Frame = wp.Backbone.View.extend({
+ tagName: 'div',
+ className: 'revisions',
+ template: wp.template('revisions-frame'),
</ins><span class="cx">
</span><del>- initialize: function( options ) {
- this.options = _.defaults( options || {}, {
- value: 0,
- min: 0,
- max: 1,
- step: 1
</del><ins>+ initialize: function() {
+ this.model = new revisions.model.FrameState({}, {
+ revisions: this.collection
</ins><span class="cx"> });
</span><del>- },
</del><span class="cx">
</span><del>- /**
- * respond to slider slide events
- * Note: in one handle mode, jQuery UI reports leftmost position as 0
- * in two handle mode, jQuery UI Slider reports leftmost position as 1
- */
- slide: function( event, ui ) {
- if ( this.singleRevision ) {
- Diff.rightDiff = ( ui.value + 1 );
- Diff.revisionView.render();
- Diff.disabledButtonCheck( ui.value );
- } else {
- if ( ui.values[0] === ui.values[1] ) // prevent compare to self
- return false;
</del><ins>+ this.listenTo( this.model, 'change:diffId', this.updateDiff );
</ins><span class="cx">
</span><del>- if ( $( ui.handle ).hasClass( 'left-handle' ) ) {
- // Left handler
- if ( Diff.leftModelLoading ) // left model still loading, prevent sliding left handle
- return false;
</del><ins>+ this.views.set( '.revisions-control-frame', new revisions.view.Controls({
+ model: this.model
+ }) );
</ins><span class="cx">
</span><del>- Diff.leftDiff = isRtl ? ui.values[1] : ui.values[0]; // handles are reversed in RTL mode
- } else {
- // Right handler
- if ( Diff.rightModelLoading ) // right model still loading, prevent sliding right handle
- return false;
</del><ins>+ if ( this.model.revisions.length ) {
+ var last = this.model.revisions.last(2);
+ var attributes = { to: last.pop() };
</ins><span class="cx">
</span><del>- Diff.rightDiff = isRtl ? ui.values[0] : ui.values[1]; // handles are reversed in RTL mode
- }
</del><ins>+ if ( last.length )
+ attributes.from = last.pop();
</ins><span class="cx">
</span><del>- Diff.revisionView.render();
</del><ins>+ this.model.set( attributes );
+
+ // Load the rest: first 10, then the rest by 50
+ this.model.diffs.loadLastUnloaded( 10 ).always( _.bind( function() {
+ this.model.diffs.loadAllBy( 50 );
+ }, this ) );
</ins><span class="cx"> }
</span><span class="cx"> },
</span><span class="cx">
</span><del>- /**
- * responds to slider start sliding events
- * in two handle mode stores start position, so if unchanged at stop event no need to reload diffs
- * also swaps in the appropriate models - left handled or right handled
- */
- start: function( event, ui ) {
- // Not needed in one mode
- if ( this.singleRevision )
- return;
</del><ins>+ render: function() {
+ wp.Backbone.View.prototype.render.apply( this, arguments );
</ins><span class="cx">
</span><del>- if ( $( ui.handle ).hasClass( 'left-handle' ) ) {
- // Left handler
- if ( Diff.leftModelLoading ) // left model still loading, prevent sliding left handle
- return false;
</del><ins>+ $('#wpbody-content .wrap').append( this.el );
+ this.views.ready();
</ins><span class="cx">
</span><del>- Diff.revisionView.draggingLeft = true;
</del><ins>+ return this;
+ },
</ins><span class="cx">
</span><del>- if ( Diff.revisionView.model !== Diff.leftHandleRevisions &&
- null !== Diff.leftHandleRevisions ) {
- Diff.revisionView.model = Diff.leftHandleRevisions; // use the left handle models
- Diff.tickmarkView.model = Diff.leftHandleRevisions;
- Diff.tickmarkView.render();
- }
</del><ins>+ updateDiff: function() {
+ this.model.diffs.ensure( this.model.get('diffId'), this ).done( function( diff ) {
+ if ( this.model.get('diffId') !== diff.id )
+ return;
+ this.views.set( '.revisions-diff-frame', new revisions.view.Diff({
+ model: diff
+ }));
+ });
+ }
+ });
</ins><span class="cx">
</span><del>- Diff.leftDiffStart = isRtl ? ui.values[1] : ui.values[0]; // in RTL mode the 'left handle' is the second in the slider, 'right' is first
</del><ins>+ // The control view.
+ // This contains the revision slider, previous/next buttons, and the compare checkbox.
+ revisions.view.Controls = wp.Backbone.View.extend({
+ tagName: 'div',
+ className: 'revisions-controls',
</ins><span class="cx">
</span><del>- } else {
- // Right handler
- if ( Diff.rightModelLoading || 0 === Diff.rightHandleRevisions.length) // right model still loading, prevent sliding right handle
- return false;
</del><ins>+ initialize: function() {
+ // Add the button view
+ this.views.add( new revisions.view.Buttons({
+ model: this.model
+ }));
</ins><span class="cx">
</span><del>- if ( Diff.revisionView.model !== Diff.rightHandleRevisions &&
- null !== Diff.rightHandleRevisions ) {
- Diff.revisionView.model = Diff.rightHandleRevisions; // use the right handle models
- Diff.tickmarkView.model = Diff.rightHandleRevisions;
- Diff.tickmarkView.render();
- }
</del><ins>+ // Add the Slider view
+ this.views.add( new revisions.view.Slider({
+ model: this.model
+ }) );
</ins><span class="cx">
</span><del>- Diff.revisionView.draggingLeft = false;
- Diff.rightDiffStart = isRtl ? ui.values[0] : ui.values[1]; // in RTL mode the 'left handle' is the second in the slider, 'right' is first
- }
- },
</del><ins>+ // Add the Meta view
+ this.views.add( new revisions.view.Meta({
+ model: this.model
+ }) );
+ }
+ });
</ins><span class="cx">
</span><del>- /**
- * responds to slider stop events
- * in two handled mode, if the handle that stopped has moved, reload the diffs for the other handle
- * the other handle compares to this handle's position, so if it changes they need to be recalculated
- */
- stop: function( event, ui ) {
- // Not needed in one mode
- if ( this.singleRevision )
- return;
</del><ins>+ // The meta view.
+ // This contains the revision meta, and the restore button.
+ revisions.view.Meta = wp.Backbone.View.extend({
+ tagName: 'div',
+ className: 'revisions-meta',
+ template: wp.template('revisions-meta'),
</ins><span class="cx">
</span><del>- // calculate and generate a diff for comparing to the left handle
- // and the right handle, swap out when dragging
- if ( $( ui.handle ).hasClass( 'left-handle' ) ) {
- // Left handler
- if ( Diff.leftDiffStart !== isRtl ? ui.values[1] : ui.values[0] ) // in RTL mode the 'left handle' is the second in the slider, 'right' is first
- Diff.reloadRight();
- } else {
- // Right handler
- if ( Diff.rightDiffStart !== isRtl ? ui.values[0] : ui.values[1] ) // in RTL mode the 'left handle' is the second in the slider, 'right' is first
- Diff.reloadLeft();
- }
</del><ins>+ initialize: function() {
+ this.listenTo( this.model, 'change:diffId', this.updateMeta );
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- addTooltip: function( handle, message ) {
- handle.find( '.ui-slider-tooltip' ).html( message );
</del><ins>+ events: {
+ 'click #restore-revision': 'restoreRevision'
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- width: function() {
- return $( '#diff-slider' ).width();
</del><ins>+ restoreRevision: function() {
+ var restoreUrl = this.model.get('to').attributes.restoreUrl.replace(/&/g, '&');
+ document.location = restoreUrl;
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- setWidth: function( width ) {
- $( '#diff-slider' ).width( width );
- },
-
- refresh: function( options, slide ) {
- $( '#diff-slider' ).slider( 'option', options );
-
- // Triggers the slide event
- if ( slide )
- $( '#diff-slider' ).trigger( 'slide' );
-
- Diff.disabledButtonCheck( options.value );
- },
-
- option: function( key ) {
- return $( '#diff-slider' ).slider( 'option', key );
- },
-
- render: function() {
- var self = this;
- // this.$el doesn't work, why?
- $( '#diff-slider' ).slider( {
- slide: $.proxy( self.slide, self ),
- start: $.proxy( self.start, self ),
- stop: $.proxy( self.stop, self )
- } );
-
- // Set options
- this.refresh( this.options );
</del><ins>+ updateMeta: function() {
+ this.$el.html( this.template( this.model.toJSON() ) );
+ if( this.model.get( 'to' ).attributes.current ) {
+ $( '#restore-revision' ).prop( 'disabled', true);
+ } else {
+ $( '#restore-revision' ).prop( 'disabled', false)
+ }
</ins><span class="cx"> }
</span><span class="cx"> });
</span><span class="cx">
</span><del>- /**
- * wp.revisions.view.Tickmarks
- *
- * The slider tickmarks.
- */
- revisions.view.Tickmarks = Backbone.View.extend({
- el: $('#diff-slider-ticks'),
- template: wp.template('revision-ticks'),
- model: Revision,
</del><span class="cx">
</span><del>- resetTicks: function() {
- var sliderMax, sliderWidth, adjustMax, tickWidth, tickCount = 0, aTickWidth, tickMargin, self = this, firstTick, lastTick;
- sliderMax = Diff.slider.option( 'max' );
- sliderWidth = Diff.slider.width();
- adjustMax = Diff.singleRevision ? 0 : 1;
- tickWidth = Math.floor( sliderWidth / ( sliderMax - adjustMax ) );
- tickWidth = ( tickWidth > 50 ) ? 50 : tickWidth; // set minimum and maximum widths for tick marks
- tickWidth = ( tickWidth < 6 ) ? 6 : tickWidth;
- sliderWidth = tickWidth * ( sliderMax - adjustMax ); // calculate the slider width
- aTickWidth = $( '.revision-tick' ).width();
</del><ins>+ // The buttons view.
+ // Encapsulates all of the configuration for the previous/next buttons, and the compare checkbox.
+ revisions.view.Buttons = wp.Backbone.View.extend({
+ tagName: 'div',
+ className: 'revisions-buttons',
+ template: wp.template('revisions-controls'),
</ins><span class="cx">
</span><del>- if ( tickWidth !== aTickWidth ) { // is the width already set correctly?
- $( '.revision-tick' ).each( function() {
- tickMargin = Math.floor( ( tickWidth - $( this ).width() ) / 2 ) + 1;
- $( this ).css( 'border-left', tickMargin + 'px solid #f7f7f7'); // space the ticks out using margins
- $( this ).css( 'border-right', ( tickWidth - tickMargin - $( this ).width() ) + 'px solid #f7f7f7'); // space the ticks out using margins
- });
- firstTick = $( '.revision-tick' ).first(); //cache selectors for optimization
- lastTick = $( '.revision-tick' ).last();
-
- sliderWidth = sliderWidth + Math.ceil( ( tickWidth - ( lastTick.outerWidth() - lastTick.innerWidth() ) ) / 2 ); // room for the last tick
- sliderWidth = sliderWidth + Math.ceil( ( tickWidth - ( firstTick.outerWidth() - firstTick.innerWidth() ) ) / 2 ); // room for the first tick
- firstTick.css( 'border-left', 'none' ); // first tick gets no left border
- lastTick.css( 'border-right', 'none' ); // last tick gets no right border
- }
-
- /**
- * reset the slider width
- */
- Diff.slider.setWidth( sliderWidth );
- $( '.diff-slider-ticks-wrapper' ).width( sliderWidth );
- $( '#diff-slider-ticks' ).width( sliderWidth );
-
- /**
- * go through all ticks, add hover and click interactions
- */
- $( '.revision-tick' ).each( function() {
- Diff.slider.addTooltip ( $( this ), Diff.revisions.at( tickCount++ ).get( 'titleTooltip' ) );
- $( this ).hover(
- function() {
- $( this ).find( '.ui-slider-tooltip' ).show().append('<div class="arrow"></div>');
- },
- function() {
- $( this ).find( '.ui-slider-tooltip' ).hide().find( '.arrow' ).remove();
- }
- );
-
- /**
- * move the slider handle when the tick marks are clicked
- */
- $( this ).on( 'click',
- { tickCount: tickCount }, // pass the tick through so we know where to move the handle
- function( event ) {
- if ( Diff.slider.singleRevision ) { // single handle mode
- Diff.rightDiff = event.data.tickCount; // reposition the right handle
- Diff.slider.refresh({
- value: Diff.rightDiff - 1
- } );
- } else { //compare two mode
- if ( isRtl ) {
- if ( event.data.tickCount < Diff.leftDiff ) { // click was on the 'left' side
- Diff.rightDiff = event.data.tickCount; // set the 'right' handle location
- Diff.reloadLeft(); // reload the left handle comparison models
- } else { // middle or 'right' clicks
- Diff.leftDiff = event.data.tickCount; // set the 'left' handle location
- Diff.reloadRight(); // reload right handle models
- }
- } else {
- if ( event.data.tickCount < Diff.leftDiff ) { // click was on the 'left' side
- Diff.leftDiff = event.data.tickCount; // set the left handle location
- Diff.reloadRight(); // reload the right handle comparison models
- } else { // middle or 'right' clicks
- Diff.rightDiff = event.data.tickCount; // set the right handle location
- Diff.reloadLeft(); // reload left handle models
- }
- }
- Diff.slider.refresh( { // set the slider handle positions
- values: [ isRtl ? Diff.rightDiff : Diff.leftDiff, isRtl ? Diff.leftDiff : Diff.rightDiff ]
- } );
- }
- Diff.revisionView.render(); // render the main view
- } );
- } );
</del><ins>+ initialize: function() {
+ this.$el.html( this.template() )
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- // render the tick mark view
- render: function() {
- var self = this, addHtml;
-
- if ( null !== self.model ) {
- addHtml = "";
- _.each ( self.model.models, function( theModel ) {
- addHtml = addHtml + self.template ( theModel.toJSON() );
- });
- self.$el.html( addHtml );
-
- }
- self.resetTicks();
- return self;
- }
- } );
-
- /**
- * wp.revisions.view.Interact
- *
- * Next/Prev buttons and the slider
- */
- revisions.view.Interact = Backbone.View.extend({
- el: $( '#revision-interact' ),
- template: wp.template( 'revision-interact' ),
-
- // next and previous buttons, only available in compare one mode
</del><span class="cx"> events: {
</span><del>- 'click #next': ! isRtl ? 'nextRevision' : 'previousRevision',
- 'click #previous': ! isRtl ? 'previousRevision' : 'nextRevision'
</del><ins>+ 'click #next': 'nextRevision',
+ 'click #previous': 'previousRevision'
</ins><span class="cx"> },
</span><ins>+
+ gotoModel: function( toIndex ) {
+ var attributes = {
+ to: this.model.revisions.at( isRtl ? this.model.revisions.length - toIndex - 1 : toIndex ) // Reverse directions for Rtl
+ };
+ // If we're at the first revision, unset 'from'.
+ if ( isRtl ? this.model.revisions.length - toIndex - 1 : toIndex ) // Reverse directions for Rtl
+ attributes.from = this.model.revisions.at( isRtl ? this.model.revisions.length - toIndex - 2 : toIndex - 1 );
+ else
+ this.model.unset('from', { silent: true });
</ins><span class="cx">
</span><del>- render: function() {
- var modelcount;
- this.$el.html( this.template );
</del><ins>+ this.model.set( attributes );
+ },
</ins><span class="cx">
</span><del>- modelcount = Diff.revisions.length;
</del><ins>+ nextRevision: function() {
+ var toIndex = this.model.revisions.indexOf( this.model.get( 'to' ) );
+ toIndex = isRtl ? toIndex - 1 : toIndex + 1;
+ this.gotoModel( toIndex );
+ },
+
+ previousRevision: function() {
+ var toIndex = this.model.revisions.indexOf( this.model.get('to') );
+ toIndex = isRtl ? toIndex + 1 : toIndex - 1;
+ this.gotoModel( toIndex );
+ },
</ins><span class="cx">
</span><del>- Diff.slider.singleRevision = Diff.singleRevision;
- Diff.slider.render();
-
- if ( Diff.singleRevision ) {
- Diff.slider.refresh({
- value: Diff.rightDiff - 1, // rightDiff value is off model index by 1
- min: 0,
- max: modelcount - 1
- });
-
- $( '#revision-diff-container' ).removeClass( 'comparing-two-revisions' );
-
- } else {
- Diff.slider.refresh({
- // in RTL mode the 'left handle' is the second in the slider, 'right' is first
- values: [ isRtl ? Diff.rightDiff : Diff.leftDiff, isRtl ? Diff.leftDiff : Diff.rightDiff ],
- min: 1,
- max: modelcount + 1,
- range: true
- });
-
- $( '#revision-diff-container' ).addClass( 'comparing-two-revisions' );
- // in RTL mode the 'left handle' is the second in the slider, 'right' is first
- $( '#diff-slider a.ui-slider-handle' ).first().addClass( isRtl ? 'right-handle' : 'left-handle' );
- $( '#diff-slider a.ui-slider-handle' ).last().addClass( isRtl ? 'left-handle' : 'right-handle' );
-
- }
-
- return this;
</del><ins>+ ready: function() {
+ this.listenTo( this.model, 'change:diffId', this.disabledButtonCheck );
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- // go to the next revision
- nextRevision: function() {
- if ( Diff.rightDiff < this.model.length ) // unless at right boundry
- Diff.rightDiff = Diff.rightDiff + 1 ;
</del><ins>+ // Check to see if the Previous or Next buttons need to be disabled or enabled
+ disabledButtonCheck: function() {
+ var maxVal = isRtl ? 0 : this.model.revisions.length - 1,
+ minVal = isRtl ? this.model.revisions.length - 1 : 0,
+ next = $( '.revisions-next .button' ),
+ previous = $( '.revisions-previous .button' ),
+ val = this.model.revisions.indexOf( this.model.get( 'to' ) );
</ins><span class="cx">
</span><del>- Diff.revisionView.render();
</del><ins>+ // Disable "Next" button if you're on the last node
+ if ( maxVal === val )
+ next.prop( 'disabled', true );
+ else
+ next.prop( 'disabled', false );
</ins><span class="cx">
</span><del>- Diff.slider.refresh({
- value: Diff.rightDiff - 1
- }, true );
</del><ins>+ // Disable "Previous" button if you're on the first node
+ if ( minVal === val )
+ previous.prop( 'disabled', true );
+ else
+ previous.prop( 'disabled', false );
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- // go to the previous revision
- previousRevision: function() {
- if ( Diff.rightDiff > 1 ) // unless at left boundry
- Diff.rightDiff = Diff.rightDiff - 1 ;
</del><span class="cx">
</span><del>- Diff.revisionView.render();
-
- Diff.slider.refresh({
- value: Diff.rightDiff - 1
- }, true );
- }
</del><span class="cx"> });
</span><span class="cx">
</span><del>- /**
- * wp.revisions.view.Diff
- *
- * Diff, compare two checkbox and restore button
- */
- revisions.view.Diff = Backbone.View.extend({
- el: $( '#revisions-diff' ),
- template: wp.template( 'revisions-diff' ),
- draggingLeft: false,
</del><ins>+ // The slider view.
+ // Encapsulates all of the configuration for the jQuery UI slider into a view.
+ revisions.view.Slider = wp.Backbone.View.extend({
+ tagName: 'div',
+ className: 'wp-slider',
</ins><span class="cx">
</span><del>- // the compare two button is in this view, add the interaction here
- events: {
- 'click #compare-two-revisions': 'compareTwo',
- 'click #restore-revision': 'restore'
- },
</del><ins>+ initialize: function() {
+ _.bindAll( this, 'start', 'slide', 'stop' );
</ins><span class="cx">
</span><del>- // render the revisions
- render: function() {
- var addHtml = '', thediff;
</del><ins>+ // Create the slider model from the provided collection data.
+ // TODO: This should actually pull from the model's `to` key.
+ var latestRevisionIndex = this.model.revisions.length - 1;
</ins><span class="cx">
</span><del>- // compare two revisions mode?
- if ( ! Diff.singleRevision ) {
- if ( this.draggingLeft ) {
- thediff = Diff.leftDiff - 1; //leftDiff value is off model index by 1
- if ( this.model.at( thediff ) ) {
- addHtml = this.template( this.model.at( thediff ).toJSON() );
- }
- } else { // dragging right handle
- thediff = Diff.rightDiff - 1; // rightDiff value is off model index by 1
- if ( this.model.at( thediff ) ) {
- addHtml = this.template( this.model.at( thediff ).toJSON() );
- }
- }
- } else { // end compare two revisions mode, eg only one slider handle
- if ( this.model.at( Diff.rightDiff - 1 ) ) { // rightDiff value is off model index by 1
- addHtml = this.template( this.model.at( Diff.rightDiff - 1 ).toJSON() );
- }
- }
- this.$el.html( addHtml );
</del><ins>+ // Find the initially selected revision
+ var initiallySelectedRevisionIndex =
+ this.model.revisions.indexOf(
+ this.model.revisions.findWhere( { id: Number( revisions.settings.selectedRevision ) } ) );
</ins><span class="cx">
</span><del>- if ( this.model.length < 2 ) {
- $( '#diff-slider' ).hide(); // don't allow compare two if fewer than three revisions
- $( '.diff-slider-ticks-wrapper' ).hide();
- }
</del><ins>+ this.settings = new revisions.model.Slider({
+ max: latestRevisionIndex,
+ value: initiallySelectedRevisionIndex,
+ start: this.start,
+ slide: this.slide,
+ stop: this.stop
+ });
+ },
</ins><span class="cx">
</span><del>- this.toggleCompareTwoCheckbox();
</del><ins>+ ready: function() {
+ this.$el.slider( this.settings.toJSON() );
+ this.settings.on( 'change', function( model, options ) {
+ // Apply changes to slider settings here.
+ this.$el.slider( { value: this.model.revisions.indexOf( this.model.get( 'to' ) ) } ); // Set handle to current to model
+ }, this );
+ // Reset to the initially selected revision
+ this.slide( '', this.settings.attributes );
</ins><span class="cx">
</span><del>- // hide the restore button when on the last sport/current post data
- $( '#restore-revision' ).toggle( ! Diff.revisions.at( Diff.rightDiff - 1 ).get( 'isCurrent' ) );
</del><ins>+ // Listen for changes in the diffId
+ this.listenTo( this.model, 'change:diffId', this.diffIdChanged );
</ins><span class="cx">
</span><del>- return this;
</del><span class="cx"> },
</span><span class="cx">
</span><del>- toggleCompareTwoCheckbox: function() {
- // don't allow compare two if fewer than three revisions
- if ( this.model.length < 3 )
- $( '#toggle-revision-compare-mode' ).hide();
-
- $( '#compare-two-revisions' ).prop( 'checked', ! Diff.singleRevision );
</del><ins>+ diffIdChanged: function() {
+ // Reset the view settings when diffId is changed
+ this.settings.set( { 'value': this.model.revisions.indexOf( this.model.get( 'to' ) ) } );
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- // turn on/off the compare two mode
- compareTwo: function() {
- if ( $( '#compare-two-revisions' ).is( ':checked' ) ) { // compare 2 mode
- Diff.singleRevision = false ;
</del><ins>+ start: function( event, ui ) {
+ // Track the mouse position to enable smooth dragging, overrides default jquery ui step behaviour
+ $( window ).mousemove( function( e ) {
+ var sliderLeft = $( '.wp-slider' ).offset().left,
+ sliderRight = sliderLeft + $( '.wp-slider' ).width();
</ins><span class="cx">
</span><del>- // in RTL mode handles are swapped, so boundary checks are different;
- if ( isRtl ){
- Diff.leftDiff = Diff.revisions.length; // put the left handle at the rightmost position, representing current revision
-
- if ( Diff.revisions.length === Diff.rightDiff ) // make sure 'left' handle not in rightmost slot
- Diff.rightDiff = Diff.rightDiff - 1;
</del><ins>+ // Follow mouse movements, as long as handle remains inside slider
+ if ( e.clientX < sliderLeft ) {
+ $( ui.handle ).css( 'left', 0 ); // Mouse to left of slider
+ } else if ( e.clientX > sliderRight ) {
+ $( ui.handle ).css( 'left', sliderRight - sliderLeft); // Mouse to right of slider
</ins><span class="cx"> } else {
</span><del>- if ( 1 === Diff.rightDiff ) // make sure right handle not in leftmost slot
- Diff.rightDiff = 2;
</del><ins>+ $( ui.handle ).css( 'left', e.clientX - sliderLeft ); // Mouse in slider
</ins><span class="cx"> }
</span><ins>+ } ); // End mousemove
+ },
</ins><span class="cx">
</span><del>- Diff.revisionView.draggingLeft = false;
</del><ins>+ slide: function( event, ui ) {
+ var attributes = {
+ to: this.model.revisions.at( isRtl ? this.model.revisions.length - ui.value - 1 : ui.value ) // Reverse directions for Rtl
+ };
</ins><span class="cx">
</span><del>- revisions.model.settings.revision_id = ''; // reset passed revision id so switching back to one handle mode doesn't re-select revision
- Diff.reloadLeftRight(); // load diffs for left and right handles
- Diff.revisionView.model = Diff.rightHandleRevisions;
</del><ins>+ // If we're at the first revision, unset 'from'.
+ if ( isRtl ? this.model.revisions.length - ui.value - 1 : ui.value ) // Reverse directions for Rtl
+ attributes.from = this.model.revisions.at( isRtl ? this.model.revisions.length - ui.value - 2 : ui.value - 1 );
+ else
+ this.model.unset('from', { silent: true });
</ins><span class="cx">
</span><del>- } else { // compare one mode
- Diff.singleRevision = true;
- Diff.revisionView.draggingLeft = false;
- Diff.reloadModelSingle();
- }
- Diff.revisionsInteractions.render();
- Diff.tickmarkView.render();
</del><ins>+ this.model.set( attributes );
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- restore: function() {
- document.location = $( '#restore-revision' ).data( 'restoreLink' );
</del><ins>+ stop: function( event, ui ) {
+ $( window ).unbind( 'mousemove' ); // Stop tracking the mouse
+ // Reset settings pops handle back to the step position
+ this.settings.trigger( 'change' );
</ins><span class="cx"> }
</span><span class="cx"> });
</span><span class="cx">
</span><ins>+ // The diff view.
+ // This is the view for the current active diff.
+ revisions.view.Diff = wp.Backbone.View.extend({
+ tagName: 'div',
+ className: 'revisions-diff',
+ template: wp.template('revisions-diff'),
</ins><span class="cx">
</span><del>- /**
- * ========================================================================
- * MODELS
- * ========================================================================
- */
-
- /**
- * wp.revisions.Revision
- */
- Revision = revisions.model.Revision = Backbone.Model.extend({
- idAttribute: 'ID',
-
- defaults: {
- ID: 0,
- titleTo: '',
- titleTooltip: '',
- titleFrom: '',
- diff: '<div class="diff-loading"><div class="spinner"></div></div>',
- restoreLink: '',
- completed: false,
- linesAdded: 0,
- linesDeleted: 0,
- scopeOfChanges: 'none',
- previousID: 0,
- isCurrent: false
- },
-
- url: function() {
- if ( Diff.singleRevision ) {
- return ajaxurl +
- '?action=revisions-data' +
- '&show_autosaves=true' +
- '&show_split_view=true' +
- '&nonce=' + revisions.model.settings.nonce +
- '&single_revision_id=' + this.id +
- '&compare_to=' + this.get( 'previousID' ) +
- '&post_id=' + revisions.model.settings.post_id;
- } else {
- return this.collection.url() + '&single_revision_id=' + this.id;
- }
-
</del><ins>+ // Generate the options to be passed to the template.
+ prepare: function() {
+ return _.extend({ fields: this.model.fields.toJSON() }, this.options );
</ins><span class="cx"> }
</span><span class="cx"> });
</span><span class="cx">
</span><del>- /**
- * wp.revisions.Revisions
- */
- Revisions = revisions.Revisions = Backbone.Collection.extend({
- model: Revision,
</del><ins>+ // Initialize the revisions UI.
+ revisions.init = function() {
+ revisions.view.frame = new revisions.view.Frame({
+ collection: new revisions.model.Revisions( revisions.settings.revisionData )
+ }).render();
+ };
</ins><span class="cx">
</span><del>- initialize: function( models, options ) {
- this.options = _.defaults( options || {}, {
- 'compareTo': revisions.model.settings.post_id,
- 'post_id': revisions.model.settings.post_id,
- 'showAutosaves': true,
- 'showSplitView': true,
- 'rightHandleAt': 0,
- 'leftHandleAt': 0,
- 'nonce': revisions.model.settings.nonce
- });
- },
-
- url: function() {
- return ajaxurl +
- '?action=revisions-data' +
- '&compare_to=' + this.options.compareTo + // revision are we comparing to
- '&post_id=' + this.options.post_id + // the post id
- '&show_autosaves=' + this.options.showAutosaves + // show or hide autosaves
- '&show_split_view=' + this.options.showSplitView + // show in split view or single column view
- '&right_handle_at=' + this.options.rightHandleAt + // mark point for comparison list
- '&left_handle_at=' + this.options.leftHandleAt + // mark point for comparison list
- '&nonce=' + this.options.nonce;
- },
-
- reload: function( options ) {
- this.options = _.defaults( options.options || {}, this.options );
-
- this.fetch({
- success: options.success || null,
- error: options.error || null
- });
- }
-
- } );
-
- $( wp.revisions );
-
</del><ins>+ $( revisions.init );
</ins><span class="cx"> }(jQuery));
</span></span></pre></div>
<a id="trunkwpadminrevisionphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-admin/revision.php (24519 => 24520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-admin/revision.php 2013-06-26 20:42:01 UTC (rev 24519)
+++ trunk/wp-admin/revision.php 2013-06-26 21:06:50 UTC (rev 24520)
</span><span class="lines">@@ -8,6 +8,12 @@
</span><span class="cx">
</span><span class="cx"> /** WordPress Administration Bootstrap */
</span><span class="cx"> require_once('./admin.php');
</span><ins>+
+require ABSPATH . 'wp-admin/includes/revision.php';
+
+// wp_get_revision_ui_diff( $post, $compare_from, $compare_to )
+// wp_prepare_revisions_for_js( $post )
+
</ins><span class="cx"> wp_reset_vars( array( 'revision', 'action' ) );
</span><span class="cx">
</span><span class="cx"> $revision_id = absint( $revision );
</span><span class="lines">@@ -21,7 +27,6 @@
</span><span class="cx"> if ( ! current_user_can( 'edit_post', $revision->post_parent ) )
</span><span class="cx"> break;
</span><span class="cx">
</span><del>-
</del><span class="cx"> if ( ! $post = get_post( $revision->post_parent ) )
</span><span class="cx"> break;
</span><span class="cx">
</span><span class="lines">@@ -77,16 +82,8 @@
</span><span class="cx"> $parent_file = $submenu_file = 'edit.php';
</span><span class="cx">
</span><span class="cx"> wp_enqueue_script( 'revisions' );
</span><ins>+wp_localize_script( 'revisions', '_wpRevisionsSettings', wp_prepare_revisions_for_js( $post, $revision_id ) );
</ins><span class="cx">
</span><del>-
-$settings = array(
- 'post_id' => $post->ID,
- 'nonce' => wp_create_nonce( 'revisions-ajax-nonce' ),
- 'revision_id' => $revision_id
-);
-
-wp_localize_script( 'revisions', 'wpRevisionsSettings', $settings );
-
</del><span class="cx"> /* Revisions Help Tab */
</span><span class="cx">
</span><span class="cx"> $revisions_overview = '<p>' . __( 'This screen is used for managing your content revisions.' ) . '</p>';
</span><span class="lines">@@ -114,24 +111,73 @@
</span><span class="cx">
</span><span class="cx"> <div class="wrap">
</span><span class="cx"> <?php screen_icon(); ?>
</span><del>- <div id="revision-diff-container" class="current-version right-model-loading">
- <h2 class="long-header"><?php echo $h2; ?></h2>
</del><ins>+ <h2 class="long-header"><?php echo $h2; ?></h2>
+</div>
</ins><span class="cx">
</span><del>- <div id="loading-status" class="updated message">
- <p><span class="spinner" ></span></p>
</del><ins>+<script id="tmpl-revisions-frame" type="text/html">
+ <span class="spinner"></span>
+ <div class="revisions-control-frame"></div>
+ <div class="revisions-diff-frame"></div>
+</script>
+
+<script id="tmpl-revisions-controls" type="text/html">
+
+ <div class="revision-toggle-compare-mode">
+ <label>
+ <input type="checkbox" class="compare-two-revisions" />
+ <?php esc_attr_e( 'Compare two revisions' ); ?>
+ </label>
+ </div>
+
+ <div class="revisions-previous">
+ <input class="button" type="button" id="previous" value="<?php echo esc_attr_x( 'Previous', 'Button label for a previous revision' ); ?>" />
+ </div>
+
+ <div class="revisions-next">
+ <input class="button" type="button" id="next" value="<?php echo esc_attr_x( 'Next', 'Button label for a next revision' ); ?>" />
+ </div>
+</script>
+
+
+<script id="tmpl-revisions-meta" type="text/html">
+ <div id="diff-header">
+ <div id="diff-header-from" class="diff-header">
+ <div id="diff-title-from" class="diff-title">
+ <strong>
+ <?php _ex( 'From:', 'Followed by post revision info' ); ?></strong>
+ <# if ( 'undefined' !== typeof data.from ) { #>
+ {{{ data.from.attributes.author.avatar }}} {{{ data.from.attributes.author.name }}},
+ {{{ data.from.attributes.timeAgo }}} <?php _e( 'ago' ); ?>
+ ({{{ data.from.attributes.dateShort }}})
+ <# } #>
+
+ </div>
+ <div class="clear"></div>
</ins><span class="cx"> </div>
</span><span class="cx">
</span><del>- <div class="diff-slider-ticks-wrapper">
- <div id="diff-slider-ticks"></div>
</del><ins>+ <div id="diff-header-to" class="diff-header">
+ <div id="diff-title-to" class="diff-title">
+ <strong><?php _ex( 'To:', 'Followed by post revision info' ); ?></strong>
+ <# if ( 'undefined' !== typeof data.to ) { #>
+ {{{ data.to.attributes.author.avatar }}} {{{ data.to.attributes.author.name }}},
+ {{{ data.to.attributes.timeAgo }}} <?php _e( 'ago' ); ?>
+ ({{{ data.to.attributes.dateShort }}})
+ <# } #>
</ins><span class="cx"> </div>
</span><span class="cx">
</span><del>- <div id="revision-interact"></div>
-
- <div id="revisions-diff"></div>
</del><ins>+ <input type="button" id="restore-revision" class="button button-primary" data-restore-link="{{{ data.restoreLink }}}" value="<?php esc_attr_e( 'Restore This Revision' )?>" />
+ </div>
</ins><span class="cx"> </div>
</span><del>-</div>
</del><ins>+</script>
</ins><span class="cx">
</span><span class="cx"> <script id="tmpl-revisions-diff" type="text/html">
</span><ins>+ <# _.each( data.fields, function( field ) { #>
+ <h3>{{{ field.name }}}</h3>
+ {{{ field.diff }}}
+ <# }); #>
+</script>
+
+<script id="tmpl-revisions-diff-old" type="text/html">
</ins><span class="cx"> <div id="toggle-revision-compare-mode">
</span><span class="cx"> <label>
</span><span class="cx"> <input type="checkbox" id="compare-two-revisions" />
</span><span class="lines">@@ -157,12 +203,10 @@
</span><span class="cx"> </div>
</span><span class="cx"> </div>
</span><span class="cx">
</span><del>- </div>
-
</del><span class="cx"> <div id="diff-table">{{{ data.diff }}}</div>
</span><span class="cx"> </script>
</span><span class="cx">
</span><del>-<script id="tmpl-revision-interact" type="text/html">
</del><ins>+<script id="tmpl-revision-interact-old" type="text/html">
</ins><span class="cx"> <div id="diff-previous-revision">
</span><span class="cx"> <input class="button" type="button" id="previous" value="<?php echo esc_attr_x( 'Previous', 'Button label for a previous revision' ); ?>" />
</span><span class="cx"> </div>
</span><span class="lines">@@ -171,7 +215,6 @@
</span><span class="cx"> <input class="button" type="button" id="next" value="<?php echo esc_attr_x( 'Next', 'Button label for a next revision' ); ?>" />
</span><span class="cx"> </div>
</span><span class="cx">
</span><del>- <div id="diff-slider" class="wp-slider"></div>
</del><span class="cx"> </script>
</span><span class="cx">
</span><span class="cx"> <script id="tmpl-revision-ticks" type="text/html">
</span></span></pre></div>
<a id="trunkwpincludesrevisionphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/revision.php (24519 => 24520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/revision.php 2013-06-26 20:42:01 UTC (rev 24519)
+++ trunk/wp-includes/revision.php 2013-06-26 21:06:50 UTC (rev 24520)
</span><span class="lines">@@ -597,68 +597,3 @@
</span><span class="cx">
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><del>-
-/**
- * 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 );
-}
</del></span></pre>
</div>
</div>
</body>
</html>