From c44ce3b6e6b7b99ac09dc6c5ca79572c20185acf Mon Sep 17 00:00:00 2001 From: Mark Jaquith Date: Thu, 11 Jul 2013 22:56:48 +0000 Subject: [PATCH] Revisions: real URLs and preloading of the requested diff. * Real URLs are being used now, using pushState. `?revision={id}` or `?from={from}&to={to}`. * Drop the redundant `action=edit` from the URLs (this is the default). * The initial comparison is preloaded, whether a single revision or a compare-two situation. See #24425. git-svn-id: http://core.svn.wordpress.org/trunk@24664 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/includes/revision.php | 21 ++++++++++++-- wp-admin/js/revisions.js | 51 ++++++++++++++++++++++++---------- wp-admin/revision.php | 7 +++-- wp-includes/link-template.php | 4 ++- 4 files changed, 63 insertions(+), 20 deletions(-) diff --git a/wp-admin/includes/revision.php b/wp-admin/includes/revision.php index 91cb634260..532e8fe96f 100644 --- a/wp-admin/includes/revision.php +++ b/wp-admin/includes/revision.php @@ -61,7 +61,7 @@ function wp_get_revision_ui_diff( $post, $compare_from, $compare_to ) { return $return; } -function wp_prepare_revisions_for_js( $post, $selected_revision_id ) { +function wp_prepare_revisions_for_js( $post, $selected_revision_id, $from = null ) { $post = get_post( $post ); $revisions = array(); $now_gmt = time(); @@ -98,10 +98,27 @@ function wp_prepare_revisions_for_js( $post, $selected_revision_id ) { ); } + // 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 ); + } + $diffs = array( array( + 'id' => $initial_revisions[0] . ':' . $initial_revisions[1], + 'fields' => wp_get_revision_ui_diff( $post->ID, $initial_revisions[0], $initial_revisions[1] ), + )); + return array( 'postId' => $post->ID, 'nonce' => wp_create_nonce( 'revisions-ajax-nonce' ), 'revisionData' => array_values( $revisions ), - 'selectedRevision' => $selected_revision_id, + 'to' => $selected_revision_id, + 'from' => $from, + 'diffData' => $diffs, + 'baseUrl' => parse_url( admin_url( 'revision.php' ), PHP_URL_PATH ), + 'compareTwoMode' => absint( $compare_two_mode ), // Apparently booleans are not allowed ); } diff --git a/wp-admin/js/revisions.js b/wp-admin/js/revisions.js index ae185c68dd..2003e5e090 100644 --- a/wp-admin/js/revisions.js +++ b/wp-admin/js/revisions.js @@ -17,9 +17,14 @@ window.wp = window.wp || {}; }; // wp_localize_script transforms top-level numbers into strings. Undo that. - if ( revisions.settings.selectedRevision ) - revisions.settings.selectedRevision = parseInt( revisions.settings.selectedRevision, 10 ); + if ( revisions.settings.to ) + revisions.settings.to = parseInt( revisions.settings.to, 10 ); + if ( revisions.settings.from ) + revisions.settings.from = parseInt( revisions.settings.from, 10 ); + // wp_localize_script does not allow for top-level booleans. Fix that. + if ( revisions.settings.compareTwoMode ) + revisions.settings.compareTwoMode = revisions.settings.compareTwoMode === '1'; /** * ======================================================================== @@ -40,7 +45,7 @@ window.wp = window.wp || {}; this.revisions = options.revisions; this.set({ max: this.revisions.length - 1, - value: this.revisions.indexOf( this.revisions.get( revisions.settings.selectedRevision ) ), + value: this.revisions.indexOf( this.revisions.get( revisions.settings.to ) ), compareTwoMode: this.frame.get('compareTwoMode') }); @@ -314,6 +319,10 @@ window.wp = window.wp || {}; revisions.model.FrameState = Backbone.Model.extend({ + defaults: { + compareTwoMode: false + }, + initialize: function( attributes, options ) { var properties = {}; @@ -322,17 +331,22 @@ window.wp = window.wp || {}; this.revisions = options.revisions; this.diffs = new revisions.model.Diffs( [], { revisions: this.revisions }); - // Set the initial revision provided through the settings. - properties.to = this.revisions.get( revisions.settings.selectedRevision ); - properties.from = this.revisions.prev( properties.to ); - properties.compareTwoMode = false; + // 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(); + 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 ); @@ -937,23 +951,30 @@ window.wp = window.wp || {}; revisions.Router = Backbone.Router.extend({ initialize: function( options ) { this.model = options.model; + this.routes = this.getRoutes(); // Maintain state history when dragging this.listenTo( this.model, 'update:diff', _.debounce( this.updateUrl, 250 ) ); }, - routes: { - 'from/:from/to/:to': 'handleRoute', - 'at/:to': 'handleRoute' + getRoutes: function() { + var routes = {}; + routes[this.baseUrl( '?from=:from&to=:to' )] = 'handleRoute'; + routes[this.baseUrl( '?revision=:to' )] = 'handleRoute'; + return routes; + }, + + baseUrl: function( url ) { + return this.model.get('baseUrl') + url; }, updateUrl: function() { var from = this.model.has('from') ? this.model.get('from').id : 0; var to = this.model.get('to').id; if ( this.model.get('compareTwoMode' ) ) - this.navigate( 'from/' + from + '/to/' + to ); + this.navigate( this.baseUrl( '?from=' + from + '&to=' + to ) ); else - this.navigate( 'at/' + to ); + this.navigate( this.baseUrl( '?revision=' + to ) ); }, handleRoute: function( a, b ) { @@ -964,7 +985,7 @@ window.wp = window.wp || {}; b = this.model.revisions.get( a ); a = this.model.revisions.prev( b ); b = b ? b.id : 0; - a = a ? a.id : 0 + a = a ? a.id : 0; compareTwo = false; } else { compareTwo = true; @@ -984,7 +1005,7 @@ window.wp = window.wp || {}; from: selectedFromRevision }); } - revisions.settings.selectedRevision = to; + revisions.settings.to = to; } }); diff --git a/wp-admin/revision.php b/wp-admin/revision.php index 0f46030285..2cb4f9633d 100644 --- a/wp-admin/revision.php +++ b/wp-admin/revision.php @@ -11,9 +11,12 @@ require_once('./admin.php'); require ABSPATH . 'wp-admin/includes/revision.php'; -wp_reset_vars( array( 'revision', 'action' ) ); +wp_reset_vars( array( 'revision', 'action', 'from', 'to' ) ); $revision_id = absint( $revision ); +$from = absint( $from ); +if ( ! $revision_id ) + $revision_id = absint( $to ); $redirect = 'edit.php'; switch ( $action ) : @@ -79,7 +82,7 @@ else $parent_file = $submenu_file = 'edit.php'; wp_enqueue_script( 'revisions' ); -wp_localize_script( 'revisions', '_wpRevisionsSettings', wp_prepare_revisions_for_js( $post, $revision_id ) ); +wp_localize_script( 'revisions', '_wpRevisionsSettings', wp_prepare_revisions_for_js( $post, $revision_id, $from ) ); /* Revisions Help Tab */ diff --git a/wp-includes/link-template.php b/wp-includes/link-template.php index 16af6271ce..c948ab884c 100644 --- a/wp-includes/link-template.php +++ b/wp-includes/link-template.php @@ -897,7 +897,9 @@ function get_edit_post_link( $id = 0, $context = 'display' ) { if ( ! $post = get_post( $id ) ) return; - if ( 'display' == $context ) + if ( 'revision' === $post->post_type ) + $action = ''; + elseif ( 'display' == $context ) $action = '&action=edit'; else $action = '&action=edit';