diff --git a/wp-admin/admin-ajax.php b/wp-admin/admin-ajax.php
index ed1ef9e499..d313854532 100644
--- a/wp-admin/admin-ajax.php
+++ b/wp-admin/admin-ajax.php
@@ -42,7 +42,7 @@ do_action( 'admin_init' );
$core_actions_get = array(
'fetch-list', 'ajax-tag-search', 'wp-compression-test', 'imgedit-preview', 'oembed-cache',
- 'autocomplete-user', 'dashboard-widgets', 'logged-in',
+ 'autocomplete-user', 'dashboard-widgets', 'logged-in', 'revisions-data'
);
$core_actions_post = array(
@@ -56,7 +56,7 @@ $core_actions_post = array(
'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',
+ 'send-attachment-to-editor', 'save-attachment-order', 'heartbeat'
);
// Register core Ajax calls.
diff --git a/wp-admin/css/colors-fresh.css b/wp-admin/css/colors-fresh.css
index bf8700ea20..5126941017 100644
--- a/wp-admin/css/colors-fresh.css
+++ b/wp-admin/css/colors-fresh.css
@@ -1351,15 +1351,26 @@ div.wp-menu-image {
/* Diff */
table.diff .diff-deletedline {
- background-color: #fdd;
+ background-color: #ffe5e6;
+ color: #f2001f;
+ text-decoration: line-through;
}
table.diff .diff-deletedline del {
background-color: #f99;
}
+table.diff .diff-deletedline-symbol {
+ color: #f2001f;
+}
+
table.diff .diff-addedline {
- background-color: #dfd;
+ background-color: #e9f6ea;
+ color: #00a500;
+}
+
+table.diff .diff-addedline-symbol {
+ color: #00a500;
}
table.diff .diff-addedline ins {
diff --git a/wp-admin/css/revisions.css b/wp-admin/css/revisions.css
new file mode 100644
index 0000000000..76f51d5b00
--- /dev/null
+++ b/wp-admin/css/revisions.css
@@ -0,0 +1,213 @@
+/* Styles for the revision screen */
+
+.revisiondiffcontainer {
+ width: 96%;
+}
+
+.revisiondiffcontainer input.button {
+ margin: 2px;
+}
+
+#diffrestore, #diffnext, #diffcancel {
+ float: right;
+ margin-right: 5px;
+}
+
+#diffprevious, #difftitle, #difftitlefrom, #diff_from_current_revision {
+ float: left;
+ margin-left: 5px;
+ height: 35px;
+}
+
+#diffprevious, #diffnext {
+ margin-top: 7px;
+ height: 30px;
+}
+
+#diffheader, #diffsubheader {
+ clear: both;
+ width: 100%;
+}
+
+#diffheader {
+ border-bottom: 2px solid #999;
+ width: 100%;
+ height: 45px;
+ line-height: 45px;
+ padding-top: 10px;
+}
+
+#diffsubheader {
+ background-color: #eee;
+ border-bottom: 2px solid #999;
+ width: 100%;
+ height:35px;
+ line-height: 35px;
+}
+
+#diffslider {
+ width: 70%;
+ margin-left: auto;
+ margin-right: auto;
+ text-align: center;
+ height: 3.5em;
+
+}
+
+#revisioncount {
+ width: 50%;
+ margin-left: auto;
+ margin-right: auto;
+ margin-top: 0;
+ line-height: 1em;
+ height: 1em;
+ text-align: center;
+ clear: none;
+ padding: 5px;
+}
+
+.revisiondiffcontainer {
+ margin-top: 10px;
+}
+
+#diffsliderwrap {
+ width: 80%;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+#diffsliderwrap #sliderinner {
+ position: relative;
+ top: 47px;
+}
+
+#removedandadded {
+ width: 100%
+ padding-bottom: 30px;
+ padding-top: 3px;
+ font-size: 16px;
+}
+
+#removed, #added {
+ width: auto;
+ text-align: left;
+ padding-left: 5px;
+ padding-right: 5px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+ float: left;
+}
+
+.diffsplit #added {
+ float: right;
+ width: 47%;
+ text-align: left;
+}
+
+.diffsplit #removedandadded {
+ width: 100%;
+}
+
+#added {
+ padding-left: 10px;
+}
+
+#removed {
+ padding-left: 0px;
+ }
+
+#removed {
+ color: #d2281f;
+}
+
+#added {
+ color: #00a100;
+}
+
+#comparetworevisions {
+ float: right;
+ line-height: 35px;
+ padding-right: 5px;
+}
+
+#comparetworevisions input{
+ margin-right: 2px;
+}
+
+#difftitle img, #difftitlefrom img {
+ vertical-align: middle;
+ margin-left: 5px;
+}
+
+#showsplitviewoption, #toggleshowautosavesoption {
+ float: right;
+ padding-left: 10px;
+ padding-right: 10px;
+}
+
+#revisionoptions {
+ margin-top: 0px;
+ line-height: 40px;
+ clear: both;
+ width: 100%;
+}
+
+.comparetwo #diffprevious, .comparetwo #diffnext {
+ display: none;
+}
+
+.comparetwo #diffslider {
+ width: 95%;
+}
+
+.currentversion span#diff_left_current_revision {
+ display: inline;
+}
+
+span#diff_left_current_revision, span#diff_from_current_revision {
+ display: none;
+}
+
+span#diff_left_count, span#diff_left_count_inner {
+ display: inline;
+}
+
+.currentversion span#diff_left_count,
+.currentversion span#diff_left_count_inner,
+.currentversion #difftitlefrom {
+ display: none;
+}
+
+#difftitlefrom {
+ float: left;
+ display: none;
+}
+
+.comparetwo #difftitlefrom, .comparetwo.currentversion span#diff_from_current_revision {
+ display: inline;
+}
+.comparetwo.currentversion #difftitlefrom {
+ display: none;
+}
+
+#modelsloading {
+ float: right;
+ line-height: 30px;
+ display: none;
+ clear: none;
+ margin: 0;
+ margin-top: -40px;
+}
+
+#modelsloading .spinner {
+ float: left;
+ }
+
+.leftmodelloading #modelsloading,
+.rightmodelloading #modelsloading,
+.leftmodelloading #modelsloading .spinner,
+.rightmodelloading #modelsloading .spinner {
+ display: inline;
+}
+
+
diff --git a/wp-admin/css/revisions.min.css b/wp-admin/css/revisions.min.css
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/wp-admin/css/wp-admin.css b/wp-admin/css/wp-admin.css
index 7299d3f627..4cfc76a8b8 100644
--- a/wp-admin/css/wp-admin.css
+++ b/wp-admin/css/wp-admin.css
@@ -3504,7 +3504,19 @@ table.diff {
}
table.diff col.content {
- width: 50%;
+ width: auto;
+}
+
+table.diff col.content.diffsplit {
+ width: 48%;
+}
+
+table.diff col.diffsplit.middle {
+ width: 4%;
+}
+
+table.diff col.ltype {
+ width: 30px;
}
table.diff tr {
@@ -8808,3 +8820,17 @@ a.widget-control-edit {
.locale-lt-lt .inline-edit-row fieldset label span.input-text-wrap {
margin-left: 8em;
}
+
+#revisions-meta-mostrecent,
+#revisions-meta-stored,
+#revisions-meta-oldest,
+#revisions-meta-link {
+ line-height: 30px;
+ height: 30px;
+ vertical-align: middle;
+ padding-right: 10px;
+}
+#revisions-meta-mostrecent img,
+#revisions-meta-oldest img {
+vertical-align: middle;
+}
diff --git a/wp-admin/edit-form-advanced.php b/wp-admin/edit-form-advanced.php
index 79d18da2f4..4eeb7fab06 100644
--- a/wp-admin/edit-form-advanced.php
+++ b/wp-admin/edit-form-advanced.php
@@ -168,7 +168,8 @@ if ( post_type_supports($post_type, 'author') ) {
add_meta_box('authordiv', __('Author'), 'post_author_meta_box', null, 'normal', 'core');
}
-if ( post_type_supports($post_type, 'revisions') && 0 < $post_ID && wp_get_post_revisions( $post_ID ) )
+// TODO review this count() - why do we need to add it?
+if ( post_type_supports($post_type, 'revisions') && 0 < $post_ID && count ( wp_get_post_revisions( $post_ID ) ) > 1 )
add_meta_box('revisionsdiv', __('Revisions'), 'post_revisions_meta_box', null, 'normal', 'core');
do_action('add_meta_boxes', $post_type, $post);
diff --git a/wp-admin/includes/ajax-actions.php b/wp-admin/includes/ajax-actions.php
index 0fabe2a50d..b9c7f13d84 100644
--- a/wp-admin/includes/ajax-actions.php
+++ b/wp-admin/includes/ajax-actions.php
@@ -1379,7 +1379,7 @@ function wp_ajax_inline_save_tax() {
global $wp_list_table;
check_ajax_referer( 'taxinlineeditnonce', '_inline_edit' );
-
+
$post_data = wp_unslash( $_POST );
$taxonomy = sanitize_key( $post_data['taxonomy'] );
@@ -2134,3 +2134,138 @@ function wp_ajax_nopriv_heartbeat() {
wp_send_json($response);
}
+function wp_ajax_revisions_data() {
+ check_ajax_referer( 'revisions-ajax-nonce', 'nonce' );
+
+ $compareto = isset( $_GET['compareto'] ) ? absint( $_GET['compareto'] ) : 0;
+ $showautosaves = isset( $_GET['showautosaves'] ) ? $_GET['showautosaves'] : '';
+ $show_split_view = isset( $_GET['show_split_view'] ) ? $_GET['show_split_view'] : '';
+ $postid = isset( $_GET['postid'] ) ? absint( $_GET['postid'] ) : '';
+
+ $comparetwomode = ( '' == $postid ) ? false : true;
+ //
+ //TODO: currently code returns all possible comparisons for the indicated 'compareto' revision
+ //however, the front end prevents users from pulling the right handle past the left or the left pass the right,
+ //so only the possible diffs need be generated
+ //
+ $alltherevisions = array();
+
+ if ( '' == $postid )
+ $postid = $compareto;
+
+ if ( ! current_user_can( 'read_post', $postid ) )
+ continue;
+
+ if ( ! $revisions = wp_get_post_revisions( $postid ) )
+ return;
+
+ //if we are comparing two revisions, the first 'revision' represented by the leftmost
+ //slider position is the current revision, prepend a comparison to this revision
+ if ( $comparetwomode )
+ array_unshift( $revisions, get_post( $postid ) );
+
+ $count = 1;
+ foreach ( $revisions as $revision ) :
+ if ( 'true' != $showautosaves && wp_is_post_autosave( $revision ) )
+ continue;
+
+ $revision_from_date_author = '';
+
+
+ $left_revision = get_post( $compareto );
+ $right_revision = get_post( $revision );
+
+ $author = get_the_author_meta( 'display_name', $revision->post_author );
+ /* translators: revision date format, see http://php.net/date */
+ $datef = _x( 'j F, Y @ G:i:s', 'revision date format');
+
+ $gravatar = get_avatar( $revision->post_author, 18 );
+
+ $date = date_i18n( $datef, strtotime( $revision->post_modified ) );
+ $revision_date_author = sprintf(
+ '%s %s, %s %s (%s)',
+ $gravatar,
+ $author,
+ human_time_diff( strtotime( $revision->post_modified ), current_time( 'timestamp' ) ),
+ __( ' ago ' ),
+ $date
+ );
+
+ if ( $comparetwomode ) {
+ $compareto_gravatar = get_avatar( $left_revision->post_author, 18 );
+ $compareto_author = get_the_author_meta( 'display_name', $left_revision->post_author );
+ $compareto_date = date_i18n( $datef, strtotime( $left_revision->post_modified ) );
+
+ $revision_from_date_author = sprintf(
+ '%s %s, %s %s (%s)',
+ $compareto_gravatar,
+ $compareto_author,
+ human_time_diff( strtotime( $left_revision->post_modified ), current_time( 'timestamp' ) ),
+ __( ' ago ' ),
+ $compareto_date
+ );
+ }
+
+ $restoreaction = wp_nonce_url(
+ add_query_arg(
+ array( 'revision' => $revision->ID,
+ 'action' => 'restore' ),
+ '/wp-admin/revision.php'
+ ),
+ "restore-post_{$compareto}|{$revision->ID}"
+ );
+
+ //
+ //make sure the left revision is the most recent
+ //
+ if ( strtotime( $right_revision->post_modified_gmt ) < strtotime( $left_revision->post_modified_gmt ) ) {
+ $temp = $left_revision;
+ $left_revision = $right_revision;
+ $right_revision = $temp;
+ }
+
+ //
+ //compare from left to right, passed from application
+ //
+ $content='';
+ foreach ( array_keys( _wp_post_revision_fields() ) as $field ) {
+ $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", 'wp_kses_post' );
+
+ $args = array();
+
+ if ( 'true' == $show_split_view )
+ $args = array( 'show_split_view' => 'true' );
+
+ $content .= wp_text_diff( $left_content, $right_content, $args );
+ }
+
+ //if we are comparing two revisions
+ //and we are on the matching revision
+ //add an error revision indicating unable to compare to self
+ if ( $comparetwomode && $compareto == $revision->ID )
+ $alltherevisions[] = array (
+ 'ID' => $revision->ID,
+ 'revision_date_author' => $revision_date_author,
+ 'revisiondiff' => sprintf('
%s
', __( 'Cannot compare revision to itself' ) ),
+ 'restoreaction' => urldecode( $restoreaction ),
+ 'revision_from_date_author' => ''
+ );
+
+ //add to the return data only if there is a difference
+ if ( '' != $content )
+ $alltherevisions[] = array (
+ 'ID' => $revision->ID,
+ 'revision_date_author' => $revision_date_author,
+ 'revisiondiff' => $content,
+ 'restoreaction' => urldecode( $restoreaction ),
+ 'revision_from_date_author' => $revision_from_date_author
+ );
+
+ endforeach;
+
+ echo json_encode( $alltherevisions );
+ exit();
+}
diff --git a/wp-admin/js/revisions.js b/wp-admin/js/revisions.js
new file mode 100644
index 0000000000..43fb1e9848
--- /dev/null
+++ b/wp-admin/js/revisions.js
@@ -0,0 +1,530 @@
+window.wp = window.wp || {};
+
+(function($) {
+ wp.revisions = {
+
+ views : {},
+
+ Model : Backbone.Model.extend({
+ defaults: {
+ ID : 0,
+ revision_date_author : '',
+ revisiondiff : '',
+ restoreaction: '',
+ diff_max : 0,
+ diff_count : 0,
+ diff_revision_to : 0,
+ revision_from_date_author : '',
+ }
+ }),
+
+ app: _.extend({}, Backbone.Events),
+
+ App : Backbone.Router.extend({
+ _revisionDifflView : null,
+ _revisions : null,
+ _left_handle_revisions : null,
+ _right_handle_revisions : null,
+ _revisionsInteractions : null,
+ _revisionsOptions : null,
+ _left_diff : 0,
+ _right_diff : 1,
+ _autosaves : false,
+ _showsplitview : true,
+ _compareoneortwo : 1,
+ left_model_loading : false, //keep track of model loads
+ right_model_loading : false, //disallow slider interaction, also repeat loads, while loading
+
+ //TODO add ability to arrive on specific revision
+ routes : {
+ "viewrevision/:revision": "viewrevision",
+ },
+
+ viewrevision : function( revision ) {
+ //coming soon
+ },
+
+ start_left_model_loading : function() {
+ this.left_model_loading = true;
+ $('.revisiondiffcontainer').addClass('leftmodelloading');
+ },
+
+ stop_left_model_loading : function() {
+ this.left_model_loading = false;
+ $('.revisiondiffcontainer').removeClass('leftmodelloading');
+ },
+
+ start_right_model_loading : function() {
+ this.right_model_loading = true;
+ $('.revisiondiffcontainer').addClass('rightmodelloading');
+ },
+
+ stop_right_model_loading : function() {
+ this.right_model_loading = false;
+ $('.revisiondiffcontainer').removeClass('rightmodelloading');
+ },
+
+ reloadmodel : function() {
+ if ( 2 == this._compareoneortwo ) {
+ this.reloadleftright();
+ } else {
+ this.reloadmodelsingle();
+ }
+ },
+
+ reloadmodelsingle : function() {
+ var self = this;
+ self._revisions.url = ajaxurl + '?action=revisions-data&compareto=' + wpRevisionsSettings.post_id +
+ '&showautosaves=' + self.self_autosaves +
+ '&showsplitview=' + REVAPP._showsplitview +
+ '&nonce=' + wpRevisionsSettings.nonce;
+ self.start_right_model_loading();
+ this._revisions.fetch({ //reload revision data
+ success : function() {
+ self.stop_right_model_loading();
+ var revisioncount = self._revisions.length;
+ if ( self._right_diff > revisioncount ) //if right handle past rightmost, move
+ self._right_diff = revisioncount;
+ //TODO add a test for matchind left revision and push left, testing
+ //also reset the slider values here
+
+ self._revisionView.render();
+ $( '#slider' ).slider( 'option', 'max', revisioncount-1 ); //TODO test this
+ },
+
+ error : function () {
+ self.stop_right_model_loading();
+ window.console && console.log( 'Error loading revision data' );
+ }
+
+ });
+ },
+
+ reloadleftright : function() {
+ var self = this;
+ self.start_left_model_loading();
+ self.start_right_model_loading();
+
+ self._left_handle_revisions = new wp.revisions.Collection();
+ self._right_handle_revisions = new wp.revisions.Collection();
+
+ if ( 0 == self._left_diff ) {
+ self._right_handle_revisions.url =
+ ajaxurl +
+ '?action=revisions-data&compareto=' + wpRevisionsSettings.post_id +
+ '&wpRevisionsSettings.post_id=' + wpRevisionsSettings.post_id +
+ '&showautosaves=' + self._autosaves +
+ '&showsplitview=' + self._showsplitview +
+ '&nonce=' + wpRevisionsSettings.nonce;
+ } else {
+ self._right_handle_revisions.url =
+ ajaxurl +
+ '?action=revisions-data&compareto=' + self._revisions.at( self._left_diff - 1 ).get( 'ID' ) +
+ '&wpRevisionsSettings.post_id=' + wpRevisionsSettings.post_id +
+ '&showautosaves=' + self._autosaves +
+ '&showsplitview=' + self._showsplitview +
+ '&nonce=' + wpRevisionsSettings.nonce;
+ }
+
+ self._left_handle_revisions.url =
+ ajaxurl +
+ '?action=revisions-data&compareto=' + self._revisions.at( self._right_diff - 1 ).get( 'ID' ) +
+ '&wpRevisionsSettings.post_id=' + wpRevisionsSettings.post_id +
+ '&showautosaves=' + self._autosaves +
+ '&showsplitview=' + self._showsplitview +
+ '&nonce=' + wpRevisionsSettings.nonce;
+
+ self._left_handle_revisions.fetch({
+
+ xhr: function() {
+ var xhr = $.ajaxSettings.xhr();
+ xhr.onprogress = self.handleProgress;
+ return xhr;
+ },
+
+ handleProgress: function(evt){
+ var percentComplete = 0;
+ if (evt.lengthComputable) {
+ percentComplete = evt.loaded / evt.total;
+ window.console && console.log( Math.round( percentComplete * 100) + "%" );
+ }
+ },
+
+ success : function(){
+ self.stop_left_model_loading();
+ },
+
+ error : function () {
+ window.console && console.log( 'Error loading revision data' );
+ self.stop_left_model_loading();
+ }
+ });
+
+ self._right_handle_revisions.fetch({
+
+ success : function(){
+ self.stop_right_model_loading();
+ },
+
+ error : function () {
+ window.console && console.log( 'Error loading revision data' );
+ self.stop_right_model_loading();
+ }
+ });
+ },
+
+ /*
+ * initialize the revision appl;ication
+ */
+ initialize : function( options ) {
+ var self = this; //store the application instance
+ if (this._revisions === null) {
+ self._autosaves = '';
+ self._revisions = new wp.revisions.Collection(); //set up collection
+ self.start_right_model_loading();
+ self._revisions.fetch({ //load revision data
+
+ success : function() {
+ self.stop_right_model_loading();
+ self.revisionDiffSetup();
+ }
+ });
+ }
+ return this;
+ },
+
+ revisionDiffSetup : function() {
+ var self = this, slider;
+
+ this._revisionView = new wp.revisions.views.View({
+ model : this._revisions
+ });
+ this._revisionView.render();
+
+ this._revisionsInteractions = new wp.revisions.views.Interact({
+ model : this._revisions
+ });
+ this._revisionsInteractions.render();
+
+ this._revisionsOptions = new wp.revisions.views.Options({
+ model : this._revisions
+ });
+ this._revisionsOptions.render();
+
+ }
+ })
+ };
+
+ wp.revisions.Collection = Backbone.Collection.extend({
+ model : wp.revisions.Model,
+ url : ajaxurl + '?action=revisions-data&compareto=' + wpRevisionsSettings.post_id + '&showautosaves=false&showsplitview=true&nonce=' + wpRevisionsSettings.nonce
+ });
+
+ _.extend(wp.revisions.views, {
+ //
+ //primary revision diff view
+ //
+ View : Backbone.View.extend({
+ el : $('#backbonerevisionsdiff')[0],
+ tagName : 'revisionvview',
+ className : 'revisionview-container',
+ template : wp.template('revision'),
+ revvapp : null,
+ comparetwochecked : '',
+ draggingleft : false,
+
+ initialize : function(){
+ },
+
+ //
+ //render the revisions
+ //
+ render : function() {
+ var addhtml = '';
+ //compare two revisions mode?
+ if ( 2 == REVAPP._compareoneortwo ) {
+ this.comparetwochecked = 'checked';
+ if ( this.draggingleft ) {
+ if ( this.model.at( REVAPP._left_diff ) ) {
+ addhtml = this.template( _.extend(
+ this.model.at( REVAPP._left_diff ).toJSON(),
+ { comparetwochecked : this.comparetwochecked } //keep the checkmark checked
+ ) );
+ }
+ } else { //dragging right handle
+ var thediff = REVAPP._right_diff;
+ if ( this.model.at( thediff ) ) {
+ addhtml = this.template( _.extend(
+ this.model.at( thediff ).toJSON(),
+ { comparetwochecked : this.comparetwochecked } //keep the checkmark checked
+ ) );
+ }
+ }
+ } else { //end compare two revisions mode, eg only one slider handel
+ this.comparetwochecked = '';
+ if ( this.model.at( REVAPP._right_diff - 1 ) ) {
+ addhtml = this.template( _.extend(
+ this.model.at( REVAPP._right_diff-1 ).toJSON(),
+ { comparetwochecked : this.comparetwochecked } //keep the checkmark checked
+ ) );
+ }
+ }
+ this.$el.html( addhtml );
+ return this;
+ },
+
+ //the compare two button is in this view, add the interaction here
+ events : {
+ 'click #comparetwo' : 'clickcomparetwo'
+ },
+
+ //
+ //turn on/off the compare two mmode
+ //
+ clickcomparetwo : function(){
+ self = this;
+ if ( $( 'input#comparetwo' ).is( ':checked' ) ) {
+ REVAPP._compareoneortwo = 2 ;
+ REVAPP.reloadleftright();
+ } else {
+ REVAPP._compareoneortwo = 1 ;
+ REVAPP._revisionView.draggingleft = false;
+ REVAPP._left_diff = 0;
+ REVAPP.reloadmodelsingle();
+ }
+ REVAPP._revisionsInteractions.render();
+ }
+ }),
+
+ //
+ //options view for show autosaves and show split view options
+ //
+ Options : Backbone.View.extend({
+ el : $('#backbonerevisionsoptions')[0],
+ tagName : 'revisionoptionsview',
+ className : 'revisionoptions-container',
+ template : wp.template('revisionoptions'),
+
+ initialize : function() {
+ },
+
+ //render the options view
+ render : function() {
+ var addhtml = this.template;
+ this.$el.html( addhtml );
+ return this;
+ },
+
+ //add options interactions
+ events : {
+ 'click #toggleshowautosaves' : 'toggleshowautosaves',
+ 'click #showsplitview' : 'showsplitview'
+ },
+
+ //
+ //toggle include autosaves
+ //
+ toggleshowautosaves : function() {
+ var self = this;
+ if ( $( '#toggleshowautosaves' ).is( ':checked' ) ) {
+ REVAPP._autosaves = true ;
+ } else {
+ REVAPP._autosaves = false ;
+ }
+ //refresh the model data
+
+ REVAPP.reloadmodel();
+ //TODO check for two handle mode
+
+ },
+
+ //
+ //toggle showing the split diff view
+ //
+ showsplitview : function() {
+ var self = this;
+
+ if ( $( 'input#showsplitview' ).is( ':checked' ) ) {
+ REVAPP._showsplitview = 'true';
+ $('.revisiondiffcontainer').addClass('diffsplit');
+ } else {
+ REVAPP._showsplitview = '';
+ $('.revisiondiffcontainer').removeClass('diffsplit');
+ }
+
+ REVAPP.reloadmodel();
+ }
+ }),
+
+ //
+ //main interactions view
+ //
+ Interact : Backbone.View.extend({
+ el : $('#backbonerevisionsinteract')[0],
+ tagName : 'revisionvinteract',
+ className : 'revisionvinteract-container',
+ template : wp.template('revisionvinteract'),
+
+ initialize : function() {
+ },
+
+ render : function() {
+ var self = this;
+
+ var addhtml = this.template;
+ this.$el.html( addhtml );
+ $( '#diff_max, #diff_maxof' ).html( this.model.length );
+ $( '#diff_count' ).html( REVAPP._right_diff );
+ $( '#diff_left_count_inner' ).html( 0 == REVAPP._left_diff ? '' : 'revision' + REVAPP._left_diff );
+
+ var modelcount = REVAPP._revisions.length;
+
+ slider = $("#slider");
+ if ( 1 == REVAPP._compareoneortwo ) {
+ //set up the slider with a single handle
+ slider.slider({
+ value : REVAPP._right_diff-1,
+ min : 0,
+ max : modelcount-1,
+ step : 1,
+
+ //slide interactions for one handles slider
+ slide : function( event, ui ) {
+ if ( REVAPP.right_model_loading ) //left model stoll loading, prevent sliding left handle
+ return false;
+
+ REVAPP._right_diff =( ui.value+1 );
+ $( '#diff_count' ).html( REVAPP._right_diff );
+ REVAPP._revisionView.render();
+ }
+ });
+ $( '.revisiondiffcontainer' ).removeClass( 'comparetwo' );
+ } else { //comparing more than one, eg 2
+ //set up the slider with two handles
+ slider.slider({
+ values : [ REVAPP._left_diff, REVAPP._right_diff + 1 ],
+ min : 1,
+ max : modelcount+1,
+ step : 1,
+ range: true,
+
+ //in two handled mode when user starts dragging, swap in precalculated diff for handle
+ start : function (event, ui ) {
+ var index = $( ui.handle ).index(); //0 (left) or 1 (right)
+
+ switch ( index ) {
+ case 1: //left handle drag
+ if ( REVAPP.left_model_loading ) //left model stoll loading, prevent sliding left handle
+ return false;
+
+ if ( REVAPP._revisionView.model !== REVAPP._left_handle_revisions &&
+ null != REVAPP._left_handle_revisions )
+ REVAPP._revisionView.model = REVAPP._left_handle_revisions;
+
+ REVAPP._revisionView.draggingleft = true;
+ break;
+
+ case 2: //right
+ if ( REVAPP.right_model_loading ) //right model stoll loading, prevent sliding right handle
+ return false;
+
+ //one extra spot at left end when comparing two
+ if ( REVAPP._revisionView.model !== REVAPP._right_handle_revisions &&
+ null != REVAPP._right_handle_revisions )
+ REVAPP._revisionView.model = REVAPP._right_handle_revisions;
+
+ REVAPP._revisionView.draggingleft = false;
+ REVAPP._right_diff = ui.values[1] - 1 ;
+ break;
+ }
+ },
+
+ //when sliding in two handled mode change appropriate value
+ slide : function( event, ui ) {
+ if ( ui.values[0] == ui.values[1] ) //prevent compare to self
+ return false;
+
+ var index = $( ui.handle ).index(); //0 (left) or 1 (right)
+
+ switch ( index ) {
+ case 1: //left
+ if ( REVAPP.left_model_loading ) //left model stoll loading, prevent sliding left handle
+ return false;
+
+ REVAPP._left_diff = ui.values[0] - 1; //one extra spot at left end when comparing two
+ break;
+
+ case 2: //right
+ if ( REVAPP.right_model_loading ) //right model stoll loading, prevent sliding right handle
+ return false;
+
+ REVAPP._right_diff = ui.values[1] - 1 ;
+ break;
+ }
+
+ $( '#diff_count' ).html( REVAPP._right_diff );
+
+ if ( 0 == REVAPP._left_diff ) {
+ $( '.revisiondiffcontainer' ).addClass( 'currentversion' );
+
+ } else {
+ $( '.revisiondiffcontainer' ).removeClass( 'currentversion' );
+ $( '#diff_left_count_inner' ).html( REVAPP._left_diff );
+ }
+
+ REVAPP._revisionView.render(); //render the diff view
+ },
+
+ //when the user stops sliding in 2 handle mode, recalculate diffs
+ stop : function( event, ui ) {
+ if ( 2 == REVAPP._compareoneortwo ) {
+ //calculate and generate a diff for comparing to the left handle
+ //and the right handle, swap out when dragging
+ if ( ! (REVAPP.left_model_loading && REVAPP.right_model.loading ) ) {
+ REVAPP.reloadleftright();
+ }
+ }
+ }
+ });
+ $( '.revisiondiffcontainer' ).addClass( 'comparetwo' );
+ }
+
+ return this;
+ },
+
+ //next and previous buttons, only available in compare one mode
+ events : {
+ 'click #next' : 'nextrevision',
+ 'click #previous' : 'previousrevision'
+ },
+
+ //go to the next revision
+ nextrevision : function() {
+ if ( REVAPP._right_diff < this.model.length ) //unless at right boundry
+ REVAPP._right_diff = REVAPP._right_diff + 1 ;
+
+ REVAPP._revisionView.render();
+
+ $( '#diff_count' ).html( REVAPP._right_diff );
+ $( '#slider' ).slider( 'value', REVAPP._right_diff - 1 ).trigger( 'slide' );
+ },
+
+ //go the the previous revision
+ previousrevision : function() {
+ if ( REVAPP._right_diff > 1 ) //unless at left boundry
+ REVAPP._right_diff = REVAPP._right_diff - 1 ;
+
+ REVAPP._revisionView.render();
+
+ $( '#diff_count' ).html( REVAPP._right_diff );
+ $( '#slider' ).slider( 'value', REVAPP._right_diff - 1 ).trigger( 'slide' );
+ }
+ })
+ });
+
+ //instantiate Revision Application
+ REVAPP = new wp.revisions.App();
+ //TODO consider enable back button to step back thru states?
+ Backbone.history.start();
+
+}(jQuery));
diff --git a/wp-admin/js/revisions.min.js b/wp-admin/js/revisions.min.js
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/wp-admin/revision.php b/wp-admin/revision.php
index 51a01479a4..452fbd8d85 100644
--- a/wp-admin/revision.php
+++ b/wp-admin/revision.php
@@ -8,15 +8,9 @@
/** WordPress Administration Bootstrap */
require_once('./admin.php');
-
-wp_enqueue_script('list-revisions');
-
-wp_reset_vars(array('revision', 'left', 'right', 'action'));
+wp_reset_vars( array( 'revision', 'action' ) );
$revision_id = absint($revision);
-$left = absint($left);
-$right = absint($right);
-
$redirect = 'edit.php';
switch ( $action ) :
@@ -33,75 +27,13 @@ case 'restore' :
$redirect = 'edit.php?post_type=' . $post->post_type;
break;
}
-
- check_admin_referer( "restore-post_$post->ID|$revision->ID" );
+ check_admin_referer( "restore-post_{$post->ID}|{$revision->ID}" );
wp_restore_post_revision( $revision->ID );
$redirect = add_query_arg( array( 'message' => 5, 'revision' => $revision->ID ), get_edit_post_link( $post->ID, 'url' ) );
break;
-case 'diff' :
- if ( !$left_revision = get_post( $left ) )
- break;
- if ( !$right_revision = get_post( $right ) )
- break;
-
- if ( !current_user_can( 'read_post', $left_revision->ID ) || !current_user_can( 'read_post', $right_revision->ID ) )
- break;
-
- // If we're comparing a revision to itself, redirect to the 'view' page for that revision or the edit page for that post
- if ( $left_revision->ID == $right_revision->ID ) {
- $redirect = get_edit_post_link( $left_revision->ID );
- include( './js/revisions-js.php' );
- break;
- }
-
- // Don't allow reverse diffs?
- if ( strtotime($right_revision->post_modified_gmt) < strtotime($left_revision->post_modified_gmt) ) {
- $redirect = add_query_arg( array( 'left' => $right, 'right' => $left ) );
- break;
- }
-
- if ( $left_revision->ID == $right_revision->post_parent ) // right is a revision of left
- $post =& $left_revision;
- elseif ( $left_revision->post_parent == $right_revision->ID ) // left is a revision of right
- $post =& $right_revision;
- elseif ( $left_revision->post_parent == $right_revision->post_parent ) // both are revisions of common parent
- $post = get_post( $left_revision->post_parent );
- else
- break; // Don't diff two unrelated revisions
-
- if ( ! WP_POST_REVISIONS || !post_type_supports($post->post_type, 'revisions') ) { // Revisions disabled
- if (
- // we're not looking at an autosave
- ( !wp_is_post_autosave( $left_revision ) && !wp_is_post_autosave( $right_revision ) )
- ||
- // we're not comparing an autosave to the current post
- ( $post->ID !== $left_revision->ID && $post->ID !== $right_revision->ID )
- ) {
- $redirect = 'edit.php?post_type=' . $post->post_type;
- break;
- }
- }
-
- if (
- // They're the same
- $left_revision->ID == $right_revision->ID
- ||
- // Neither is a revision
- ( !wp_get_post_revision( $left_revision->ID ) && !wp_get_post_revision( $right_revision->ID ) )
- )
- break;
-
- $post_title = '' . get_the_title() . '';
- $h2 = sprintf( __( 'Compare Revisions of “%1$s”' ), $post_title );
- $title = __( 'Revisions' );
-
- $left = $left_revision->ID;
- $right = $right_revision->ID;
-
- $redirect = false;
- break;
case 'view' :
+case 'edit' :
default :
if ( !$revision = wp_get_post_revision( $revision_id ) )
break;
@@ -119,13 +51,9 @@ default :
$post_title = '' . get_the_title() . '';
$revision_title = wp_post_revision_title( $revision, false );
- $h2 = sprintf( __( 'Revision for “%1$s” created on %2$s' ), $post_title, $revision_title );
+ $h2 = sprintf( __( 'Compare Revisions of “%1$s”' ), $post_title );
$title = __( 'Revisions' );
- // Sets up the diff radio buttons
- $left = $revision->ID;
- $right = $post->ID;
-
$redirect = false;
break;
endswitch;
@@ -145,79 +73,83 @@ if ( !empty($post->post_type) && 'post' != $post->post_type )
else
$parent_file = $submenu_file = 'edit.php';
+wp_enqueue_style( 'revisions' );
+wp_enqueue_script( 'revisions' );
+
require_once( './admin-header.php' );
+//TODO - Some of the translations below split things into multiple strings that are contextually related and this makes it pretty impossible for RTL translation.
+//TODO can we pass the context in a better way
?>
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
'form-table', 'parent' => true, 'right' => $right, 'left' => $left );
-if ( ! WP_POST_REVISIONS || !post_type_supports($post->post_type, 'revisions') )
- $args['type'] = 'autosave';
-
-wp_list_post_revisions( $post, $args );
-
+ $comparetworevisionslink = get_edit_post_link( $revision->ID );
?>
-
+
+
+
+
+
+
+*/
+require_once( './admin-footer.php' );
\ No newline at end of file
diff --git a/wp-includes/css/jquery-ui-slider.css b/wp-includes/css/jquery-ui-slider.css
new file mode 100644
index 0000000000..4ac53e2588
--- /dev/null
+++ b/wp-includes/css/jquery-ui-slider.css
@@ -0,0 +1,544 @@
+/*! jQuery UI - v1.10.1 - 2013-02-15
+* http://jqueryui.com
+* Includes: jquery.ui.core.css, jquery.ui.slider.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS%2CTahoma%2CVerdana%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=gloss_wave&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=highlight_soft&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=glass&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=glass&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=highlight_soft&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=diagonals_thick&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=diagonals_thick&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=flat&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
+* Copyright (c) 2013 jQuery Foundation and other contributors Licensed MIT */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden {
+ display: none;
+}
+.ui-helper-hidden-accessible {
+ border: 0;
+ clip: rect(0 0 0 0);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ width: 1px;
+}
+.ui-helper-reset {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ line-height: 1.3;
+ text-decoration: none;
+ font-size: 100%;
+ list-style: none;
+}
+.ui-helper-clearfix:before,
+.ui-helper-clearfix:after {
+ content: "";
+ display: table;
+ border-collapse: collapse;
+}
+.ui-helper-clearfix:after {
+ clear: both;
+}
+.ui-helper-clearfix {
+ min-height: 0; /* support: IE7 */
+}
+.ui-helper-zfix {
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ position: absolute;
+ opacity: 0;
+ filter:Alpha(Opacity=0);
+}
+
+.ui-front {
+ z-index: 100;
+}
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled {
+ cursor: default !important;
+}
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+ display: block;
+ text-indent: -99999px;
+ overflow: hidden;
+ background-repeat: no-repeat;
+}
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+}
+.ui-slider {
+ position: relative;
+ text-align: left;
+}
+.ui-slider .ui-slider-handle {
+ position: absolute;
+ z-index: 2;
+ width: 1.2em;
+ height: 1.2em;
+ cursor: default;
+}
+.ui-slider .ui-slider-range {
+ position: absolute;
+ z-index: 1;
+ font-size: .7em;
+ display: block;
+ border: 0;
+ background-position: 0 0;
+}
+
+/* For IE8 - See #6727 */
+.ui-slider.ui-state-disabled .ui-slider-handle,
+.ui-slider.ui-state-disabled .ui-slider-range {
+ filter: inherit;
+}
+
+.ui-slider-horizontal {
+ height: .8em;
+}
+.ui-slider-horizontal .ui-slider-handle {
+ top: -.3em;
+ margin-left: -.6em;
+}
+.ui-slider-horizontal .ui-slider-range {
+ top: 0;
+ height: 100%;
+}
+.ui-slider-horizontal .ui-slider-range-min {
+ left: 0;
+}
+.ui-slider-horizontal .ui-slider-range-max {
+ right: 0;
+}
+
+.ui-slider-vertical {
+ width: .8em;
+ height: 100px;
+}
+.ui-slider-vertical .ui-slider-handle {
+ left: -.3em;
+ margin-left: 0;
+ margin-bottom: -.6em;
+}
+.ui-slider-vertical .ui-slider-range {
+ left: 0;
+ width: 100%;
+}
+.ui-slider-vertical .ui-slider-range-min {
+ bottom: 0;
+}
+.ui-slider-vertical .ui-slider-range-max {
+ top: 0;
+}
+
+/* Component containers
+----------------------------------*/
+.ui-widget {
+ font-family: Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;
+ font-size: 1.1em;
+}
+.ui-widget .ui-widget {
+ font-size: 1em;
+}
+.ui-widget input,
+.ui-widget select,
+.ui-widget textarea,
+.ui-widget button {
+ font-family: Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;
+ font-size: 1em;
+}
+.ui-widget-content {
+ border: 1px solid #dddddd;
+ background: #eeeeee url(../images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x;
+ color: #333333;
+}
+.ui-widget-content a {
+ color: #333333;
+}
+.ui-widget-header {
+ border: 1px solid #e78f08;
+ background: #f6a828 url(../images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x;
+ color: #ffffff;
+ font-weight: bold;
+}
+.ui-widget-header a {
+ color: #ffffff;
+}
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default,
+.ui-widget-content .ui-state-default,
+.ui-widget-header .ui-state-default {
+ border: 1px solid #cccccc;
+ background: #f6f6f6 url(../images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x;
+ font-weight: bold;
+ color: #1c94c4;
+}
+.ui-state-default a,
+.ui-state-default a:link,
+.ui-state-default a:visited {
+ color: #1c94c4;
+ text-decoration: none;
+}
+.ui-state-hover,
+.ui-widget-content .ui-state-hover,
+.ui-widget-header .ui-state-hover,
+.ui-state-focus,
+.ui-widget-content .ui-state-focus,
+.ui-widget-header .ui-state-focus {
+ border: 1px solid #fbcb09;
+ background: #fdf5ce url(../images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x;
+ font-weight: bold;
+ color: #c77405;
+}
+.ui-state-hover a,
+.ui-state-hover a:hover,
+.ui-state-hover a:link,
+.ui-state-hover a:visited {
+ color: #c77405;
+ text-decoration: none;
+}
+.ui-state-active,
+.ui-widget-content .ui-state-active,
+.ui-widget-header .ui-state-active {
+ border: 1px solid #fbd850;
+ background: #ffffff url(../images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;
+ font-weight: bold;
+ color: #eb8f00;
+}
+.ui-state-active a,
+.ui-state-active a:link,
+.ui-state-active a:visited {
+ color: #eb8f00;
+ text-decoration: none;
+}
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight,
+.ui-widget-content .ui-state-highlight,
+.ui-widget-header .ui-state-highlight {
+ border: 1px solid #fed22f;
+ background: #ffe45c url(../images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x;
+ color: #363636;
+}
+.ui-state-highlight a,
+.ui-widget-content .ui-state-highlight a,
+.ui-widget-header .ui-state-highlight a {
+ color: #363636;
+}
+.ui-state-error,
+.ui-widget-content .ui-state-error,
+.ui-widget-header .ui-state-error {
+ border: 1px solid #cd0a0a;
+ background: #b81900 url(../images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat;
+ color: #ffffff;
+}
+.ui-state-error a,
+.ui-widget-content .ui-state-error a,
+.ui-widget-header .ui-state-error a {
+ color: #ffffff;
+}
+.ui-state-error-text,
+.ui-widget-content .ui-state-error-text,
+.ui-widget-header .ui-state-error-text {
+ color: #ffffff;
+}
+.ui-priority-primary,
+.ui-widget-content .ui-priority-primary,
+.ui-widget-header .ui-priority-primary {
+ font-weight: bold;
+}
+.ui-priority-secondary,
+.ui-widget-content .ui-priority-secondary,
+.ui-widget-header .ui-priority-secondary {
+ opacity: .7;
+ filter:Alpha(Opacity=70);
+ font-weight: normal;
+}
+.ui-state-disabled,
+.ui-widget-content .ui-state-disabled,
+.ui-widget-header .ui-state-disabled {
+ opacity: .35;
+ filter:Alpha(Opacity=35);
+ background-image: none;
+}
+.ui-state-disabled .ui-icon {
+ filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
+}
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+ width: 16px;
+ height: 16px;
+ background-position: 16px 16px;
+}
+.ui-icon,
+.ui-widget-content .ui-icon {
+ background-image: url(../images/ui-icons_222222_256x240.png);
+}
+.ui-widget-header .ui-icon {
+ background-image: url(../images/ui-icons_ffffff_256x240.png);
+}
+.ui-state-default .ui-icon {
+ background-image: url(../images/ui-icons_ef8c08_256x240.png);
+}
+.ui-state-hover .ui-icon,
+.ui-state-focus .ui-icon {
+ background-image: url(../images/ui-icons_ef8c08_256x240.png);
+}
+.ui-state-active .ui-icon {
+ background-image: url(../images/ui-icons_ef8c08_256x240.png);
+}
+.ui-state-highlight .ui-icon {
+ background-image: url(../images/ui-icons_228ef1_256x240.png);
+}
+.ui-state-error .ui-icon,
+.ui-state-error-text .ui-icon {
+ background-image: url(../images/ui-icons_ffd27a_256x240.png);
+}
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-on { background-position: -96px -144px; }
+.ui-icon-radio-off { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-left,
+.ui-corner-tl {
+ border-top-left-radius: 4px;
+}
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-right,
+.ui-corner-tr {
+ border-top-right-radius: 4px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-left,
+.ui-corner-bl {
+ border-bottom-left-radius: 4px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-right,
+.ui-corner-br {
+ border-bottom-right-radius: 4px;
+}
+
+/* Overlays */
+.ui-widget-overlay {
+ background: #666666 url(../images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat;
+ opacity: .5;
+ filter: Alpha(Opacity=50);
+}
+.ui-widget-shadow {
+ margin: -5px 0 0 -5px;
+ padding: 5px;
+ background: #000000 url(../images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x;
+ opacity: .2;
+ filter: Alpha(Opacity=20);
+ border-radius: 5px;
+}
diff --git a/wp-includes/css/jquery-ui-slider.min.css b/wp-includes/css/jquery-ui-slider.min.css
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/wp-includes/js/template.js b/wp-includes/js/template.js
new file mode 100644
index 0000000000..a8bcdfaa91
--- /dev/null
+++ b/wp-includes/js/template.js
@@ -0,0 +1,29 @@
+window.wp = window.wp || {};
+
+(function ($) {
+ var template;
+ /**
+ * wp.template( id )
+ *
+ * Fetches a template by id.
+ *
+ * @param {string} id A string that corresponds to a DOM element with an id prefixed with "tmpl-".
+ * For example, "attachment" maps to "tmpl-attachment".
+ * @return {function} A function that lazily-compiles the template requested.
+ */
+ template = wp.template = _.memoize(function ( id ) {
+ var compiled,
+ options = {
+ evaluate: /<#([\s\S]+?)#>/g,
+ interpolate: /\{\{\{([\s\S]+?)\}\}\}/g,
+ escape: /\{\{([^\}]+?)\}\}(?!\})/g,
+ variable: 'data'
+ };
+
+ return function ( data ) {
+ compiled = compiled || _.template( $( '#tmpl-' + id ).html(), null, options );
+ return compiled( data );
+ };
+ });
+
+}(jQuery));
diff --git a/wp-includes/js/template.min.js b/wp-includes/js/template.min.js
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/wp-includes/pluggable.php b/wp-includes/pluggable.php
index 99aaad12bf..3041eb2fab 100644
--- a/wp-includes/pluggable.php
+++ b/wp-includes/pluggable.php
@@ -1713,16 +1713,20 @@ function wp_text_diff( $left_string, $right_string, $args = null ) {
$left_lines = explode("\n", $left_string);
$right_lines = explode("\n", $right_string);
-
$text_diff = new Text_Diff($left_lines, $right_lines);
- $renderer = new WP_Text_Diff_Renderer_Table();
+ $renderer = new WP_Text_Diff_Renderer_Table( $args );
$diff = $renderer->render($text_diff);
if ( !$diff )
return '';
$r = "\n";
- $r .= "";
+
+ if ( isset( $args[ 'showsplitview' ] ) && 'true' == $args[ 'showsplitview' ] ) {
+ $r .= "";
+ } else {
+ $r .= "";
+ }
if ( $args['title'] || $args['title_left'] || $args['title_right'] )
$r .= "";
diff --git a/wp-includes/post-template.php b/wp-includes/post-template.php
index 13a8407f15..06be04786f 100644
--- a/wp-includes/post-template.php
+++ b/wp-includes/post-template.php
@@ -1300,23 +1300,34 @@ function wp_post_revision_title( $revision, $link = true ) {
if ( !in_array( $revision->post_type, array( 'post', 'page', 'revision' ) ) )
return false;
+ $author = get_the_author_meta( 'display_name', $revision->post_author );
/* translators: revision date format, see http://php.net/date */
- $datef = _x( 'j F, Y @ G:i', 'revision date format');
- /* translators: 1: date */
- $autosavef = __( '%1$s [Autosave]' );
- /* translators: 1: date */
- $currentf = __( '%1$s [Current Revision]' );
+ $datef = _x( 'j F, Y @ G:i:s', 'revision date format');
+
+ $gravatar = get_avatar( $revision->post_author, 18 );
$date = date_i18n( $datef, strtotime( $revision->post_modified ) );
if ( $link && current_user_can( 'edit_post', $revision->ID ) && $link = get_edit_post_link( $revision->ID ) )
$date = "$date";
+
+ $revision_date_author = sprintf(
+ '%s %s, %s %s (%s)',
+ $gravatar,
+ $author,
+ human_time_diff( strtotime( $revision->post_modified ), current_time( 'timestamp' ) ),
+ __( 'ago' ),
+ $date
+ );
+
+ $autosavef = __( '%1$s [Autosave]' );
+ $currentf = __( '%1$s [Current Revision]' );
if ( !wp_is_post_revision( $revision ) )
- $date = sprintf( $currentf, $date );
+ $revision_date_author = sprintf( $currentf, $revision_date_author );
elseif ( wp_is_post_autosave( $revision ) )
- $date = sprintf( $autosavef, $date );
+ $revision_date_author = sprintf( $autosavef, $revision_date_author );
- return $date;
+ return $revision_date_author;
}
/**
diff --git a/wp-includes/script-loader.php b/wp-includes/script-loader.php
index d168c2c99a..5be260b025 100644
--- a/wp-includes/script-loader.php
+++ b/wp-includes/script-loader.php
@@ -270,7 +270,10 @@ function wp_default_scripts( &$scripts ) {
$scripts->add( 'json2', "/wp-includes/js/json2$suffix.js", array(), '2011-02-23');
$scripts->add( 'underscore', '/wp-includes/js/underscore.min.js', array(), '1.4.4', 1 );
- $scripts->add( 'backbone', '/wp-includes/js/backbone.min.js', array('underscore','jquery'), '0.9.2', 1 );
+ $scripts->add( 'template', "/wp-includes/js/template$suffix.js", array('underscore'), '1.4.4', 1 );
+ $scripts->add( 'backbone', '/wp-includes/js/backbone.min.js', array('underscore','jquery', 'template'), '0.9.2', 1 );
+
+ $scripts->add( 'revisions', "/wp-admin/js/revisions$suffix.js", array( 'backbone', 'jquery-ui-slider' ), false, 1 );
$scripts->add( 'imgareaselect', "/wp-includes/js/imgareaselect/jquery.imgareaselect$suffix.js", array('jquery'), '0.9.8', 1 );
@@ -539,6 +542,8 @@ function wp_default_styles( &$styles ) {
$styles->add( 'customize-controls', "/wp-admin/css/customize-controls$suffix.css", array( 'wp-admin', 'colors', 'ie' ) );
$styles->add( 'media-views', "/wp-includes/css/media-views$suffix.css", array( 'buttons' ) );
$styles->add( 'buttons', "/wp-includes/css/buttons$suffix.css" );
+ $styles->add( 'wp-jquery-ui-slider', "/wp-includes/css/jquery-ui-slider$suffix.css" );
+ $styles->add( 'revisions', "/wp-admin/css/revisions$suffix.css", array( 'wp-jquery-ui-slider' ) );
foreach ( $rtl_styles as $rtl_style ) {
$styles->add_data( $rtl_style, 'rtl', true );
diff --git a/wp-includes/wp-diff.php b/wp-includes/wp-diff.php
index 65dd00743d..be6187f697 100644
--- a/wp-includes/wp-diff.php
+++ b/wp-includes/wp-diff.php
@@ -59,6 +59,15 @@ class WP_Text_Diff_Renderer_Table extends Text_Diff_Renderer {
*/
var $inline_diff_renderer = 'WP_Text_Diff_Renderer_inline';
+ /**
+ * Should we show the split view or not
+ *
+ * @var string
+ * @access protected
+ * @since 3.6.0
+ */
+ var $_show_split_view = true;
+
/**
* Constructor - Call parent constructor with params array.
*
@@ -70,6 +79,8 @@ class WP_Text_Diff_Renderer_Table extends Text_Diff_Renderer {
*/
function __construct( $params = array() ) {
parent::__construct( $params );
+ if ( isset( $params[ 'show_split_view' ] ) )
+ $this->_show_split_view = $params[ 'show_split_view' ];
}
/**
@@ -98,7 +109,8 @@ class WP_Text_Diff_Renderer_Table extends Text_Diff_Renderer {
* @return string
*/
function addedLine( $line ) {
- return "| + | {$line} | ";
+ return "{$line} | ";
+
}
/**
@@ -108,7 +120,7 @@ class WP_Text_Diff_Renderer_Table extends Text_Diff_Renderer {
* @return string
*/
function deletedLine( $line ) {
- return "- | {$line} | ";
+ return "{$line} | ";
}
/**
@@ -118,7 +130,7 @@ class WP_Text_Diff_Renderer_Table extends Text_Diff_Renderer {
* @return string
*/
function contextLine( $line ) {
- return " | {$line} | ";
+ return "{$line} | ";
}
/**
@@ -127,7 +139,7 @@ class WP_Text_Diff_Renderer_Table extends Text_Diff_Renderer {
* @return string
*/
function emptyLine() {
- return ' | ';
+ return ' | ';
}
/**
@@ -142,8 +154,12 @@ class WP_Text_Diff_Renderer_Table extends Text_Diff_Renderer {
$r = '';
foreach ($lines as $line) {
if ( $encode )
- $line = htmlspecialchars( $line );
- $r .= '' . $this->emptyLine() . $this->addedLine( $line ) . "
\n";
+ $line = wp_kses_post( $line );
+ if ( $this->_show_split_view ) {
+ $r .= '' . $this->emptyLine() . $this->emptyLine() . $this->addedLine( $line ) . "
\n";
+ } else {
+ $r .= '' . $this->addedLine( $line ) . "
\n";
+ }
}
return $r;
}
@@ -160,8 +176,13 @@ class WP_Text_Diff_Renderer_Table extends Text_Diff_Renderer {
$r = '';
foreach ($lines as $line) {
if ( $encode )
- $line = htmlspecialchars( $line );
- $r .= '' . $this->deletedLine( $line ) . $this->emptyLine() . "
\n";
+ $line = wp_kses_post( $line );
+ if ( $this->_show_split_view ) {
+ $r .= '' . $this->deletedLine( $line ) . $this->emptyLine() . $this->emptyLine() . "
\n";
+ } else {
+ $r .= '' . $this->deletedLine( $line ) . "
\n";
+ }
+
}
return $r;
}
@@ -178,9 +199,12 @@ class WP_Text_Diff_Renderer_Table extends Text_Diff_Renderer {
$r = '';
foreach ($lines as $line) {
if ( $encode )
- $line = htmlspecialchars( $line );
- $r .= '' .
- $this->contextLine( $line ) . $this->contextLine( $line ) . "
\n";
+ $line = wp_kses_post( $line );
+ if ( $this->_show_split_view ) {
+ $r .= '' . $this->contextLine( $line ) . $this->emptyLine() . $this->contextLine( $line ) . "
\n";
+ } else {
+ $r .= '' . $this->contextLine( $line ) . "
\n";
+ }
}
return $r;
}
@@ -264,7 +288,11 @@ class WP_Text_Diff_Renderer_Table extends Text_Diff_Renderer {
} elseif ( $final_rows[$row] < 0 ) { // Final is blank. This is really a deleted row.
$r .= $this->_deleted( array($orig_line), false );
} else { // A true changed row.
- $r .= '' . $this->deletedLine( $orig_line ) . $this->addedLine( $final_line ) . "
\n";
+ if ( $this->_show_split_view ) {
+ $r .= '' . $this->deletedLine( $orig_line ) . $this->emptyLine() . $this->addedLine( $final_line ) . "
\n";
+ } else {
+ $r .= '' . $this->deletedLine( $orig_line ) . "
" . $this->addedLine( $final_line ) . "
\n";
+ }
}
}