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 ?> + +
+ +
- -

- - - - - - - - - $field_title ) : - if ( 'diff' == $action ) { - $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' ); - if ( !$content = wp_text_diff( $left_content, $right_content ) ) - continue; // There is no difference between left and right - $identical = false; - } else { - add_filter( "_wp_post_revision_field_$field", 'htmlspecialchars' ); - $content = apply_filters( "_wp_post_revision_field_$field", $revision->$field, $field, $revision, '' ); - } - ?> - - - - - - - - - - - - -
- - -

- -
- -

- +

+
+
+

+
+
+
'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 ""; + return ""; + } /** @@ -108,7 +120,7 @@ class WP_Text_Diff_Renderer_Table extends Text_Diff_Renderer { * @return string */ function deletedLine( $line ) { - return ""; + return ""; } /** @@ -118,7 +130,7 @@ class WP_Text_Diff_Renderer_Table extends Text_Diff_Renderer { * @return string */ function contextLine( $line ) { - return ""; + return ""; } /** @@ -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"; + } } }
+{$line}{$line}-{$line}{$line} {$line}{$line}