diff --git a/wp-admin/css/colors-fresh.css b/wp-admin/css/colors-fresh.css index d5088678ec..7916261dff 100644 --- a/wp-admin/css/colors-fresh.css +++ b/wp-admin/css/colors-fresh.css @@ -175,8 +175,7 @@ h3.dashboard-widget-title small, .sidebar-name, #nav-menu-header, #nav-menu-footer, -.menu-item-handle, -.wp-slider .ui-slider-handle { +.menu-item-handle { background: #f1f1f1; background-image: -webkit-gradient(linear, left bottom, left top, from(#ececec), to(#f9f9f9)); background-image: -webkit-linear-gradient(bottom, #ececec, #f9f9f9); @@ -185,6 +184,8 @@ h3.dashboard-widget-title small, background-image: linear-gradient(to top, #ececec, #f9f9f9); } + + .widget .widget-top, .postbox h3, .stuffbox h3 { @@ -1378,14 +1379,38 @@ table.diff .diff-addedline ins { background-color: #e9f6ea; } +.diff-to-title { + color: #0080AA; +} + #diffsubheader{ background-color: #f7f7f7; } +.comparetwo#diffsubheader.diff-left-hand-meta-row { + background-color: #fcfcfc; +} + +.revision-tick.revision-toloadtrue { + background-color: #9999cc; + background: url(../images/wpspin_light.gif) no-repeat; + background-position: middle; + background-size: 1px 10px; +} + +.revision-tick.revision-toloadfalse { + background-color: #aaa; +} + #att-info { background-color: #e4f2Fd; } +body .ui-tooltip { + border-color: #d7d7d7; + background-color: #fff; +} + /* jQuery UI Slider */ .wp-slider.ui-slider { border-color: #d7d7d7; @@ -1393,22 +1418,30 @@ table.diff .diff-addedline ins { } .wp-slider .ui-slider-handle { - border-color: #d7d7d7; + border-color: none; +} + +.wp-slider .ui-slider-handle.left-handle { +background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAA3NCSVQICAjb4U/gAAABAlBMVEXR2uHM1dzCzNW4ydOzxtSxw9Gqwc+bs7+Ss8SVscaZrLqQq7yNrMCKqr+EqsGDqb6GpruCpbl8pL15o7t1n7hwnLVika1djq5giqJXiqlYiqNJgp9ieYlDfqA/epw3dpk7dpg2dpo3dZo6dZc4dJY4dJg3cZY2bpE1bosxaIYxZIMrYX0tXnwtXHYsWHEnVW0mTmglT2cjTGIhRVsfQlYaN0kYM0QULDgTKTYRJzQTJzINISoLHCYNGyYKGCEIFxwJEhcJEhsHEhQDDAkHCg8EBwwCBwoEBAQBAwIBAQEBAQMAAgEBAAAAAAQAAQMBAAIAAAICAAEBAQAAAQAAAAD///+62qV+AAAAVnRSTlP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////AEpNbNkAAAAJcEhZcwAACusAAArrAYKLDVoAAAAUdEVYdENyZWF0aW9uIFRpbWUAMy85LzEzrdD8jAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAACbSURBVBiVVcvVDoNQEEXRqbu781B3d/dQQknh/P+vtBQKt/tpsnKGEOW4klkQFFvIsqwYzUJUvCts1wJl9gIruxT5hpLEyMBLKG+Z0ToJgrPLTDqOjyCxNN7mcahiaz50uDWsX0Fk+tKahKGJpX55qp1qpAsCY0lt5MdPUD2KoniowBRXn+f5Xp4RZDfCKg1W0D637P/iznn06w0M+083NZW9ZwAAAABJRU5ErkJggg==); +} + +.wp-slider .ui-slider-handle.ui-state-active.left-handle { +background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAA3NCSVQICAjb4U/gAAAAzFBMVEXZ5ejU4eXM3ODG2NzE1tvB1Nq90deux86sxs2qxcynwsqlwcmjwMihvseevMWdvMSbusOXuMGTtb6IrbiHrLeCqbSBqLN/p7J3oa11oKxzn6tvnKhrmaZqmKVpmKVol6RllaJhk6Bej51djptaiZZZiJVYhpNWg5BUf4xSfYlRfIhPeYRMdYBKcXxFaXNDZnA+X2g9XmY8XGU4VV43VFw2U1s0UFgyTVQxS1IwSVAuR00sREosQ0orQkgqQEYpPkQoPkMoPUMoPUL///8pY4MvAAAARHRSTlP/////////////////////////////////////////////////////////////////////////////////////////AHHSjxIAAAAJcEhZcwAACusAAArrAYKLDVoAAAAUdEVYdENyZWF0aW9uIFRpbWUAMy85LzEzrdD8jAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAACUSURBVBiVVctXEoJQEETRMaIo5qwF5hwxYOY9ev97EiQ43q+pUz2EYk9n5UElU0rpRO016toO79WhxlVysWqkroRgsswSjAsbnasgpGdsMk25gooZvR3K8CQxCuU9jH8FhZ3022rwJTZ4CK9nnwJBbiO8yVpFKDButm1bOn6iLFyZt5igeZLHOrhgfJ8k/yXTVoLrAxo1P5iCdUg7AAAAAElFTkSuQmCC); +} + +.wp-slider .ui-slider-handle { + /* Slider drag Triangle CSS */ +background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAA3NCSVQICAjb4U/gAAAA8FBMVEU2dZipwNBJl8VGmcX///+EpLlBgqpymrNFjru3ydNWiKs6eZzY4uuRrL08faPL3OZBjLSBqsCTssRHlMJEf59cj657o7xKl8OEqsE9gag2dJtEkb+ct8iZs8BHmMePq8BejKZAiK5llK5FjrlJl8c6dZdGl8avxdBJlcZ4nbc6ep6XrbpKgZ+Lqr5KmcdIkbqsws1Gk8E+f6c4dptaiadFirRKl8V8pblImcNIl8eGpruVscZCh7BMlsdIlcFImchEkbs9eJpCjbdGjbk8fJ84dp02dpo8gatMlsM2dps8faVAg61Ej71Ek75IksFIlcOaLCw7AAAAUHRSTlP/////AP///////////////////////////////////////////////////////////////////////////////////////////////////xB6m5UAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAUdEVYdENyZWF0aW9uIFRpbWUAMy85LzEzrdD8jAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAACaSURBVBiVVcxZD8FAGIXhjxzUVktQgqKmo7ZYhkgsiS1tQuj//zeomo736uS5OFSo2W6UXc/R5hxXW5foxDlXqUKZx0GFZpXynuM4kXhjgjgyJkGzQIjpvi9Fx1uQ0iQUh4GkR/Ini0CQ2IfQ24YC4X8T+Mn0zj8lO1IgnqZpzlxE0m4YhrFsKYJVn126UGV+W1wHf4LdpByuF0goFKI7tv/dAAAAAElFTkSuQmCC); } .wp-slider .ui-slider-handle.ui-state-hover, .wp-slider .ui-slider-handle.ui-state-focus { - border-color: #aaa; + border-color: none; + outline: none; } .wp-slider .ui-slider-handle.ui-state-active { - border-color: #aaa; - background: #eee; - background-image: -webkit-gradient(linear, left bottom, left top, from(#f9f9f9), to(#ececec)); - background-image: -webkit-linear-gradient(bottom, #f9f9f9, #ececec); - background-image: -moz-linear-gradient(bottom, #f9f9f9, #ececec); - background-image: -o-linear-gradient(bottom, #f9f9f9, #ececec); - background-image: linear-gradient(to top, #f9f9f9, #ececec); + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAA3NCSVQICAjb4U/gAAAA51BMVEUgZpDkzc0yd6f///8mcqFJm8cjbZZzr80mg78lh8BDk8UngLl+s9AmfKk4hrGeweBaoMhNlMORwt4nd6Zdm8BAjMEnf7RYmsMkb50mhsFWlsYhZ5ImhbwocZg0f61Lk8E9i7twqNBgo8VSmMUofLBcm8o3faUpfK8mh8Aia5MgZpFMmcgpeapDmcJjo8sliMEmh70nhLkkcKAqgLF2sc8sc5ojbZsngrMkh8EnfKw1eaUjbpkkapImeKQgaJAohb0mh8MmhcMng7kkcKEpf68iZ48haJMmhb8kicEmc6MibJkia5UnhLsw1mWvAAAATXRSTlP/AP8A/////////////////////////////////////////////////////////////////////////////////////////////////9/iR18AAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAUdEVYdENyZWF0aW9uIFRpbWUAMy85LzEzrdD8jAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAACaSURBVBiVVc15D8FAEIfh+Ymj6761LIrSiCNVVyjbRGgifP/PQ6q22/evyZPJDNXzD6G0qNDq5PtO3DJDFyfRpk+po2Eo0h5Qx9U0LRa3SejdlR2rDMLI41yKh6/AtOSzUiuU4kvemSMUDBsRXGuRIHj/CvCXyTNcSXelQBQYY1uBWMY651xfK4KzbdgzqJI73LK7hGC6r0bTB5apIhqIH/YIAAAAAElFTkSuQmCC); } /* edit image */ diff --git a/wp-admin/css/wp-admin.css b/wp-admin/css/wp-admin.css index 1bbaafb293..b831e61436 100644 --- a/wp-admin/css/wp-admin.css +++ b/wp-admin/css/wp-admin.css @@ -3597,6 +3597,16 @@ table.diff .diff-addedline ins { vertical-align: middle; } +.diff-from-title, +.diff-to-title { + font-size: 14px; + font-weight: bold; + width:60px; + text-align: right; + float: left; + margin-right: 5px; +} + .revisiondiffcontainer { width: 96%; } @@ -3605,13 +3615,15 @@ table.diff .diff-addedline ins { margin: 2px; } -#diffrestore, -#diffnext, -#diffcancel { +#diffnext { float: right; margin-right: 5px; } +#diffrestore input{ + margin-left: 10px; +} + #diffprevious, #difftitle, #difftitlefrom, @@ -3623,7 +3635,6 @@ table.diff .diff-addedline ins { #diffprevious, #diffnext { - margin-top: 7px; height: 30px; } @@ -3635,24 +3646,37 @@ table.diff .diff-addedline ins { #diffheader { border-bottom: 1px solid #dfdfdf; width: 100%; - height: 45px; - line-height: 45px; - padding-top: 10px; + height: 40px; + line-height: 40px; + padding-top: 30px; } -#diffsubheader { - border-bottom: 1px solid #dfdfdf; +#diffsubheader,.diff-left-hand-meta-row { width: 100%; height:35px; line-height: 35px; + display: block; } -#diffslider { +#diffslider{ width: 70%; margin-left: auto; margin-right: auto; text-align: center; - height: 3.5em; + height: 0.8em; + margin-top: 20px; +} + +.diff-slider-ticks-wrapper { + margin-left: auto; + margin-right: auto; + text-align: center; +} + +#diff-slider-ticks { + position: absolute; + margin-top: 50px; + z-index: 1; } #revisioncount { @@ -3722,6 +3746,9 @@ table.diff .diff-addedline ins { #comparetworevisions { float: right; + position: absolute; + top: 10px; + right: 10px; line-height: 35px; padding-right: 5px; } @@ -3731,10 +3758,15 @@ table.diff .diff-addedline ins { } #difftitle img, -#difftitlefrom img { +#difftitlefrom img, +.post-revisions li img { vertical-align: middle; margin-left: 5px; } +.post-revisions li { + vertical-align: middle; + height: 28px; +} #showsplitviewoption, #toggleshowautosavesoption { @@ -3757,11 +3789,11 @@ table.diff .diff-addedline ins { .comparetwo #diffprevious, .comparetwo #diffnext, span#diff_left_current_revision, -span#diff_from_current_revision, +#diff_from_current_revision, .currentversion span#diff_left_count, .currentversion span#diff_left_count_inner, -.currentversion #difftitlefrom, -.comparetwo.currentversion #difftitlefrom { +.comparetwo.currentversion #diff_from_current_revision, +#diffsubheader.diff-left-hand-meta-row { display: none; } @@ -3769,13 +3801,51 @@ span#diff_from_current_revision, span#diff_left_count, span#diff_left_count_inner, .comparetwo #difftitlefrom, -.comparetwo.currentversion span#diff_from_current_revision, .leftmodelloading #modelsloading, .rightmodelloading #modelsloading, .leftmodelloading #modelsloading .spinner, .rightmodelloading #modelsloading .spinner, -{ - display: inline; +.comparetwo #diffsubheader.diff-left-hand-meta-row { + display: block; +} + +.revision-tick { + width: 1px; + float: left; + margin-right: 15px; + height: 11px; + padding: 0; + margin-left: 0px; +} + +.revision-tick.revision-scopeofchanges-vsmall { + width: 1px; + background-color: #aaa; +} + +.revision-tick.revision-scopeofchanges-small { + width: 2px; + background-color: #aaa; + margin-left: -1px; +} + +.revision-tick.revision-scopeofchanges-med { + width: 3px; + margin-left: -2px; + background-color: #666; +} + +.revision-tick.revision-scopeofchanges-large { + width: 4px; + margin-left: -3px; + background-color: #333; +} + +.revision-tick.revision-scopeofchanges-vlarge { + margin-left: -3px; + width: 4px; + background-color: #111; + left: 1; } .diff-loading { @@ -3792,23 +3862,89 @@ span#diff_left_count_inner, float: none; } -#difftitlefrom { - float: left; - display: none; -} - #modelsloading { float: right; + position: absolute; line-height: 30px; display: none; clear: none; - margin: 0; + right: 170px; margin-top: -40px; } #modelsloading .spinner { float: left; - } +} + +.ui-tooltip-content img { + float: left; + margin-right: 5px; +} + + + +/* jQuery UI Tooltip 1.10.1 */ + +.ui-tooltip { + padding: 8px; + position: absolute; + z-index: 9999; + max-width: 300px; + min-width: 130px; +} + +body .ui-tooltip { + border-width: 1px; +} + +.ui-tooltip, .arrow:after { + border: 1px solid #d7d7d7; +} + +.ui-tooltip { + padding: 5px 10px; +} + +.arrow { + width: 70px; + height: 16px; + overflow: hidden; + position: absolute; + left: 50%; + margin-left: -35px; + bottom: -16px; + z-index: 99999; + +} + +.arrow.top { + top: -16px; + bottom: auto; +} + +.arrow.left { + left: 20%; +} + +.arrow:after { + content: ""; + position: absolute; + left: 20px; + top: -20px; + width: 25px; + height: 25px; + background-color: #FFF; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + tranform: rotate(45deg); +} + +.arrow.top:after { + bottom: -20px; + top: auto; +} /* jQuery UI Slider */ @@ -3824,11 +3960,9 @@ span#diff_left_count_inner, .wp-slider .ui-slider-handle { position: absolute; z-index: 2; - width: 1.2em; - height: 1.2em; - border-width: 1px; - border-style: solid; - border-radius: 3px; + width: 17px; + height: 17px; + border: none; } .wp-slider .ui-slider-range { diff --git a/wp-admin/includes/ajax-actions.php b/wp-admin/includes/ajax-actions.php index a5a3a167d7..7d7d90c759 100644 --- a/wp-admin/includes/ajax-actions.php +++ b/wp-admin/includes/ajax-actions.php @@ -2123,35 +2123,26 @@ function wp_ajax_revisions_data() { /* translators: revision date format, see http://php.net/date */ $datef = _x( 'j F, Y @ G:i:s', 'revision date format'); + $left_revision = get_post( $compare_to ); + //single model fetch mode + //return the diff of a single revision comparison if ( 0 != $single_revision_id ) { - $left_revision = get_post( $compare_to ); $right_revision = get_post( $single_revision_id ); - if ( $compare_two_mode ) { - $compare_to_gravatar = get_avatar( $left_revision->post_author, 18 ); - $compare_to_author = get_the_author_meta( 'display_name', $left_revision->post_author ); - $compare_to_date = date_i18n( $datef, strtotime( $left_revision->post_modified ) ); - - $revision_from_date_author = sprintf( - /* translators: post revision title: 1: author avatar, 2: author name, 3: time ago, 4: date */ - _x( '%1$s %2$s, %3$s ago (%4$s)', 'post revision title' ), - $compare_to_gravatar, - $compare_to_author, - human_time_diff( strtotime( $left_revision->post_modified ), current_time( 'timestamp' ) ), - $compare_to_date - ); - } - // //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; } + $linesadded=0; + $linesdeleted=0; + // //compare from left to right, passed from application // @@ -2167,41 +2158,77 @@ function wp_ajax_revisions_data() { if ( ! empty( $show_split_view ) ) $args = array( 'show_split_view' => true ); - $content .= wp_text_diff( $left_content, $right_content, $args ); + $diff = wp_text_diff_with_count( $left_content, $right_content, $args ); + + if ( isset( $diff[ 'html' ] ) ) + $content .= $diff[ 'html' ]; + + if ( isset( $diff[ 'linesadded' ] ) ) + $linesadded = $linesadded + $diff[ 'linesadded' ]; + + if ( isset( $diff[ 'linesdeleted' ] ) ) + $linesdeleted = $linesdeleted + $diff[ 'linesdeleted' ]; + + } - $content = '' == $content ? __( 'No difference' ) : $content; - $alltherevisions = array ( - 'revisiondiff' => $content - ); + $content = '' == $content ? __( 'No difference' ) : $content; + + $alltherevisions = array ( + 'revisiondiff' => $content, + 'lines_deleted' => $linesdeleted, + 'lines_added' => $linesadded + ); echo json_encode( $alltherevisions ); exit(); - } + } //end single model fetch + + //fetch the list of revisions available //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 ( $compare_two_mode ) - array_unshift( $revisions, get_post( $post_id ) ); - + if ( ! wp_first_revision_matches_current_version( $post_id ) ) //revisions don't have current version + array_unshift( $revisions, get_post( $post_id ) ) ; + //$revisions->append ( get_post( $post_id ) ); + //error_log( var_dump( $revisions )); $count = -1; + //reverse the list to start with oldes revision + $revisions = array_reverse( $revisions ); + + $previous_revision_id = 0; foreach ( $revisions as $revision ) : - if ( ! empty( $show_autosaves ) && wp_is_post_autosave( $revision ) ) + //error_log( ( $show_autosaves )); + if ( empty( $show_autosaves ) && wp_is_post_autosave( $revision ) ) continue; $revision_from_date_author = ''; $count++; // return blank data for diffs to the left of the left handle (for right handel model) // or to the right of the right handle (for left handel model) - if ( ( 0 != $left_handle_at && $count <= $left_handle_at ) || - ( 0 != $right_handle_at && $count > $right_handle_at )) { + if ( ( 0 != $left_handle_at && $count <= $left_handle_at ) || + ( 0 != $right_handle_at && $count > $right_handle_at )) { $alltherevisions[] = array ( 'ID' => $revision->ID, ); - continue; } - $gravatar = get_avatar( $revision->post_author, 18 ); + if ( $compare_two_mode ) { + $compare_to_gravatar = get_avatar( $left_revision->post_author, 24 ); + $compare_to_author = get_the_author_meta( 'display_name', $left_revision->post_author ); + $compare_to_date = date_i18n( $datef, strtotime( $left_revision->post_modified ) ); + + $revision_from_date_author = sprintf( + /* translators: post revision title: 1: author avatar, 2: author name, 3: time ago, 4: date */ + _x( '%1$s %2$s, %3$s ago (%4$s)', 'post revision title' ), + $compare_to_gravatar, + $compare_to_author, + human_time_diff( strtotime( $left_revision->post_modified ), current_time( 'timestamp' ) ), + $compare_to_date + ); + } + + $gravatar = get_avatar( $revision->post_author, 24 ); $author = get_the_author_meta( 'display_name', $revision->post_author ); $date = date_i18n( $datef, strtotime( $revision->post_modified ) ); $revision_date_author = sprintf( @@ -2213,22 +2240,58 @@ function wp_ajax_revisions_data() { $date ); + $autosavef = __( '%1$s [Autosave]' ); + $currentf = __( '%1$s [Current Revision]' ); + + if ( ! $post = get_post( $post_id)) + exit(); + + if ( $left_revision->post_modified === $post->post_modified ) + $revision_from_date_author = sprintf( $currentf, $revision_from_date_author ); + elseif ( wp_is_post_autosave( $left_revision ) ) + $revision_from_date_author = sprintf( $autosavef, $revision_from_date_author ); + + if ( $revision->post_modified === $post->post_modified ) + $revision_date_author = sprintf( $currentf, $revision_date_author ); + elseif ( wp_is_post_autosave( $revision ) ) + $revision_date_author = sprintf( $autosavef, $revision_date_author ); + + $date_short_format = __( 'j M @ G:i' ); + $date_short = date_i18n( $date_short_format, strtotime( $revision->post_modified ) ); + + $revision_date_author_short = sprintf( + '%s %s
%s', + $gravatar, + $author, + $date_short + ); + $restoreaction = wp_nonce_url( add_query_arg( array( 'revision' => $revision->ID, 'action' => 'restore' ), admin_url( 'revision.php' ) ), - "restore-post_{$compare_to}|{$revision->ID}" + "restore-post_{$revision->ID}" ); - - $alltherevisions[] = array ( + // if this is a left handled calculation swap data + if ( 0 != $right_handle_at ) { + $tmp = $revision_from_date_author; + $revision_from_date_author = $revision_date_author; + $revision_date_author = $tmp; + } + if ( ( $compare_two_mode || 0 !== $previous_revision_id ) ) { + $alltherevisions[] = array ( 'ID' => $revision->ID, 'revision_date_author' => $revision_date_author, 'revision_from_date_author' => $revision_from_date_author, + 'revision_date_author_short' => $revision_date_author_short, 'restoreaction' => urldecode( $restoreaction ), - 'revision_toload' => true + 'revision_toload' => true, + 'previous_revision_id' => $previous_revision_id ); + } + $previous_revision_id = $revision->ID; endforeach; diff --git a/wp-admin/js/revisions.js b/wp-admin/js/revisions.js index 882500f05e..da109d3275 100644 --- a/wp-admin/js/revisions.js +++ b/wp-admin/js/revisions.js @@ -7,19 +7,33 @@ window.wp = window.wp || {}; Model : Backbone.Model.extend({ idAttribute : 'ID', - urlRoot : ajaxurl + '?action=revisions-data&compare_to=' + wpRevisionsSettings.post_id + - '&show_autosaves=false&show_split_view=true&nonce=' + wpRevisionsSettings.nonce, + urlRoot : ajaxurl + '?action=revisions-data' + + '&show_autosaves=true&show_split_view=true&nonce=' + wpRevisionsSettings.nonce, defaults: { ID : 0, revision_date_author : '', + revision_date_author_short: '', revisiondiff : '
', restoreaction : '', revision_from_date_author : '', - revision_toload : false + revision_toload : false, + lines_added : 0, + lines_deleted : 0, + scope_of_changes : 'none', + previous_revision_id : 0 }, url : function() { - return this.urlRoot + '&single_revision_id=' + this.id; + if ( 1 === REVAPP._compareoneortwo ) { + return this.urlRoot + + '&single_revision_id=' + this.id + + '&compare_to=' + this.get( 'previous_revision_id' ) + + '&post_id=' + wpRevisionsSettings.post_id; + } else { + return this.urlRoot + + '&single_revision_id=' + this.id; + } + } }), @@ -33,45 +47,71 @@ window.wp = window.wp || {}; _right_handle_revisions : null, _revisionsInteractions : null, _revisionsOptions : null, - _left_diff : 0, + _left_diff : 1, _right_diff : 1, - _autosaves : false, + _autosaves : true, _show_split_view : true, _compareoneortwo : 1, _left_model_loading : false, //keep track of model loads _right_model_loading : false, //disallow slider interaction, also repeat loads, while loading + _tickmarkView : null, //the slider tickmarks + _has_tooltip : false, - //TODO add ability to arrive on specific revision routes : { }, - viewrevision : function( revision ) { - //coming soon - }, - reload_toload_revisions : function( model_collection, reverse_direction ) { var self = this; var revisions_to_load = model_collection.where( { revision_toload : true } ); - //console.log(revisions_to_load); var delay=0; - _.each(revisions_to_load, function( the_model ) { + //match slider to passed revision_id + _.each( revisions_to_load, function( the_model ) { + if ( the_model.get( 'ID' ) == wpRevisionsSettings.revision_id ) { + self._right_diff = self._revisions.indexOf( the_model ) + 1; + } + + }); + _.each( revisions_to_load, function( the_model ) { the_model.urlRoot = model_collection.url; _.delay( function() { the_model.fetch( { update : true, add : false, remove : false, - //async : false, success : function( model ) { - //console.log(model.get( 'ID' ) +'-'+self._revisions.at( self._right_diff ).get( 'ID' )); - if ( model.get( 'ID' ) === self._revisions.at( self._right_diff - 1 ).get( 'ID' ) ) { //reload if current model refreshed - //console.log('render'); + model.set( 'revision_toload', 'false' ); + + //stop spinner when all models are loaded + if ( 0 === model_collection.where( { revision_toload : true } ).length ) + self.stop_model_loading_spinner(); + + self._tickmarkView.render(); + + var total_changes = model.get( 'lines_added' ) + model.get( 'lines_deleted'); + var scope_of_changes = 'vsmall'; + + // Note: hard coded scope of changes + // TODO change to dynamic based on range of values + if ( total_changes > 1 && total_changes <= 3 ) { + scope_of_changes = 'small'; + } else if(total_changes > 3 && total_changes <= 5 ) { + scope_of_changes = 'med'; + } else if(total_changes > 5 && total_changes <= 10 ) { + scope_of_changes = 'large'; + } else if(total_changes > 10 ) { + scope_of_changes = 'vlarge'; + } + model.set( 'scope_of_changes', scope_of_changes ); + if ( 0 !== self._right_diff && + model.get( 'ID' ) === self._revisions.at( self._right_diff - 1 ).get( 'ID' ) ) { + //reload if current model refreshed self._revisionView.render(); } + } } ); }, delay ) ; - delay = delay + 200; //stagger model loads by 200 ms to avoid hammering server with requests + delay = delay + 150; //stagger model loads to avoid hammering server with requests } ); }, @@ -83,7 +123,6 @@ window.wp = window.wp || {}; stop_left_model_loading : function() { this._left_model_loading = false; - $('.revisiondiffcontainer').removeClass('leftmodelloading'); }, start_right_model_loading : function() { @@ -93,7 +132,11 @@ window.wp = window.wp || {}; stop_right_model_loading : function() { this._right_model_loading = false; + }, + + stop_model_loading_spinner : function() { $('.revisiondiffcontainer').removeClass('rightmodelloading'); + $('.revisiondiffcontainer').removeClass('leftmodelloading'); }, reloadmodel : function() { @@ -104,44 +147,49 @@ window.wp = window.wp || {}; } }, + //load the models for the single handle mode reloadmodelsingle : function() { var self = this; self._revisions.url = ajaxurl + '?action=revisions-data&compare_to=' + wpRevisionsSettings.post_id + '&show_autosaves=' + self._autosaves + - '&show_split_view=' + REVAPP._show_split_view + + '&show_split_view=' + self._show_split_view + '&nonce=' + wpRevisionsSettings.nonce; self.start_right_model_loading(); - this._revisions.fetch({ //reload revision data + self._revisions.fetch({ //reload revision data success : function() { - self.stop_right_model_loading(); + console.log('loaded'); + //self.stop_right_model_loading(); + //REVAPP._right_diff -= 1; var revisioncount = self._revisions.length; - if ( self._right_diff > revisioncount ) //if right handle past rightmost, move - self._right_diff = revisioncount; - + self._revisionView.model = self._revisions; self._revisionView.render(); self.reload_toload_revisions( self._revisions ); + self._tickmarkView.model = self._revisions; + self._tickmarkView.render(); + $( '#slider' ).slider( 'option', 'max', revisioncount-1 ); //TODO test this, if autsave option changed + $( '#slider' ).slider( 'value', self._right_diff - 1 ).trigger( 'slide' ); - $( '#slider' ).slider( 'option', 'max', revisioncount-1 ); //TODO test this, autsaves changed }, error : function () { self.stop_right_model_loading(); - //console.log( 'Error loading revision data' ); } }); }, + //load the models for the left handle reloadleft : function() { var self = this; self.start_left_model_loading(); self._left_handle_revisions = new wp.revisions.Collection(); + self._left_handle_revisions.url = ajaxurl + '?action=revisions-data&compare_to=' + self._revisions.at( self._right_diff - 1 ).get( 'ID' ) + '&post_id=' + wpRevisionsSettings.post_id + - '&show_autosaves=' + self._autosaves + - '&show_split_view=' + self._show_split_view + + '&show_autosaves=' + REVAPP._autosaves + + '&show_split_view=' + REVAPP._show_split_view + '&nonce=' + wpRevisionsSettings.nonce + '&right_handle_at=' + ( self._right_diff ); @@ -150,47 +198,48 @@ window.wp = window.wp || {}; success : function(){ self.stop_left_model_loading(); self.reload_toload_revisions( self._left_handle_revisions ); - }, + self._tickmarkView.model = self._left_handle_revisions; + $( '#slider' ).slider( 'option', 'max', self._revisions.length ); + // ensure right handle not beyond length, in particular if viewing autosaves is switched from on to off + // the number of models in the collection might get shorter, this ensures right handle is not beyond last model + if ( self._right_diff > self._revisions.length ) + self._right_diff = self._revisions.length; + }, error : function () { - //console.log( 'Error loading revision data' ); self.stop_left_model_loading(); } }); }, + //load the models for the right handle reloadright : function() { var self = this; self.start_right_model_loading(); self._right_handle_revisions = new wp.revisions.Collection(); - if ( 0 === self._left_diff ) { + self._right_handle_revisions.url = ajaxurl + - '?action=revisions-data&compare_to=' + wpRevisionsSettings.post_id + + '?action=revisions-data&compare_to=' + ( self._revisions.at( self._left_diff ).get( 'ID' ) -1)+ '&post_id=' + wpRevisionsSettings.post_id + - '&show_autosaves=' + self._autosaves + - '&show_split_view=' + self._show_split_view + + '&show_autosaves=' + REVAPP._autosaves + + '&show_split_view=' + REVAPP._show_split_view + '&nonce=' + wpRevisionsSettings.nonce; - } else { - self._right_handle_revisions.url = - ajaxurl + - '?action=revisions-data&compare_to=' + self._revisions.at( self._left_diff - 1 ).get( 'ID' ) + - '&post_id=' + wpRevisionsSettings.post_id + - '&show_autosaves=' + self._autosaves + - '&show_split_view=' + self._show_split_view + - '&nonce=' + wpRevisionsSettings.nonce + - '&left_handle_at=' + (self._left_diff ) ; - } self._right_handle_revisions.fetch({ success : function(){ self.stop_right_model_loading(); self.reload_toload_revisions( self._right_handle_revisions ); + self._tickmarkView.model = self._right_handle_revisions; + $( '#slider' ).slider( 'option', 'max', self._revisions.length ); + $( '#slider' ).slider( 'values', [ REVAPP._left_diff, REVAPP._right_diff] ).trigger( 'slide' ); + + //REVAPP._revisionView.render(); + }, error : function ( response ) { - //console.log( 'Error loading revision data - ' + response.toSource() ); self.stop_right_model_loading(); } }); @@ -198,6 +247,8 @@ window.wp = window.wp || {}; }, reloadleftright : function() { + this.start_right_model_loading(); + this.start_left_model_loading(); this.reloadleft(); this.reloadright(); }, @@ -208,35 +259,79 @@ window.wp = window.wp || {}; 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(); + //self._right_handle_revisions = self._revisions; + self.completeApplicationSetup(); } }); } return this; }, - revisionDiffSetup : function() { + addTooltip : function( handle, message ) { + + handle.attr( 'title', '' ).tooltip({ + track: false, + + position: { + my: "left-30 top-66", + at: "top left", + using: function( position, feedback ) { + $( this ).css( position ); + $( "
" ) + .addClass( "arrow" ) + .addClass( feedback.vertical ) + .addClass( feedback.horizontal ) + .appendTo( $( this ) ); + } + }, + show: false, + hide: false, + content: function() { + return message; + } + + } ); + }, +/**/ + + completeApplicationSetup : function() { this._revisionView = new wp.revisions.views.View({ model : this._revisions }); this._revisionView.render(); - $( '#diff_max, #diff_maxof' ).html( this._revisions.length ); - $( '#diff_count' ).html( REVAPP._right_diff ); $( '#slider' ).slider( 'option', 'max', this._revisions.length - 1 ); this.reload_toload_revisions( this._revisions ); + this._revisionsInteractions = new wp.revisions.views.Interact({ model : this._revisions }); this._revisionsInteractions.render(); + this._tickmarkView = new wp.revisions.views.Tickmarks({ + model : this._revisions + }); + this._tickmarkView.render(); + this._tickmarkView.resetticks(); + + + /* + .on( 'mouseup', function( event ) { + REVAPP._keep_tooltip_open = false; + $( this ).find('.ui-slider-tooltip').hide(); + } ).on( 'mousedown', function( event ) { + REVAPP._keep_tooltip_open = true; + } ).on( 'mouseout', function( event ) { + if ( REVAPP._keep_tooltip_open) + event.stopImmediatePropagation(); + }); + */ /* //Options hidden for now, moving to screen options this._revisionsOptions = new wp.revisions.views.Options({ @@ -252,13 +347,74 @@ window.wp = window.wp || {}; wp.revisions.Collection = Backbone.Collection.extend({ model : wp.revisions.Model, url : ajaxurl + '?action=revisions-data&compare_to=' + wpRevisionsSettings.post_id + - '&show_autosaves=false&show_split_view=true&nonce=' + wpRevisionsSettings.nonce, + '&show_autosaves=true&show_split_view=true&nonce=' + wpRevisionsSettings.nonce, initialize : function() { } } ); _.extend(wp.revisions.views, { + + //Ticks inside slider view + // + Tickmarks : Backbone.View.extend({ + el : $('#diff-slider-ticks')[0], + tagName : 'diff-slider-ticks-view', + className : 'diff-slider-ticks-container', + template : wp.template('revision-ticks'), + model : wp.revisions.Model, + + resetticks : function() { + var slider_max = $( '#slider' ).slider( 'option', 'max'); + var slider_width = $( '#slider' ).width(); + var adjust_max = ( 2 === REVAPP._compareoneortwo ) ? 1 : 0; + var tick_width = Math.floor( slider_width / ( slider_max - adjust_max ) ); + + //TODO: adjust right margins for wider ticks so they stay centered on handle stop point + + //set minimum and maximum widths for tick marks + tick_width = (tick_width > 50 ) ? 50 : tick_width; + tick_width = (tick_width < 10 ) ? 10 : tick_width; + + slider_width = tick_width * (slider_max - adjust_max ) +1; + + $( '#slider' ).width( slider_width ); + $( '.diff-slider-ticks-wrapper' ).width( slider_width ); + $( '#diffslider' ).width( slider_width ); + $( '#diff-slider-ticks' ).width( slider_width ); + + var a_tick_width = $( '.revision-tick' ).width(); + + if ( tick_width !== a_tick_width ) { // is the width already set correctly? + $( '.revision-tick' ).each( function( ) { + $(this).css( 'margin-right', tick_width - 1 + 'px'); //space the ticks out using right margin + }); + + if( 2 === REVAPP._compareoneortwo ) { + $( '.revision-tick' ).first().remove(); //TODO - remove the check + } + $( '.revision-tick' ).last().css( 'margin-right', '0' ); // last tick gets no right margin + } + + }, + + //render the tickmark view + render : function() { + var self = this; + + if ( null !== self.model ) { + var addhtml = ""; + _.each ( self.model.models, function ( the_model ) { + addhtml = addhtml + self.template ( the_model.toJSON() ); + }); + self.$el.html( addhtml ); + + } + self.resetticks(); + return self; + } + }), + // //primary revision diff view // @@ -267,19 +423,16 @@ window.wp = window.wp || {}; 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 ) { @@ -310,9 +463,34 @@ window.wp = window.wp || {}; this.$el.html( addhtml ); if ( this.model.length < 3 ) { $( 'div#comparetworevisions' ).hide(); //don't allow compare two if fewer than three revisions - } - //console.log ( (this.model.at( REVAPP._right_diff - 1 )).url()); + if ( this.model.length < 2 ) { + $( 'div#diffslider' ).hide(); //don't allow compare two if fewer than three revisions + $( 'div.diff-slider-ticks-wrapper' ).hide(); + } + + // + // add tooltips to the handles + // + if ( 2 === REVAPP._compareoneortwo ) { + REVAPP.addTooltip ( $( 'a.ui-slider-handle.left-handle' ), + ( REVAPP._right_diff >= REVAPP._revisions.length ) ? '' : REVAPP._revisions.at( REVAPP._left_diff ).get( 'revision_date_author_short' ) ); + REVAPP.addTooltip ( $( 'a.ui-slider-handle.right-handle' ), + ( REVAPP._right_diff >= REVAPP._revisions.length ) ? '' : REVAPP._revisions.at( REVAPP._right_diff ).get( 'revision_date_author_short' ) ); + } else { + REVAPP.addTooltip ( $( 'a.ui-slider-handle' ), + ( REVAPP._right_diff >= REVAPP._revisions.length ) ? '' : REVAPP._revisions.at( REVAPP._right_diff ).get( 'revision_date_author_short' ) ); + } + + // + // hide the restore button when on the last sport/current post data + // + if ( REVAPP._right_diff === REVAPP._revisions.length ){ + $( '.restore-button' ).hide(); + } else { + $( '.restore-button' ).show(); + } + return this; }, @@ -326,31 +504,42 @@ window.wp = window.wp || {}; // clickcomparetwo : function(){ self = this; - if ( $( 'input#comparetwo' ).is( ':checked' ) ) { + + if ( $( 'input#comparetwo' ).is( ':checked' ) ) { //compare 2 mode REVAPP._compareoneortwo = 2 ; - REVAPP.reloadleftright(); - } else { - REVAPP._compareoneortwo = 1 ; - REVAPP._revisionView.draggingleft = false; - REVAPP._left_diff = 0; - REVAPP.reloadmodelsingle(); - } - REVAPP._revisionsInteractions.render(); + + if ( 1 === REVAPP._right_diff ) + REVAPP._right_diff = 2; + REVAPP._revisionView.draggingleft = false; + + wpRevisionsSettings.revision_id = ''; // reset passed revision id so switching back to one handle mode doesn't re-select revision + REVAPP.reloadleftright(); + REVAPP._revisionView.model = REVAPP._right_handle_revisions; + + } else { //compare one mode + REVAPP._compareoneortwo = 1 ; + REVAPP._revisionView.draggingleft = false; + //REVAPP._left_diff = 0; + //REVAPP._right_diff = (REVAPP._revisions.length <= REVAPP._right_diff ) ? REVAPP._right_diff + 1 : REVAPP._right_diff + 1; + REVAPP.reloadmodelsingle(); + } + //REVAPP._revisionView.render(); + REVAPP._revisionsInteractions.render(); + REVAPP._tickmarkView.render(); + } }), // //options view for show autosaves and show split view options // + /* DISABLED for now 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; @@ -396,7 +585,7 @@ window.wp = window.wp || {}; REVAPP.reloadmodel(); } }), - + */ // //main interactions view // @@ -405,14 +594,8 @@ window.wp = window.wp || {}; tagName : 'revisionvinteract', className : 'revisionvinteract-container', template : wp.template('revisionvinteract'), - _restoreword : '', initialize : function() { - this._restoreword = $( 'input#restore' ).attr( 'value' ); - }, - - reset_restore_button : function() { - $( 'input#restore' ).attr( 'value', this._restoreword + ' ' + REVAPP._revisions.at( REVAPP._right_diff - 1 ).get( 'ID' ) ); }, render : function() { @@ -420,10 +603,6 @@ window.wp = window.wp || {}; 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 ); - self.reset_restore_button(); var modelcount = REVAPP._revisions.length; @@ -431,23 +610,37 @@ window.wp = window.wp || {}; 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, + 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._right_diff = ( ui.value + 1 ); REVAPP._revisionView.render(); - self.reset_restore_button(); - } + /* + $( 'a.ui-slider-handle' ).tooltip( { + content: REVAPP._revisions.at( ui.value ).get( 'revision_date_author_short' ), + position: { + my: "top-65", + using: function( position, feedback ) { + $( this ).css( position ); + $( "
" ) + .addClass( "arrow" ) + .addClass( feedback.vertical ) + .addClass( feedback.horizontal ) + .appendTo( this ); + } + } + });//.trigger( 'close' ).trigger( 'open' ); +*/ + } }); $( '.revisiondiffcontainer' ).removeClass( 'comparetwo' ); + } else { //comparing more than one, eg 2 //set up the slider with two handles slider.slider({ @@ -460,28 +653,33 @@ window.wp = window.wp || {}; //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 + if ( REVAPP._left_model_loading ) //left model still 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; + + if ( REVAPP._revisionView.model !== REVAPP._left_handle_revisions && + null !== REVAPP._left_handle_revisions ) { + REVAPP._revisionView.model = REVAPP._left_handle_revisions; + REVAPP._tickmarkView.model = REVAPP._left_handle_revisions; + REVAPP._tickmarkView.render(); + } + REVAPP._left_diff_start = ui.values[ 0 ]; break; case 2: //right - if ( REVAPP._right_model_loading ) //right model stoll loading, prevent sliding right handle + if ( REVAPP._right_model_loading || 0 === REVAPP._right_handle_revisions.length) //right model still 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 ) + null !== REVAPP._right_handle_revisions ) { REVAPP._revisionView.model = REVAPP._right_handle_revisions; + REVAPP._tickmarkView.model = REVAPP._right_handle_revisions; + REVAPP._tickmarkView.render(); + } REVAPP._revisionView.draggingleft = false; REVAPP._right_diff_start = ui.values[ 1 ]; @@ -501,29 +699,26 @@ window.wp = window.wp || {}; if ( REVAPP._left_model_loading ) //left model still loading, prevent sliding left handle return false; - REVAPP._left_diff = ui.values[ 0 ] - 1; //one extra spot at left end when comparing two + REVAPP._left_diff = ui.values[ 0 ]; break; case 2: //right if ( REVAPP._right_model_loading ) //right model still loading, prevent sliding right handle return false; - REVAPP._right_diff = ui.values[ 1 ] - 1 ; + REVAPP._right_diff = ui.values[ 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 - self.reset_restore_button(); + REVAPP._revisionView.render(); + }, //when the user stops sliding in 2 handle mode, recalculate diffs @@ -536,23 +731,26 @@ window.wp = window.wp || {}; switch ( index ) { case 1: //left + //left handle dragged & changed, reload right handle model - if ( ! ( REVAPP._left_diff_start === ui.values[ 0 ] || REVAPP._left_model_loading ) ) + if ( REVAPP._left_diff_start !== ui.values[ 0 ] ) REVAPP.reloadright(); break; case 2: //right + //REVAPP._right_diff = ( 1 >= REVAPP._right_diff ) ? 1 : REVAPP._right_diff-1; //right handle dragged & changed, reload left handle model if changed - if ( ! ( REVAPP._right_diff_start === ui.values[ 1 ] || REVAPP._right_model_loading ) ) { + if ( REVAPP._right_diff_start !== ui.values[ 1 ] ) REVAPP.reloadleft(); - } + break; } } } }); $( '.revisiondiffcontainer' ).addClass( 'comparetwo' ); + $( '#diffslider a.ui-slider-handle' ).first().addClass( 'left-handle' ).next().addClass( 'right-handle' ); } return this; @@ -571,9 +769,7 @@ window.wp = window.wp || {}; REVAPP._revisionView.render(); - $( '#diff_count' ).html( REVAPP._right_diff ); $( '#slider' ).slider( 'value', REVAPP._right_diff - 1 ).trigger( 'slide' ); - this.reset_restore_button(); }, //go the the previous revision @@ -583,16 +779,12 @@ window.wp = window.wp || {}; REVAPP._revisionView.render(); - $( '#diff_count' ).html( REVAPP._right_diff ); $( '#slider' ).slider( 'value', REVAPP._right_diff - 1 ).trigger( 'slide' ); - this.reset_restore_button(); } }) }); //instantiate Revision Application REVAPP = new wp.revisions.App(); - //TODO consider enable back button to step back thru states? - //Backbone.history.start({pushState: true}); }(jQuery)); diff --git a/wp-admin/revision.php b/wp-admin/revision.php index bf8f6dfe42..385d4ef79e 100644 --- a/wp-admin/revision.php +++ b/wp-admin/revision.php @@ -17,25 +17,21 @@ switch ( $action ) : case 'restore' : if ( ! $revision = wp_get_post_revision( $revision_id ) ) break; + if ( ! current_user_can( 'edit_post', $revision->post_parent ) ) break; + + if ( ! $post = get_post( $revision->post_parent ) ) break; - // Revisions disabled and we're not looking at an autosave - if ( ( ! WP_POST_REVISIONS || ! post_type_supports( $post->post_type, 'revisions' ) ) && ! wp_is_post_autosave( $revision ) ) { + // Revisions disabled (previously checked autosavegs && ! wp_is_post_autosave( $revision )) + if ( ( ! WP_POST_REVISIONS || ! post_type_supports( $post->post_type, 'revisions' ) ) ) { $redirect = 'edit.php?post_type=' . $post->post_type; break; } - check_admin_referer( "restore-post_{$post->ID}|{$revision->ID}" ); - //store revision event in post meta - $restore_details = array( - 'restored_revision_id' => $revision->ID, - 'restored_by_user' => get_current_user_id(), - 'restored_time' => time() - ); - update_post_meta( $post->ID, '_post_restored_from', $restore_details ); + check_admin_referer( "restore-post_{$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' ) ); @@ -58,7 +54,6 @@ default : } $post_title = '' . get_the_title() . ''; - $revision_title = wp_post_revision_title( $revision, false ); $h2 = sprintf( __( 'Compare Revisions of “%1$s”' ), $post_title ); $title = __( 'Revisions' ); @@ -80,41 +75,66 @@ if ( ! empty( $post->post_type ) && 'post' != $post->post_type ) $parent_file = $submenu_file = 'edit.php?post_type=' . $post->post_type; else $parent_file = $submenu_file = 'edit.php'; - 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 -?> - -ID ); +$wpRevisionsSettings = array( 'post_id' => $post->ID, + 'nonce' => wp_create_nonce( 'revisions-ajax-nonce' ), + 'revision_id' => $revision_id ); +wp_localize_script( 'revisions', 'wpRevisionsSettings', $wpRevisionsSettings ); + +$comparetworevisionslink = get_edit_post_link( $revision->ID ); ?> -
+
+
-

+
+
+
-
+
+ +

-
-
+
+
+
+
+
+
+
+

+ '', 'title_left' => '', 'title_right' => '' ); + $args = wp_parse_args( $args, $defaults ); + + if ( !class_exists( 'WP_Text_Diff_Renderer_Table' ) ) + require( ABSPATH . WPINC . '/wp-diff.php' ); + + $left_string = normalize_whitespace( $left_string ); + $right_string = normalize_whitespace( $right_string ); + + $left_lines = explode( "\n", $left_string ); + $right_lines = explode( "\n", $right_string) ; + + $text_diff = new Text_Diff($left_lines, $right_lines ); + $linesadded = $text_diff->countAddedLines(); + $linesdeleted = $text_diff->countDeletedLines(); + + $renderer = new WP_Text_Diff_Renderer_Table(); + $diff = $renderer->render( $text_diff ); + + if ( !$diff ) + return ''; + + $r = "\n"; + + if ( ! empty( $args[ 'show_split_view' ] ) ) { + $r .= ""; + } else { + $r .= ""; + } + + if ( $args['title'] || $args['title_left'] || $args['title_right'] ) + $r .= ""; + if ( $args['title'] ) + $r .= "\n"; + if ( $args['title_left'] || $args['title_right'] ) { + $r .= "\n"; + $r .= "\t\n"; + $r .= "\t\n"; + $r .= "\n"; + } + if ( $args['title'] || $args['title_left'] || $args['title_right'] ) + $r .= "\n"; + + $r .= "\n$diff\n\n"; + $r .= "
$args[title]
$args[title_left]$args[title_right]
"; + + return array( 'html' => $r, 'linesadded' => $linesadded, 'linesdeleted' => $linesdeleted ); + } + endif; diff --git a/wp-includes/post-template.php b/wp-includes/post-template.php index 5d130fe208..9df1de9ffd 100644 --- a/wp-includes/post-template.php +++ b/wp-includes/post-template.php @@ -1306,11 +1306,50 @@ function wp_post_revision_title( $revision, $link = true ) { if ( !in_array( $revision->post_type, array( 'post', 'page', 'revision' ) ) ) return false; + /* 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]' ); + + $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"; + + if ( !wp_is_post_revision( $revision ) ) + $date = sprintf( $currentf, $date ); + elseif ( wp_is_post_autosave( $revision ) ) + $date = sprintf( $autosavef, $date ); + + return $date; +} + +/** + * Retrieve formatted date timestamp of a revision (linked to that revisions's page). + * + * @package WordPress + * @subpackage Post_Revisions + * @since 3.6.0 + * + * @uses date_i18n() + * + * @param int|object $revision Revision ID or revision object. + * @param bool $link Optional, default is true. Link to revisions's page? + * @return string gravatar, user, i18n formatted datetimestamp or localized 'Current Revision'. + */ +function wp_post_revision_title_expanded( $revision, $link = true ) { + if ( !$revision = get_post( $revision ) ) + return $revision; + + 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:s', 'revision date format'); - $gravatar = get_avatar( $revision->post_author, 18 ); + $gravatar = get_avatar( $revision->post_author, 24 ); $date = date_i18n( $datef, strtotime( $revision->post_modified ) ); if ( $link && current_user_can( 'edit_post', $revision->ID ) && $link = get_edit_post_link( $revision->ID ) ) @@ -1388,11 +1427,18 @@ function wp_list_post_revisions( $post_id = 0, $args = null ) { } /* translators: post revision: 1: when, 2: author name */ - $titlef = _x( '%1$s by %2$s', 'post revision' ); + $titlef = _x( '%1$s', 'post revision' ); if ( $parent ) array_unshift( $revisions, $post ); + // since 3.6 revisions include a copy of the current post data as a revision + // the collowing removes this current revision if present from the list of + // revisions returned by wp_list_post_revisions, remove these to include the + // crrent post revision in the list of revisions + if ( wp_first_revision_matches_current_version( $post_id ) ) + array_pop( $revisions ); + $rows = $right_checked = ''; $class = false; $can_edit_post = current_user_can( 'edit_post', $post->ID ); @@ -1402,34 +1448,11 @@ function wp_list_post_revisions( $post_id = 0, $args = null ) { if ( 'revision' === $type && wp_is_post_autosave( $revision ) ) continue; - $date = wp_post_revision_title( $revision ); - $name = get_the_author_meta( 'display_name', $revision->post_author ); + $date = wp_post_revision_title_expanded( $revision ); - if ( 'form-table' == $format ) { - if ( $left ) - $left_checked = $left == $revision->ID ? ' checked="checked"' : ''; - else - $left_checked = $right_checked ? ' checked="checked"' : ''; // [sic] (the next one) - $right_checked = $right == $revision->ID ? ' checked="checked"' : ''; + $title = sprintf( $titlef, $date ); + $rows .= "\t
  • $title
  • \n"; - $class = $class ? '' : " class='alternate'"; - - if ( $post->ID != $revision->ID && $can_edit_post ) - $actions = 'ID|$revision->ID" ) . '">' . __( 'Restore' ) . ''; - else - $actions = ''; - - $rows .= "\n"; - $rows .= "\t\n"; - $rows .= "\t\n"; - $rows .= "\t$date\n"; - $rows .= "\t$name\n"; - $rows .= "\t$actions\n"; - $rows .= "\n"; - } else { - $title = sprintf( $titlef, $date, $name ); - $rows .= "\t
  • $title
  • \n"; - } } if ( 'form-table' == $format ) : ?> @@ -1479,27 +1502,27 @@ function wp_list_post_revisions( $post_id = 0, $args = null ) { // if the post was previously restored from a revision // show the restore event details // - if ( $restored_from_meta = get_post_meta( $post->ID, '_post_restored_from', true ) ) { - $author = get_the_author_meta( 'display_name', $restored_from_meta[ 'restored_by_user' ] ); - /* translators: revision date format, see http://php.net/date */ - $datef = _x( 'j F, Y @ G:i:s', 'revision date format'); - $date = date_i18n( $datef, strtotime( $restored_from_meta[ 'restored_time' ] ) ); - $timesince = human_time_diff( $restored_from_meta[ 'restored_time' ], current_time( 'timestamp' ) ); - ?> + if ( $restored_from_meta = get_post_meta( $post->ID, '_post_restored_from', true ) ) { + $author = get_the_author_meta( 'display_name', $restored_from_meta[ 'restored_by_user' ] ); + /* translators: revision date format, see http://php.net/date */ + $datef = _x( 'j F, Y @ G:i:s', 'revision date format'); + $date = date_i18n( $datef, strtotime( $restored_from_meta[ 'restored_time' ] ) ); + $timesince = human_time_diff( $restored_from_meta[ 'restored_time' ], current_time( 'timestamp' ) ) ; + ?>
    -
    - + -
    - +
    + "; - } + } endif; diff --git a/wp-includes/revision.php b/wp-includes/revision.php index 7b0cbb5bf8..2b09d59b63 100644 --- a/wp-includes/revision.php +++ b/wp-includes/revision.php @@ -404,3 +404,29 @@ function _show_post_preview() { add_filter('the_preview', '_set_preview'); } } + +/** + * Determines if the specified post's most recent revision matches the post (by checking post_modified). + * + * @package WordPress + * @subpackage Post_Revisions + * @since 3.6.0 + * + * @param int|object $post Post ID or post object. + * @return bool false if not a match, otherwise true. + */ +function wp_first_revision_matches_current_version( $post ) { + + if ( ! $post = get_post( $post ) ) + return false; + + if ( ! $revisions = wp_get_post_revisions( $post->ID ) ) + return false; + + $last_revision = array_shift( $revisions ); + + if ( ! ($last_revision->post_modified == $post->post_modified ) ) + return false; + + return true; +} diff --git a/wp-includes/script-loader.php b/wp-includes/script-loader.php index 7942b60147..ece253ddd5 100644 --- a/wp-includes/script-loader.php +++ b/wp-includes/script-loader.php @@ -273,7 +273,7 @@ function wp_default_scripts( &$scripts ) { $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.10', 1 ); - $scripts->add( 'revisions', "/wp-admin/js/revisions$suffix.js", array( 'backbone', 'jquery-ui-slider' ), false, 1 ); + $scripts->add( 'revisions', "/wp-admin/js/revisions$suffix.js", array( 'backbone', 'jquery-ui-slider', 'jquery-ui-tooltip' ), false, 1 ); $scripts->add( 'imgareaselect', "/wp-includes/js/imgareaselect/jquery.imgareaselect$suffix.js", array('jquery'), '0.9.8', 1 );