diff --git a/wp-admin/css/wp-admin.css b/wp-admin/css/wp-admin.css index d9aa74f2cb..f5e94f6882 100644 --- a/wp-admin/css/wp-admin.css +++ b/wp-admin/css/wp-admin.css @@ -3538,6 +3538,39 @@ td.plugin-title p { height: 140px; } +.revisions .loading-indicator { + position: absolute; + text-align: center; + vertical-align: middle; + opacity: 0; + margin: 0 auto; + width: 100%; + height: 32px; + top: 3em; + background: #fff url(../images/wpspin_light-2x.gif) no-repeat center top; + -webkit-transition: opacity 0.5s; + -moz-transition: opacity 0.5s; + -ms-transition: opacity 0.5s; + -o-transition: opacity 0.5s; + transition: opacity 0.5s; +} + +.revisions.loading .loading-indicator { + opacity: 1; +} + +.revisions .diff { + -webkit-transition: opacity 0.5s; + -moz-transition: opacity 0.5s; + -ms-transition: opacity 0.5s; + -o-transition: opacity 0.5s; + transition: opacity 0.5s; +} + +.revisions.loading .diff { + opacity: 0.5; +} + .revisions-meta { margin-top: 15px; } diff --git a/wp-admin/includes/ajax-actions.php b/wp-admin/includes/ajax-actions.php index dab4df3602..0bfc988b5a 100644 --- a/wp-admin/includes/ajax-actions.php +++ b/wp-admin/includes/ajax-actions.php @@ -2092,8 +2092,6 @@ function wp_ajax_heartbeat() { function wp_ajax_get_revision_diffs() { require ABSPATH . 'wp-admin/includes/revision.php'; - // check_ajax_referer( 'revisions-ajax-nonce', 'nonce' ); - if ( ! $post = get_post( (int) $_REQUEST['post_id'] ) ) wp_send_json_error(); diff --git a/wp-admin/includes/revision.php b/wp-admin/includes/revision.php index 532e8fe96f..fce7c50ba9 100644 --- a/wp-admin/includes/revision.php +++ b/wp-admin/includes/revision.php @@ -66,11 +66,12 @@ function wp_prepare_revisions_for_js( $post, $selected_revision_id, $from = null $revisions = array(); $now_gmt = time(); - $revisions = wp_get_post_revisions( $post->ID ); + $revisions = wp_get_post_revisions( $post->ID, array( 'order' => 'ASC', 'orderby' => 'modified' ) ); cache_users( wp_list_pluck( $revisions, 'post_author' ) ); foreach ( $revisions as $revision ) { + $modified = strtotime( $revision->post_modified ); $modified_gmt = strtotime( $revision->post_modified_gmt ); $restore_link = wp_nonce_url( add_query_arg( @@ -88,9 +89,8 @@ function wp_prepare_revisions_for_js( $post, $selected_revision_id, $from = null '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 ), - 'dateUnix' => $modified_gmt, + 'date' => date_i18n( __( 'M j, Y @ G:i' ), $modified ), + 'dateShort' => date_i18n( _x( 'j M @ G:i', 'revision date short format' ), $modified ), 'timeAgo' => sprintf( __( '%s ago' ), human_time_diff( $modified_gmt, $now_gmt ) ), 'autosave' => wp_is_post_autosave( $revision ), 'current' => $revision->post_modified_gmt === $post->post_modified_gmt, @@ -99,16 +99,13 @@ function wp_prepare_revisions_for_js( $post, $selected_revision_id, $from = null } // Now, grab the initial diff - if ( ! $from ) { // Single mode - $initial_revisions = array_reverse( array_keys( array_slice( $revisions, array_search( $selected_revision_id, array_keys( $revisions ) ), 2, true ) ) ); - $compare_two_mode = false; - } else { // Compare two - $compare_two_mode = true; - $initial_revisions = array( $from, $selected_revision_id ); - } + $compare_two_mode = (bool) $from; + if ( ! $from ) // Single mode + $from = array_keys( array_slice( $revisions, array_search( $selected_revision_id, array_keys( $revisions ) ) - 1, 1, true ) )[0]; + $diffs = array( array( - 'id' => $initial_revisions[0] . ':' . $initial_revisions[1], - 'fields' => wp_get_revision_ui_diff( $post->ID, $initial_revisions[0], $initial_revisions[1] ), + 'id' => $from . ':' . $selected_revision_id, + 'fields' => wp_get_revision_ui_diff( $post->ID, $from, $selected_revision_id ), )); return array( @@ -120,5 +117,6 @@ function wp_prepare_revisions_for_js( $post, $selected_revision_id, $from = null 'diffData' => $diffs, 'baseUrl' => parse_url( admin_url( 'revision.php' ), PHP_URL_PATH ), 'compareTwoMode' => absint( $compare_two_mode ), // Apparently booleans are not allowed + 'revisionIds' => array_keys( $revisions ), ); } diff --git a/wp-admin/js/revisions.js b/wp-admin/js/revisions.js index d88c8450df..1956938eba 100644 --- a/wp-admin/js/revisions.js +++ b/wp-admin/js/revisions.js @@ -129,15 +129,6 @@ window.wp = window.wp || {}; _.bindAll( this, 'next', 'prev' ); }, - comparator: function( a, b ) { - var a_ = a.get('dateUnix'); - var b_ = b.get('dateUnix'); - var cmp = (a_ > b_) - (a_ < b_); - if (cmp === 0 && a.id != b.id) - cmp = a.id < b.id ? -1 : 1; - return cmp; - }, - next: function( revision ) { var index = this.indexOf( revision ); @@ -335,23 +326,24 @@ window.wp = window.wp || {}; // Set the initial diffs collection provided through the settings this.diffs.set( revisions.settings.diffData ); - // Set the initial revisions, baseUrl, and mode as provided through settings - properties.to = this.revisions.get( revisions.settings.to ); - properties.from = this.revisions.get( revisions.settings.from ) || this.revisions.prev( properties.to ); - properties.compareTwoMode = revisions.settings.compareTwoMode; - properties.baseUrl = revisions.settings.baseUrl; - this.set( properties ); - - // Start the router. This will trigger a navigate event and ensure that - // the `from` and `to` revisions accurately reflect the hash. - this.router = new revisions.Router({ model: this }); - Backbone.history.start({ pushState: true }); - // Set up internal listeners this.listenTo( this, 'change:from', this.changeRevisionHandler ); this.listenTo( this, 'change:to', this.changeRevisionHandler ); this.listenTo( this, 'update:revisions', this.loadSurrounding ); this.listenTo( this, 'change:compareTwoMode', this.changedMode ); + this.listenTo( this.diffs, 'ensure:load', this.updateLoadingStatus ); + this.listenTo( this, 'update:diff', this.updateLoadingStatus ); + + // Set the initial revisions, baseUrl, and mode as provided through settings + properties.to = this.revisions.get( revisions.settings.to ); + properties.from = this.revisions.get( revisions.settings.from ); + properties.compareTwoMode = revisions.settings.compareTwoMode; + properties.baseUrl = revisions.settings.baseUrl; + this.set( properties, { silent: true } ); + + // Start the router + this.router = new revisions.Router({ model: this }); + Backbone.history.start({ pushState: true }); }, changedMode: function() { @@ -359,6 +351,10 @@ window.wp = window.wp || {}; this.loadSurrounding( this.get( 'from' ), this.get( 'to' ) ); }, + updateLoadingStatus: function() { + this.set( 'loading', ! this.diff() ); + }, + loadSurrounding: function( from, to ) { // Different strategies for single and compare-two models if ( this.get( 'compareTwoMode' ) ) { @@ -441,13 +437,9 @@ window.wp = window.wp || {}; template: wp.template('revisions-frame'), initialize: function() { - // Generate the frame model. - this.model = new revisions.model.FrameState({}, { - revisions: this.collection - }); - this.listenTo( this.model, 'update:diff', this.renderDiff ); this.listenTo( this.model, 'change:compareTwoMode', this.updateCompareTwoMode ); + this.listenTo( this.model, 'change:loading', this.updateLoadingStatus ); this.views.set( '.revisions-control-frame', new revisions.view.Controls({ model: this.model @@ -455,6 +447,7 @@ window.wp = window.wp || {}; }, render: function() { + console.log( 'diff', this.model.diff() ); this.model.updateDiff({ immediate: true }).done( _.bind( function() { wp.Backbone.View.prototype.render.apply( this, arguments ); @@ -472,6 +465,10 @@ window.wp = window.wp || {}; }) ); }, + updateLoadingStatus: function() { + this.$el.toggleClass( 'loading', this.model.get('loading') ); + }, + updateCompareTwoMode: function() { this.$el.toggleClass( 'comparing-two-revisions', this.model.get('compareTwoMode') ); } @@ -1013,7 +1010,9 @@ window.wp = window.wp || {}; // Initialize the revisions UI. revisions.init = function() { revisions.view.frame = new revisions.view.Frame({ - collection: new revisions.model.Revisions( revisions.settings.revisionData ) + model: new revisions.model.FrameState({}, { + revisions: new revisions.model.Revisions( revisions.settings.revisionData ) + }) }).render(); }; diff --git a/wp-admin/revision.php b/wp-admin/revision.php index 2cb4f9633d..fef0f8a0c5 100644 --- a/wp-admin/revision.php +++ b/wp-admin/revision.php @@ -185,10 +185,13 @@ require_once( './admin-header.php' );