Changeset 23898
- Timestamp:
- 04/04/2013 07:53:49 AM (12 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/wp-admin/includes/ajax-actions.php
r23890 r23898 2093 2093 check_ajax_referer( 'revisions-ajax-nonce', 'nonce' ); 2094 2094 2095 $compare_to = isset( $_GET['compare_to'] ) ? absint( $_GET['compare_to'] ) : 0;2096 $show_autosaves = isset( $_GET['show_autosaves'] ) ? $_GET['show_autosaves'] : '';2097 $show_split_view = isset( $_GET['show_split_view'] ) ? $_GET['show_split_view'] : '';2098 $post_id = isset( $_GET['post_id'] ) ? absint( $_GET['post_id'] ) : '';2099 $right_handle_at = isset( $_GET['right_handle_at'] ) ?$_GET['right_handle_at'] : 0;2100 $left_handle_at = isset( $_GET['left_handle_at'] ) ?$_GET['left_handle_at'] : 0;2101 $single_revision_id = isset( $_GET['single_revision_id'] ) ? $_GET['single_revision_id']: 0;2102 2103 $compare_two_mode = ( '' == $post_id ) ? false : true; 2095 $compare_to = ! empty( $_GET['compare_to'] ) ? absint( $_GET['compare_to'] ) : 0; 2096 $show_autosaves = ! empty( $_GET['show_autosaves'] ); 2097 $show_split_view = ! empty( $_GET['show_split_view'] ); 2098 $post_id = ! empty( $_GET['post_id'] ) ? absint( $_GET['post_id'] ) : 0; 2099 $right_handle_at = ! empty( $_GET['right_handle_at'] ) ? (int) $_GET['right_handle_at'] : 0; 2100 $left_handle_at = ! empty( $_GET['left_handle_at'] ) ? (int) $_GET['left_handle_at'] : 0; 2101 $single_revision_id = ! empty( $_GET['single_revision_id'] ) ? absint( $_GET['single_revision_id'] ) : 0; 2102 $compare_two_mode = (bool) $post_id; 2103 2104 2104 // 2105 2105 //TODO: currently code returns all possible comparisons for the indicated 'compare_to' revision … … 2107 2107 //so only the possible diffs need be generated 2108 2108 // 2109 $all therevisions = array();2110 if ( '' ==$post_id )2109 $all_the_revisions = array(); 2110 if ( ! $post_id ) 2111 2111 $post_id = $compare_to; 2112 2112 … … 2117 2117 return; 2118 2118 2119 /* translators: revision date format, see http://php.net/date */2120 $datef = _x( 'j F, Y @ G:i:s', 'revision date format');2121 2122 2119 $left_revision = get_post( $compare_to ); 2123 2120 2124 2121 //single model fetch mode 2125 2122 //return the diff of a single revision comparison 2126 if ( 0 !=$single_revision_id ) {2123 if ( $single_revision_id ) { 2127 2124 $right_revision = get_post( $single_revision_id ); 2128 2125 2129 if ( 0 ==$compare_to )2126 if ( ! $compare_to ) 2130 2127 $left_revision = get_post( $post_id ); 2131 2128 2132 // make sure the right revision is the most recent 2133 if ( $compare_two_mode && $right_revision->ID < $left_revision->ID ) { 2134 $temp = $left_revision; 2135 $left_revision = $right_revision; 2136 $right_revision = $temp; 2137 } 2138 2139 $linesadded=0; 2140 $linesdeleted=0; 2141 2142 // 2129 // make sure the right revision is the most recent 2130 if ( $compare_two_mode && $right_revision->ID < $left_revision->ID ) { 2131 $temp = $left_revision; 2132 $left_revision = $right_revision; 2133 $right_revision = $temp; 2134 } 2135 2136 $lines_added = $lines_deleted = 0; 2137 $content = ''; 2143 2138 //compare from left to right, passed from application 2144 //2145 $content='';2146 2139 foreach ( array_keys( _wp_post_revision_fields() ) as $field ) { 2147 2140 $left_content = apply_filters( "_wp_post_revision_field_$field", $left_revision->$field, $field, $left_revision, 'left' ); … … 2152 2145 $args = array(); 2153 2146 2154 if ( ! empty( $show_split_view ))2147 if ( $show_split_view ) 2155 2148 $args = array( 'show_split_view' => true ); 2156 2149 2157 2150 // compare_to == 0 means first revision, so compare to a blank field to show whats changed 2158 $diff = wp_text_diff_with_count( ( 0 == $compare_to ) ? '' : $left_content, $right_content, $args );2151 $diff = wp_text_diff_with_count( ( 0 == $compare_to ) ? '' : $left_content, $right_content, $args ); 2159 2152 2160 2153 if ( isset( $diff[ 'html' ] ) ) 2161 2154 $content .= $diff[ 'html' ]; 2162 2155 2163 if ( isset( $diff[ 'linesadded' ] ) ) 2164 $linesadded = $linesadded + $diff[ 'linesadded' ]; 2165 2166 if ( isset( $diff[ 'linesdeleted' ] ) ) 2167 $linesdeleted = $linesdeleted + $diff[ 'linesdeleted' ]; 2168 2169 2156 if ( isset( $diff[ 'lines_added' ] ) ) 2157 $lines_added = $lines_added + $diff[ 'lines_added' ]; 2158 2159 if ( isset( $diff[ 'lines_deleted' ] ) ) 2160 $lines_deleted = $lines_deleted + $diff[ 'lines_deleted' ]; 2170 2161 } 2171 2162 $content = '' == $content ? __( 'No difference' ) : $content; 2172 2163 2173 $all therevisions = array (2174 ' revisiondiff'=> $content,2175 'lines_deleted' => $lines deleted,2176 'lines_added' => $linesadded2164 $all_the_revisions = array ( 2165 'diff' => $content, 2166 'lines_deleted' => $lines_deleted, 2167 'lines_added' => $lines_added 2177 2168 ); 2178 echo json_encode( $alltherevisions ); 2169 2170 echo json_encode( $all_the_revisions ); 2179 2171 exit(); 2180 2172 } //end single model fetch … … 2187 2179 $previous_revision_id = 0; 2188 2180 2181 /* translators: revision date format, see http://php.net/date */ 2182 $datef = _x( 'j F, Y @ G:i:s', 'revision date format'); 2183 2189 2184 foreach ( $revisions as $revision ) : 2190 //error_log( ( $show_autosaves )); 2191 if ( empty( $show_autosaves ) && wp_is_post_autosave( $revision ) ) 2192 continue; 2185 if ( ! $show_autosaves && wp_is_post_autosave( $revision ) ) 2186 continue; 2193 2187 2194 2188 $revision_from_date_author = ''; … … 2196 2190 // return blank data for diffs to the left of the left handle (for right handel model) 2197 2191 // or to the right of the right handle (for left handel model) 2198 if ( ( 0 != $left_handle_at && $count < =$left_handle_at ) ||2199 ( 0 != $right_handle_at && $count > $right_handle_at )) {2200 $all therevisions[] = array (2192 if ( ( 0 != $left_handle_at && $count < $left_handle_at ) || 2193 ( 0 != $right_handle_at && $count > ( $right_handle_at - 2 ) ) ) { 2194 $all_the_revisions[] = array ( 2201 2195 'ID' => $revision->ID, 2202 2196 ); … … 2231 2225 ); 2232 2226 2233 $autosavef = _ _( '%1$s [Autosave]' );2234 $currentf = _ _( '%1$s [Current Revision]' );2235 2236 if ( ! $post = get_post( $post_id ))2237 exit();2227 $autosavef = _x( '%1$s [Autosave]', 'post revision title extra' ); 2228 $currentf = _x( '%1$s [Current Revision]', 'post revision title extra' ); 2229 2230 if ( ! $post = get_post( $post_id ) ) 2231 continue; 2238 2232 2239 2233 if ( $left_revision->post_modified === $post->post_modified ) … … 2247 2241 $revision_date_author = sprintf( $autosavef, $revision_date_author ); 2248 2242 2249 $date_short_format = __( 'j M @ G:i' ); 2243 /* translators: revision date short format, see http://php.net/date */ 2244 $date_short_format = _x( 'j M @ G:i', 'revision date short format'); 2250 2245 $date_short = date_i18n( $date_short_format, strtotime( $revision->post_modified ) ); 2251 2246 … … 2257 2252 ); 2258 2253 2259 $restore action= wp_nonce_url(2254 $restore_link = wp_nonce_url( 2260 2255 add_query_arg( 2261 2256 array( 'revision' => $revision->ID, … … 2265 2260 "restore-post_{$revision->ID}" 2266 2261 ); 2262 2267 2263 // if this is a left handled calculation swap data 2268 2264 if ( 0 != $right_handle_at ) { … … 2271 2267 $revision_date_author = $tmp; 2272 2268 } 2269 2273 2270 if ( ( $compare_two_mode || -1 !== $previous_revision_id ) ) { 2274 $all therevisions[] = array (2275 'ID' => $revision->ID,2276 ' revision_date_author'=> $revision_date_author,2277 ' revision_from_date_author'=> $revision_from_date_author,2278 ' revision_date_author_short'=> $revision_date_author_short,2279 'restore action' => urldecode( $restoreaction),2280 'revision_toload' => true,2271 $all_the_revisions[] = array ( 2272 'ID' => $revision->ID, 2273 'titleTo' => $revision_date_author, 2274 'titleFrom' => $revision_from_date_author, 2275 'titleTooltip' => $revision_date_author_short, 2276 'restoreLink' => urldecode( $restore_link ), 2277 'revision_toload' => true, 2281 2278 'previous_revision_id' => $previous_revision_id 2282 2279 ); … … 2286 2283 endforeach; 2287 2284 2288 echo json_encode( $all therevisions );2285 echo json_encode( $all_the_revisions ); 2289 2286 exit(); 2290 2287 } -
trunk/wp-admin/js/revisions.js
r23872 r23898 2 2 3 3 (function($) { 4 wp.revisions = { 5 6 views: {}, 7 8 Model: Backbone.Model.extend({ 9 idAttribute: 'ID', 10 urlRoot: ajaxurl + '?action=revisions-data' + 11 '&show_autosaves=true&show_split_view=true&nonce=' + wpRevisionsSettings.nonce, 12 defaults: { 13 ID: 0, 14 revision_date_author: '', 15 revision_date_author_short: '', 16 revisiondiff: '<div class="diff-loading"><div class="spinner"></div></div>', 17 restoreaction: '', 18 revision_from_date_author: '', 19 revision_toload: false, 20 lines_added: 0, 21 lines_deleted: 0, 22 scope_of_changes: 'none', 23 previous_revision_id: 0 24 }, 25 26 url: function() { 27 if ( 1 === REVAPP._compareOneOrTwo ) { 28 return this.urlRoot + 29 '&single_revision_id=' + this.id + 30 '&compare_to=' + this.get( 'previous_revision_id' ) + 31 '&post_id=' + wpRevisionsSettings.post_id; 32 } else { 33 return this.urlRoot + 34 '&single_revision_id=' + this.id; 35 } 36 37 } 38 39 }), 40 41 app: _.extend({}, Backbone.Events), 42 43 App: Backbone.Router.extend({ 44 _revisions: null, 45 _leftHandleRevisions: null, 46 _rightHandleRevisions: null, 47 _revisionsInteractions: null, 48 _revisionsOptions: null, 49 _leftDiff: 1, 50 _rightDiff: 1, 51 _autosaves: true, 52 _showSplitView: true, 53 _compareOneOrTwo: 1, 54 _leftModelLoading: false, // keep track of model loads 55 _rightModelLoading: false, // disallow slider interaction, also repeat loads, while loading 56 _tickmarkView: null, // the slider tickmarks 57 58 routes: { 59 }, 60 61 reloadToLoadRevisions: function( model_collection, reverse_direction ) { 62 var self = this, 63 revisionsToLoad = model_collection.where( { revision_toload: true } ), 64 delay = 0; 65 // match slider to passed revision_id 66 _.each( revisionsToLoad, function( theModel ) { 67 if ( theModel.get( 'ID' ) == wpRevisionsSettings.revision_id ) { 68 self._rightDiff = self._revisions.indexOf( theModel ) + 1; 69 } 70 71 }); 72 _.each( revisionsToLoad, function( theModel ) { 73 theModel.urlRoot = model_collection.url; 74 _.delay( function() { 75 theModel.fetch( { 76 update: true, 77 add: false, 78 remove: false, 79 success: function( model ) { 80 model.set( 'revision_toload', 'false' ); 81 82 // stop spinner when all models are loaded 83 if ( 0 === model_collection.where( { revision_toload: true } ).length ) 84 self.stopModelLoadingSpinner(); 85 86 self._tickmarkView.render(); 87 88 var total_changes = model.get( 'lines_added' ) + model.get( 'lines_deleted'), 89 scope_of_changes = 'vsmall'; 90 91 // Note: hard coded scope of changes 92 // TODO change to dynamic based on range of values 93 if ( total_changes > 1 && total_changes <= 3 ) { 94 scope_of_changes = 'small'; 95 } else if(total_changes > 3 && total_changes <= 5 ) { 96 scope_of_changes = 'med'; 97 } else if(total_changes > 5 && total_changes <= 10 ) { 98 scope_of_changes = 'large'; 99 } else if(total_changes > 10 ) { 100 scope_of_changes = 'vlarge'; 101 } 102 model.set( 'scope_of_changes', scope_of_changes ); 103 if ( 0 !== self._rightDiff && 104 model.get( 'ID' ) === self._revisions.at( self._rightDiff - 1 ).get( 'ID' ) ) { 105 // reload if current model refreshed 106 self._revisionView.render(); 107 } 108 109 } 110 } ); 111 }, delay ) ; 112 delay = delay + 150; // stagger model loads to avoid hammering server with requests 113 } 114 ); 115 }, 116 117 startLeftModelLoading: function() { 118 this._leftModelLoading = true; 119 $('.revisiondiffcontainer').addClass('leftmodelloading'); 120 }, 121 122 stopLeftModelLoading: function() { 123 this._leftModelLoading = false; 124 }, 125 126 startRightModelLoading: function() { 127 this._rightModelLoading = true; 128 $('.revisiondiffcontainer').addClass('rightmodelloading'); 129 }, 130 131 stopRightModelLoading: function() { 132 this._rightModelLoading = false; 133 }, 134 135 stopModelLoadingSpinner: function() { 136 $('.revisiondiffcontainer').removeClass('rightmodelloading'); 137 $('.revisiondiffcontainer').removeClass('leftmodelloading'); 138 }, 139 140 reloadModel: function() { 141 if ( 2 === this._compareOneOrTwo ) { 142 this.reloadLeftRight(); 143 } else { 144 this.reloadModelSingle(); 145 } 146 }, 147 148 // load the models for the single handle mode 149 reloadModelSingle: function() { 4 var Revision, Revisions, Diff, l10n, revisions; 5 6 revisions = wp.revisions = function() { 7 Diff = revisions.Diff = new Diff(); 8 }; 9 10 _.extend( revisions, { model: {}, view: {}, controller: {} } ); 11 12 // Link any localized strings. 13 l10n = revisions.model.l10n = typeof wpRevisionsL10n === 'undefined' ? {} : wpRevisionsL10n; 14 15 // Link any settings. 16 revisions.model.settings = l10n.settings || {}; 17 delete l10n.settings; 18 19 20 /** 21 * ======================================================================== 22 * CONTROLLERS 23 * ======================================================================== 24 */ 25 26 /** 27 * wp.revisions.controller.Diff 28 * 29 * Controlls the diff 30 */ 31 Diff = revisions.controller.Diff = Backbone.Model.extend( { 32 rightDiff: 1, 33 leftDiff: 1, 34 revisions: null, 35 leftHandleRevisions: null, 36 rightHandleRevisions: null, 37 revisionsInteractions: null, 38 autosaves: true, 39 showSplitView: true, 40 singleRevision: true, 41 leftModelLoading: false, // keep track of model loads 42 rightModelLoading: false, // disallow slider interaction, also repeat loads, while loading 43 tickmarkView: null, // the slider tickmarks 44 slider: null, // the slider instance 45 46 constructor: function() { 47 this.slider = new revisions.view.Slider(); 48 if ( null === this.revisions ) { 49 this.revisions = new Revisions(); // set up collection 50 this.startRightModelLoading(); 51 150 52 var self = this; 151 self._revisions.url = ajaxurl + '?action=revisions-data&compare_to=' + wpRevisionsSettings.post_id + 152 '&show_autosaves=' + self._autosaves + 153 '&show_split_view=' + self._showSplitView + 154 '&nonce=' + wpRevisionsSettings.nonce; 155 self.startRightModelLoading(); 156 self._revisions.fetch({ // reload revision data 53 this.revisions.fetch({ // load revision data 157 54 success: function() { 158 console.log('loaded');159 // self.stopRightModelLoading();160 // REVAPP._rightDiff -= 1;161 var revisionCount = self._revisions.length;162 self._revisionView.model = self._revisions;163 self._revisionView.render();164 self.reloadToLoadRevisions( self._revisions );165 self._tickmarkView.model = self._revisions;166 self._tickmarkView.render();167 $( '#slider' ).slider( 'option', 'max', revisionCount - 1 ); // TODO: test this, if autosave option changed168 $( '#slider' ).slider( 'value', self._rightDiff - 1 ).trigger( 'slide' );169 170 },171 172 error: function() {173 55 self.stopRightModelLoading(); 174 } 175 176 }); 177 }, 178 179 // load the models for the left handle 180 reloadLeft: function() { 181 var self = this; 182 self.startLeftModelLoading(); 183 self._leftHandleRevisions = new wp.revisions.Collection(); 184 185 self._leftHandleRevisions.url = 186 ajaxurl + 187 '?action=revisions-data&compare_to=' + self._revisions.at( self._rightDiff - 1 ).get( 'ID' ) + 188 '&post_id=' + wpRevisionsSettings.post_id + 189 '&show_autosaves=' + REVAPP._autosaves + 190 '&show_split_view=' + REVAPP._showSplitView + 191 '&nonce=' + wpRevisionsSettings.nonce + 192 '&right_handle_at=' + ( self._rightDiff ); 193 194 self._leftHandleRevisions.fetch({ 195 196 success: function(){ 197 self.stopLeftModelLoading(); 198 self.reloadToLoadRevisions( self._leftHandleRevisions ); 199 self._tickmarkView.model = self._leftHandleRevisions; 200 $( '#slider' ).slider( 'option', 'max', self._revisions.length ); 201 // ensure right handle not beyond length, in particular if viewing autosaves is switched from on to off 202 // the number of models in the collection might get shorter, this ensures right handle is not beyond last model 203 if ( self._rightDiff > self._revisions.length ) 204 self._rightDiff = self._revisions.length; 205 }, 206 207 error: function() { 208 self.stopLeftModelLoading(); 56 self.completeApplicationSetup(); 209 57 } 210 58 }); 211 }, 212 213 // load the models for the right handle 214 reloadRight: function() { 215 var self = this; 216 self.startRightModelLoading(); 217 self._rightHandleRevisions = new wp.revisions.Collection(); 218 219 self._rightHandleRevisions.url = 220 ajaxurl + 221 '?action=revisions-data&compare_to=' + ( self._revisions.at( self._leftDiff ).get( 'ID' ) - 1 )+ 222 '&post_id=' + wpRevisionsSettings.post_id + 223 '&show_autosaves=' + REVAPP._autosaves + 224 '&show_split_view=' + REVAPP._showSplitView + 225 '&nonce=' + wpRevisionsSettings.nonce; 226 227 self._rightHandleRevisions.fetch({ 228 229 success: function(){ 230 self.stopRightModelLoading(); 231 self.reloadToLoadRevisions( self._rightHandleRevisions ); 232 self._tickmarkView.model = self._rightHandleRevisions; 233 $( '#slider' ).slider( 'option', 'max', self._revisions.length ); 234 $( '#slider' ).slider( 'values', [ REVAPP._leftDiff, REVAPP._rightDiff] ).trigger( 'slide' ); 235 236 // REVAPP._revisionView.render(); 237 59 } 60 }, 61 62 reloadToLoadRevisions: function( models, reverse_direction ) { 63 var self = this, 64 revisionsToLoad = models.where( { revision_toload: true } ), 65 delay = 0; 66 67 // match slider to passed revision_id 68 _.each( revisionsToLoad, function( revision ) { 69 if ( revision.get( 'ID' ) == revisions.model.settings.revision_id ) 70 self.rightDiff = self.revisions.indexOf( revision ) + 1; 71 }); 72 73 _.each( revisionsToLoad, function( revision ) { 74 _.delay( function() { 75 revision.fetch( { 76 update: true, 77 add: false, 78 remove: false, 79 success: function( model ) { 80 model.set( 'revision_toload', 'false' ); 81 82 // stop spinner when all models are loaded 83 if ( 0 === models.where( { revision_toload: true } ).length ) 84 self.stopModelLoadingSpinner(); 85 86 self.tickmarkView.render(); 87 88 var total_changes = model.get( 'lines_added' ) + model.get( 'lines_deleted'), 89 scope_of_changes = 'vsmall'; 90 91 // Note: hard coded scope of changes 92 // TODO change to dynamic based on range of values 93 if ( total_changes > 1 && total_changes <= 3 ) { 94 scope_of_changes = 'small'; 95 } else if( total_changes > 3 && total_changes <= 5 ) { 96 scope_of_changes = 'med'; 97 } else if( total_changes > 5 && total_changes <= 10 ) { 98 scope_of_changes = 'large'; 99 } else if( total_changes > 10 ) { 100 scope_of_changes = 'vlarge'; 101 } 102 model.set( 'scope_of_changes', scope_of_changes ); 103 if ( 0 !== self.rightDiff && 104 model.get( 'ID' ) === self.revisions.at( self.rightDiff - 1 ).get( 'ID' ) ) { 105 // reload if current model refreshed 106 self.revisionView.render(); 107 } 108 109 } 110 } ); 111 }, delay ) ; 112 delay = delay + 150; // stagger model loads to avoid hammering server with requests 113 } 114 ); 115 }, 116 117 startLeftModelLoading: function() { 118 this.leftModelLoading = true; 119 $('.revisiondiffcontainer').addClass('leftmodelloading'); 120 }, 121 122 stopLeftModelLoading: function() { 123 this.leftModelLoading = false; 124 }, 125 126 startRightModelLoading: function() { 127 this.rightModelLoading = true; 128 $('.revisiondiffcontainer').addClass('rightmodelloading'); 129 }, 130 131 stopRightModelLoading: function() { 132 this.rightModelLoading = false; 133 }, 134 135 stopModelLoadingSpinner: function() { 136 $('.revisiondiffcontainer').removeClass('rightmodelloading'); 137 $('.revisiondiffcontainer').removeClass('leftmodelloading'); 138 }, 139 140 reloadModel: function() { 141 if ( this.singleRevision ) { 142 this.reloadModelSingle(); 143 } else { 144 this.reloadLeftRight(); 145 } 146 }, 147 148 // load the models for the single handle mode 149 reloadModelSingle: function() { 150 var self = this; 151 152 // TODO: Only updates the query args yet 153 self.revisions.reload({ 154 'showAutosaves': self.autosaves, 155 'showSplitView': self.showSplitView 156 }); 157 158 self.startRightModelLoading(); 159 self.revisions.fetch({ // reload revision data 160 success: function() { 161 var revisionCount = self.revisions.length; 162 self.revisionView.model = self.revisions; 163 self.revisionView.render(); 164 self.reloadToLoadRevisions( self.revisions ); 165 self.tickmarkView.model = self.revisions; 166 self.tickmarkView.render(); 167 self.slider.refresh({ 168 'max': revisionCount - 1, 169 'value': self.rightDiff - 1 170 }, true); 171 }, 172 173 error: function() { 174 self.stopRightModelLoading(); 175 } 176 177 }); 178 }, 179 180 // load the models for the left handle 181 reloadLeft: function() { 182 var self = this; 183 self.startLeftModelLoading(); 184 self.leftHandleRevisions = new Revisions( {}, { 185 'compareTo': self.revisions.at( self.rightDiff - 1 ).get( 'ID' ), 186 'showAutosaves': self.autosaves, 187 'showSplitView': self.showSplitView, 188 'rightHandleAt': self.rightDiff 189 }); 190 191 self.leftHandleRevisions.fetch({ 192 success: function(){ 193 self.stopLeftModelLoading(); 194 self.reloadToLoadRevisions( self.leftHandleRevisions ); 195 self.tickmarkView.model = self.leftHandleRevisions; 196 self.slider.refresh({ 197 'max': self.revisions.length 198 }); 199 // ensure right handle not beyond length, in particular if viewing autosaves is switched from on to off 200 // the number of models in the collection might get shorter, this ensures right handle is not beyond last model 201 if ( self.rightDiff > self.revisions.length ) 202 self.rightDiff = self.revisions.length; 238 203 }, 239 204 240 error: function( response ) { 241 self.stopRightModelLoading(); 205 error: function() { 206 self.stopLeftModelLoading(); 207 } 208 }); 209 }, 210 211 // load the models for the right handle 212 reloadRight: function() { 213 var self = this; 214 self.startRightModelLoading(); 215 self.rightHandleRevisions = new Revisions( {}, { 216 'compareTo': self.revisions.at( self.leftDiff ).get( 'ID' ) - 1, 217 'showAutosaves': self.autosaves, 218 'showSplitView': self.showSplitView, 219 'leftHandleAt': self.leftDiff 220 }); 221 222 self.rightHandleRevisions.fetch({ 223 success: function(){ 224 self.stopRightModelLoading(); 225 self.reloadToLoadRevisions( self.rightHandleRevisions ); 226 self.tickmarkView.model = self.rightHandleRevisions; 227 self.slider.refresh({ 228 'max': self.revisions.length, 229 'values': [ self.leftDiff, self.rightDiff] 230 }, true); 231 }, 232 233 error: function( response ) { 234 self.stopRightModelLoading(); 235 } 236 }); 237 238 }, 239 240 reloadLeftRight: function() { 241 this.startRightModelLoading(); 242 this.startLeftModelLoading(); 243 this.reloadLeft(); 244 this.reloadRight(); 245 }, 246 247 completeApplicationSetup: function() { 248 this.revisionView = new revisions.view.Diff({ 249 model: this.revisions 250 }); 251 this.revisionView.render(); 252 253 this.reloadToLoadRevisions( this.revisions ); 254 255 this.revisionsInteractions = new revisions.view.Interact({ 256 model: this.revisions 257 }); 258 this.revisionsInteractions.render(); 259 260 this.tickmarkView = new revisions.view.Tickmarks({ 261 model: this.revisions 262 }); 263 this.tickmarkView.render(); 264 this.tickmarkView.resetTicks(); 265 266 } 267 }); 268 269 270 /** 271 * ======================================================================== 272 * VIEWS 273 * ======================================================================== 274 */ 275 276 /** 277 * wp.revisions.view.Slider 278 * 279 * The slider 280 */ 281 revisions.view.Slider = Backbone.View.extend({ 282 el: $( '#slider' ), 283 singleRevision: true, 284 285 initialize: function( options ) { 286 this.options = _.defaults( options || {}, { 287 value: 0, 288 min: 0, 289 max: 1, 290 step: 1 291 }); 292 }, 293 294 slide: function( event, ui ) { 295 if ( this.singleRevision ) { 296 Diff.rightDiff = ( ui.value + 1 ); 297 Diff.revisionView.render(); 298 } else { 299 if ( ui.values[0] === ui.values[1] ) // prevent compare to self 300 return false; 301 302 if ( $( ui.handle ).hasClass( 'left-handle' ) ) { 303 // Left handler 304 if ( Diff.leftModelLoading ) // left model still loading, prevent sliding left handle 305 return false; 306 307 Diff.leftDiff = ui.values[0]; 308 } else { 309 // Right handler 310 if ( Diff.rightModelLoading ) // right model still loading, prevent sliding right handle 311 return false; 312 313 Diff.rightDiff = ui.values[1]; 314 } 315 316 if ( 0 === Diff.leftDiff ) { 317 $( '.revisiondiffcontainer' ).addClass( 'currentversion' ); 318 } else { 319 $( '.revisiondiffcontainer' ).removeClass( 'currentversion' ); 320 } 321 322 Diff.revisionView.render(); 323 } 324 }, 325 326 start: function( event, ui ) { 327 // Not needed in one mode 328 if ( this.singleRevision ) 329 return; 330 331 if ( $( ui.handle ).hasClass( 'left-handle' ) ) { 332 // Left handler 333 if ( Diff.leftModelLoading ) // left model still loading, prevent sliding left handle 334 return false; 335 336 Diff.revisionView.draggingLeft = true; 337 338 if ( Diff.revisionView.model !== Diff.leftHandleRevisions && 339 null !== Diff.leftHandleRevisions ) { 340 Diff.revisionView.model = Diff.leftHandleRevisions; 341 Diff.tickmarkView.model = Diff.leftHandleRevisions; 342 Diff.tickmarkView.render(); 343 } 344 345 Diff.leftDiffStart = ui.values[ 0 ]; 346 347 } else { 348 // Right handler 349 if ( Diff.rightModelLoading || 0 === Diff.rightHandleRevisions.length) // right model still loading, prevent sliding right handle 350 return false; 351 352 if ( Diff.revisionView.model !== Diff.rightHandleRevisions && 353 null !== Diff.rightHandleRevisions ) { 354 Diff.revisionView.model = Diff.rightHandleRevisions; 355 Diff.tickmarkView.model = Diff.rightHandleRevisions; 356 Diff.tickmarkView.render(); 357 } 358 359 Diff.revisionView.draggingLeft = false; 360 Diff.rightDiffStart = ui.values[1]; 361 } 362 }, 363 364 stop: function( event, ui ) { 365 // Not needed in one mode 366 if ( this.singleRevision ) 367 return; 368 369 // calculate and generate a diff for comparing to the left handle 370 // and the right handle, swap out when dragging 371 if ( $( ui.handle ).hasClass( 'left-handle' ) ) { 372 // Left hadnler 373 if ( Diff.leftDiffStart !== ui.values[0] ) 374 Diff.reloadRight(); 375 } else { 376 // Right handler 377 if ( Diff.rightDiffStart !== ui.values[1] ) 378 Diff.reloadLeft(); 379 } 380 }, 381 382 addTooltip: function( handle, message ) { 383 384 handle.attr( 'title', '' ).tooltip({ 385 track: false, 386 387 position: { 388 my: "left-30 top-66", 389 at: "top left", 390 using: function( position, feedback ) { 391 $( this ).css( position ); 392 $( "<div>" ) 393 .addClass( "arrow" ) 394 .addClass( feedback.vertical ) 395 .addClass( feedback.horizontal ) 396 .appendTo( $( this ) ); 242 397 } 398 }, 399 show: false, 400 hide: false, 401 content: function() { 402 return message; 403 } 404 405 } ); 406 }, 407 408 width: function() { 409 return $( '#slider' ).width(); 410 }, 411 412 setWidth: function( width ) { 413 return $( '#slider' ).width( width ); 414 }, 415 416 refresh: function( options, slide ) { 417 $( '#slider' ).slider( 'option', options ); 418 419 // Triggers the slide event 420 if ( slide ) 421 $( '#slider' ).trigger( 'slide' ); 422 }, 423 424 option: function( key ) { 425 return $( '#slider' ).slider( 'option', key ); 426 }, 427 428 render: function() { 429 var self = this; 430 // this.$el doesn't work, why? 431 $( '#slider' ).slider( { 432 slide: $.proxy( self.slide, self ), 433 start: $.proxy( self.start, self ), 434 stop: $.proxy( self.stop, self ) 435 } ); 436 437 // Set options 438 this.refresh( this.options ); 439 } 440 }); 441 442 /** 443 * wp.revisions.view.Tickmarks 444 * 445 * The slider tickmarks. 446 */ 447 revisions.view.Tickmarks = Backbone.View.extend({ 448 el: $('#diff-slider-ticks'), 449 template: wp.template('revision-ticks'), 450 model: Revision, 451 452 resetTicks: function() { 453 var sliderMax = Diff.slider.option( 'max' ); 454 var sliderWidth = Diff.slider.width(); 455 var adjustMax = Diff.singleRevision ? 0 : 1; 456 var tickWidth = Math.floor( sliderWidth / ( sliderMax - adjustMax ) ); 457 458 // TODO: adjust right margins for wider ticks so they stay centered on handle stop point 459 460 // set minimum and maximum widths for tick marks 461 tickWidth = (tickWidth > 50 ) ? 50 : tickWidth; 462 tickWidth = (tickWidth < 10 ) ? 10 : tickWidth; 463 464 sliderWidth = tickWidth * (sliderMax - adjustMax ) + 1; 465 466 Diff.slider.setWidth( sliderWidth ); 467 $( '.diff-slider-ticks-wrapper' ).width( sliderWidth ); 468 $( '#diffslider' ).width( sliderWidth ); 469 $( '#diff-slider-ticks' ).width( sliderWidth ); 470 471 var aTickWidth = $( '.revision-tick' ).width(); 472 473 if ( tickWidth !== aTickWidth ) { // is the width already set correctly? 474 $( '.revision-tick' ).each( function( ) { 475 $(this).css( 'margin-right', tickWidth - 1 + 'px'); // space the ticks out using right margin 243 476 }); 244 477 245 }, 246 247 reloadLeftRight: function() { 248 this.startRightModelLoading(); 249 this.startLeftModelLoading(); 250 this.reloadLeft(); 251 this.reloadRight(); 252 }, 253 254 /* 255 * initialize the revision application 256 */ 257 initialize: function( options ) { 258 var self = this; // store the application instance 259 if (this._revisions === null) { 260 self._revisions = new wp.revisions.Collection(); // set up collection 261 self.startRightModelLoading(); 262 self._revisions.fetch({ // load revision data 263 264 success: function() { 265 self.stopRightModelLoading(); 266 // self._rightHandleRevisions = self._revisions; 267 self.completeApplicationSetup(); 268 } 269 }); 270 } 271 return this; 272 }, 273 274 addTooltip: function( handle, message ) { 275 276 handle.attr( 'title', '' ).tooltip({ 277 track: false, 278 279 position: { 280 my: "left-30 top-66", 281 at: "top left", 282 using: function( position, feedback ) { 283 $( this ).css( position ); 284 $( "<div>" ) 285 .addClass( "arrow" ) 286 .addClass( feedback.vertical ) 287 .addClass( feedback.horizontal ) 288 .appendTo( $( this ) ); 289 } 290 }, 291 show: false, 292 hide: false, 293 content: function() { 294 return message; 478 if( ! Diff.singleRevision ) { 479 $( '.revision-tick' ).first().remove(); // TODO - remove the check 480 } 481 $( '.revision-tick' ).last().css( 'margin-right', '0' ); // last tick gets no right margin 482 } 483 484 }, 485 486 // render the tickmark view 487 render: function() { 488 var self = this; 489 490 if ( null !== self.model ) { 491 var addHtml = ""; 492 _.each ( self.model.models, function( theModel ) { 493 addHtml = addHtml + self.template ( theModel.toJSON() ); 494 }); 495 self.$el.html( addHtml ); 496 497 } 498 self.resetTicks(); 499 return self; 500 } 501 }); 502 503 /** 504 * wp.revisions.view.Interact 505 * 506 * Next/Prev buttons and the slider 507 */ 508 // TODO: Change Interact to something else. 509 revisions.view.Interact = Backbone.View.extend({ 510 el: $('#backbonerevisionsinteract'), 511 template: wp.template('revision-interact'), 512 513 // next and previous buttons, only available in compare one mode 514 events: { 515 'click #next': 'nextRevision', 516 'click #previous': 'previousRevision' 517 }, 518 519 render: function() { 520 var self = this; 521 522 var addHtml = this.template; 523 this.$el.html( addHtml ); 524 525 var modelcount = Diff.revisions.length; 526 527 Diff.slider.singleRevision = Diff.singleRevision; 528 Diff.slider.render(); 529 530 if ( Diff.singleRevision ) { 531 Diff.slider.refresh({ 532 value: Diff.rightDiff - 1, 533 min: 0, 534 max: modelcount - 1 535 }); 536 537 $( '.revisiondiffcontainer' ).removeClass( 'comparetwo' ); 538 539 } else { 540 Diff.slider.refresh({ 541 values: [ Diff.leftDiff, Diff.rightDiff + 1 ], 542 min: 1, 543 max: modelcount + 1, 544 range: true 545 }); 546 547 $( '.revisiondiffcontainer' ).addClass( 'comparetwo' ); 548 $( '#diffslider a.ui-slider-handle' ).first().addClass( 'left-handle' ); 549 $( '#diffslider a.ui-slider-handle' ).last().addClass( 'right-handle' ); 550 551 } 552 553 return this; 554 }, 555 556 // go to the next revision 557 nextRevision: function() { 558 if ( Diff.rightDiff < this.model.length ) // unless at right boundry 559 Diff.rightDiff = Diff.rightDiff + 1 ; 560 561 Diff.revisionView.render(); 562 563 Diff.slider.refresh({ 564 value: Diff.rightDiff - 1 565 }, true ); 566 }, 567 568 // go the the previous revision 569 previousRevision: function() { 570 if ( Diff.rightDiff > 1 ) // unless at left boundry 571 Diff.rightDiff = Diff.rightDiff - 1 ; 572 573 Diff.revisionView.render(); 574 575 Diff.slider.refresh({ 576 value: Diff.rightDiff - 1 577 }, true ); 578 } 579 }); 580 581 /** 582 * wp.revisions.view.Diff 583 * 584 * Next/Prev buttons and the slider 585 */ 586 revisions.view.Diff = Backbone.View.extend({ 587 el: $('#backbonerevisionsdiff'), 588 template: wp.template('revision'), 589 draggingLeft: false, 590 591 // the compare two button is in this view, add the interaction here 592 events: { 593 'click #comparetwo': 'compareTwo', 594 'click #restore': 'restore' 595 }, 596 597 // render the revisions 598 render: function() { 599 var addHtml = ''; 600 var thediff; 601 602 // compare two revisions mode? 603 if ( ! Diff.singleRevision ) { 604 if ( this.draggingLeft ) { 605 thediff = Diff.leftDiff - 1; 606 if ( this.model.at( thediff ) ) { 607 addHtml = this.template( this.model.at( thediff ).toJSON() ); 295 608 } 296 297 } ); 298 }, 299 /**/ 300 301 completeApplicationSetup: function() { 302 this._revisionView = new wp.revisions.views.View({ 303 model: this._revisions 304 }); 305 this._revisionView.render(); 306 $( '#slider' ).slider( 'option', 'max', this._revisions.length - 1 ); 307 308 this.reloadToLoadRevisions( this._revisions ); 309 310 this._revisionsInteractions = new wp.revisions.views.Interact({ 311 model: this._revisions 312 }); 313 this._revisionsInteractions.render(); 314 315 this._tickmarkView = new wp.revisions.views.Tickmarks({ 316 model: this._revisions 317 }); 318 this._tickmarkView.render(); 319 this._tickmarkView.resetTicks(); 320 321 322 /* 323 .on( 'mouseup', function( event ) { 324 REVAPP._keep_tooltip_open = false; 325 $( this ).find('.ui-slider-tooltip').hide(); 326 } ).on( 'mousedown', function( event ) { 327 REVAPP._keep_tooltip_open = true; 328 } ).on( 'mouseout', function( event ) { 329 if ( REVAPP._keep_tooltip_open) 330 event.stopImmediatePropagation(); 331 }); 332 */ 333 /* 334 // Options hidden for now, moving to screen options 335 this._revisionsOptions = new wp.revisions.views.Options({ 336 model: this._revisions 337 }); 338 this._revisionsOptions.render(); 339 */ 340 341 } 342 }) 343 }; 344 345 wp.revisions.Collection = Backbone.Collection.extend({ 346 model: wp.revisions.Model, 347 url: ajaxurl + '?action=revisions-data&compare_to=' + wpRevisionsSettings.post_id + 348 '&show_autosaves=true&show_split_view=true&nonce=' + wpRevisionsSettings.nonce, 349 350 initialize: function() { 351 } 609 } else { // dragging right handle 610 thediff = Diff.rightDiff -1; 611 if ( this.model.at( thediff ) ) { 612 addHtml = this.template( this.model.at( thediff ).toJSON() ); 613 } 614 } 615 } else { // end compare two revisions mode, eg only one slider handle 616 this.comparetwochecked = ''; 617 if ( this.model.at( Diff.rightDiff - 1 ) ) { 618 addHtml = this.template( this.model.at( Diff.rightDiff - 1 ).toJSON() ); 619 } 620 } 621 this.$el.html( addHtml ); 622 623 if ( this.model.length < 2 ) { 624 $( '#diffslider' ).hide(); // don't allow compare two if fewer than three revisions 625 $( '.diff-slider-ticks-wrapper' ).hide(); 626 } 627 628 // add tooltips to the handles 629 if ( ! Diff.singleRevision ) { 630 Diff.slider.addTooltip ( $( 'a.ui-slider-handle.left-handle' ), 631 ( Diff.leftDiff < 0 ) ? '' : Diff.revisions.at( Diff.leftDiff - 1 ).get( 'titleTooltip' ) ); 632 Diff.slider.addTooltip ( $( 'a.ui-slider-handle.right-handle' ), 633 ( Diff.rightDiff > Diff.revisions.length ) ? '' : Diff.revisions.at( Diff.rightDiff - 1 ).get( 'titleTooltip' ) ); 634 } else { 635 Diff.slider.addTooltip ( $( 'a.ui-slider-handle' ), 636 ( Diff.rightDiff > Diff.revisions.length ) ? '' : Diff.revisions.at( Diff.rightDiff - 1 ).get( 'titleTooltip' ) ); 637 } 638 639 this.toogleCompareTwoCheckbox(); 640 641 // hide the restore button when on the last sport/current post data 642 if ( Diff.rightDiff === Diff.revisions.length ){ 643 $( '#restore' ).hide(); 644 } else { 645 $( '#restore' ).show(); 646 } 647 648 return this; 649 }, 650 651 toogleCompareTwoCheckbox: function() { 652 // don't allow compare two if fewer than three revisions 653 if ( this.model.length < 3 ) 654 $( '#comparetworevisions' ).hide(); 655 656 $( '#comparetwo' ).prop( 'checked', ! Diff.singleRevision ); 657 }, 658 659 // turn on/off the compare two mode 660 compareTwo: function() { 661 if ( $( 'input#comparetwo' ).is( ':checked' ) ) { // compare 2 mode 662 Diff.singleRevision = false ; 663 664 if ( 1 === Diff.rightDiff ) 665 Diff.rightDiff = 2; 666 667 Diff.revisionView.draggingLeft = false; 668 669 revisions.model.settings.revision_id = ''; // reset passed revision id so switching back to one handle mode doesn't re-select revision 670 Diff.reloadLeftRight(); 671 Diff.revisionView.model = Diff.rightHandleRevisions; 672 673 } else { // compare one mode 674 Diff.singleRevision = true; 675 Diff.revisionView.draggingLeft = false; 676 Diff.reloadModelSingle(); 677 } 678 Diff.revisionsInteractions.render(); 679 Diff.tickmarkView.render(); 680 }, 681 682 restore: function() { 683 document.location = $( '#restore' ).data( 'restoreLink' ); 684 } 685 }); 686 687 688 /** 689 * ======================================================================== 690 * MODELS 691 * ======================================================================== 692 */ 693 694 /** 695 * wp.revisions.Revision 696 */ 697 Revision = revisions.model.Revision = Backbone.Model.extend({ 698 idAttribute: 'ID', 699 urlRoot: ajaxurl + '?action=revisions-data' + 700 '&show_autosaves=true&show_split_view=true&nonce=' + revisions.model.settings.nonce, 701 defaults: { 702 ID: 0, 703 titleTo: '', 704 titleTooltip: '', 705 titleFrom: '', 706 diff: '<div class="diff-loading"><div class="spinner"></div></div>', 707 restoreLink: '', 708 revision_toload: false, 709 lines_added: 0, 710 lines_deleted: 0, 711 scope_of_changes: 'none', 712 previous_revision_id: 0 713 }, 714 715 url: function() { 716 if ( Diff.singleRevision ) { 717 return this.urlRoot + 718 '&single_revision_id=' + this.id + 719 '&compare_to=' + this.get( 'previous_revision_id' ) + 720 '&post_id=' + revisions.model.settings.post_id; 721 } else { 722 return this.collection.url() + '&single_revision_id=' + this.id; 723 } 724 725 } 726 }); 727 728 /** 729 * wp.revisions.Revisions 730 */ 731 Revisions = revisions.Revisions = Backbone.Collection.extend({ 732 model: Revision, 733 urlRoot: ajaxurl + '?action=revisions-data', 734 735 initialize: function( models, options ) { 736 this.options = _.defaults( options || {}, { 737 'compareTo': revisions.model.settings.post_id, 738 'post_id': revisions.model.settings.post_id, 739 'showAutosaves': true, 740 'showSplitView': true, 741 'rightHandleAt': 0, 742 'leftHandleAt': 0, 743 'nonce': revisions.model.settings.nonce 744 }); 745 }, 746 747 url: function() { 748 return this.urlRoot + 749 '&compare_to=' + this.options.compareTo + 750 '&post_id=' + this.options.post_id + 751 '&show_autosaves=' + this.options.showAutosaves + 752 '&show_split_view=' + this.options.showSplitView + 753 '&right_handle_at=' + this.options.rightHandleAt + 754 '&left_handle_at=' + this.options.leftHandleAt + 755 '&nonce=' + this.options.nonce; 756 }, 757 758 reload: function( options ) { 759 this.options = _.defaults( options || {}, this.options ); 760 761 // TODO 762 //this.fetch(); 763 } 764 352 765 } ); 353 766 354 _.extend(wp.revisions.views, { 355 356 // Ticks inside slider view 357 Tickmarks: Backbone.View.extend({ 358 el: $('#diff-slider-ticks')[0], 359 tagName: 'diff-slider-ticks-view', 360 className: 'diff-slider-ticks-container', 361 template: wp.template('revision-ticks'), 362 model: wp.revisions.Model, 363 364 resetTicks: function() { 365 var sliderMax = $( '#slider' ).slider( 'option', 'max'); 366 var sliderWidth = $( '#slider' ).width(); 367 var adjustMax = ( 2 === REVAPP._compareOneOrTwo ) ? 1 : 0; 368 var tickWidth = Math.floor( sliderWidth / ( sliderMax - adjustMax ) ); 369 370 // TODO: adjust right margins for wider ticks so they stay centered on handle stop point 371 372 // set minimum and maximum widths for tick marks 373 tickWidth = (tickWidth > 50 ) ? 50 : tickWidth; 374 tickWidth = (tickWidth < 10 ) ? 10 : tickWidth; 375 376 sliderWidth = tickWidth * (sliderMax - adjustMax ) + 1; 377 378 $( '#slider' ).width( sliderWidth ); 379 $( '.diff-slider-ticks-wrapper' ).width( sliderWidth ); 380 $( '#diffslider' ).width( sliderWidth ); 381 $( '#diff-slider-ticks' ).width( sliderWidth ); 382 383 var aTickWidth = $( '.revision-tick' ).width(); 384 385 if ( tickWidth !== aTickWidth ) { // is the width already set correctly? 386 $( '.revision-tick' ).each( function( ) { 387 $(this).css( 'margin-right', tickWidth - 1 + 'px'); // space the ticks out using right margin 388 }); 389 390 if( 2 === REVAPP._compareOneOrTwo ) { 391 $( '.revision-tick' ).first().remove(); // TODO - remove the check 392 } 393 $( '.revision-tick' ).last().css( 'margin-right', '0' ); // last tick gets no right margin 394 } 395 396 }, 397 398 // render the tickmark view 399 render: function() { 400 var self = this; 401 402 if ( null !== self.model ) { 403 var addHtml = ""; 404 _.each ( self.model.models, function( theModel ) { 405 addHtml = addHtml + self.template ( theModel.toJSON() ); 406 }); 407 self.$el.html( addHtml ); 408 409 } 410 self.resetTicks(); 411 return self; 412 } 413 }), 414 415 // primary revision diff view 416 View: Backbone.View.extend({ 417 el: $('#backbonerevisionsdiff')[0], 418 tagName: 'revisionvview', 419 className: 'revisionview-container', 420 template: wp.template('revision'), 421 comparetwochecked: '', 422 draggingLeft: false, 423 424 // render the revisions 425 render: function() { 426 var addHtml = ''; 427 var thediff; 428 // compare two revisions mode? 429 430 if ( 2 === REVAPP._compareOneOrTwo ) { 431 432 this.comparetwochecked = 'checked'; 433 if ( this.draggingLeft ) { 434 thediff = REVAPP._leftDiff -1; 435 if ( this.model.at( thediff ) ) { 436 addHtml = this.template( _.extend( 437 this.model.at( thediff ).toJSON(), 438 { comparetwochecked: this.comparetwochecked } // keep the checkmark checked 439 ) ); 440 } 441 } else { // dragging right handle 442 thediff = REVAPP._rightDiff -1; 443 if ( this.model.at( thediff ) ) { 444 addHtml = this.template( _.extend( 445 this.model.at( thediff ).toJSON(), 446 { comparetwochecked: this.comparetwochecked } // keep the checkmark checked 447 ) ); 448 } 449 } 450 } else { // end compare two revisions mode, eg only one slider handle 451 this.comparetwochecked = ''; 452 if ( this.model.at( REVAPP._rightDiff - 1 ) ) { 453 addHtml = this.template( _.extend( 454 this.model.at( REVAPP._rightDiff - 1 ).toJSON(), 455 { comparetwochecked: this.comparetwochecked } // keep the checkmark unchecked 456 ) ); 457 } 458 } 459 this.$el.html( addHtml ); 460 if ( this.model.length < 3 ) { 461 $( 'div#comparetworevisions' ).hide(); // don't allow compare two if fewer than three revisions 462 } 463 if ( this.model.length < 2 ) { 464 $( 'div#diffslider' ).hide(); // don't allow compare two if fewer than three revisions 465 $( 'div.diff-slider-ticks-wrapper' ).hide(); 466 } 467 468 // add tooltips to the handles 469 if ( 2 === REVAPP._compareOneOrTwo ) { 470 REVAPP.addTooltip ( $( 'a.ui-slider-handle.left-handle' ), 471 ( REVAPP._leftDiff < 0 ) ? '' : REVAPP._revisions.at( REVAPP._leftDiff - 1 ).get( 'revision_date_author_short' ) ); 472 REVAPP.addTooltip ( $( 'a.ui-slider-handle.right-handle' ), 473 ( REVAPP._rightDiff > REVAPP._revisions.length ) ? '' : REVAPP._revisions.at( REVAPP._rightDiff - 1 ).get( 'revision_date_author_short' ) ); 474 } else { 475 REVAPP.addTooltip ( $( 'a.ui-slider-handle' ), 476 ( REVAPP._rightDiff > REVAPP._revisions.length ) ? '' : REVAPP._revisions.at( REVAPP._rightDiff - 1 ).get( 'revision_date_author_short' ) ); 477 } 478 479 // hide the restore button when on the last sport/current post data 480 if ( REVAPP._rightDiff === REVAPP._revisions.length ){ 481 $( '.restore-button' ).hide(); 482 } else { 483 $( '.restore-button' ).show(); 484 } 485 486 return this; 487 }, 488 489 // the compare two button is in this view, add the interaction here 490 events: { 491 'click #comparetwo': 'clickcomparetwo' 492 }, 493 494 // turn on/off the compare two mmode 495 clickcomparetwo: function(){ 496 self = this; 497 498 if ( $( 'input#comparetwo' ).is( ':checked' ) ) { // compare 2 mode 499 REVAPP._compareOneOrTwo = 2 ; 500 501 if ( 1 === REVAPP._rightDiff ) 502 REVAPP._rightDiff = 2; 503 REVAPP._revisionView.draggingLeft = false; 504 505 wpRevisionsSettings.revision_id = ''; // reset passed revision id so switching back to one handle mode doesn't re-select revision 506 REVAPP.reloadLeftRight(); 507 REVAPP._revisionView.model = REVAPP._rightHandleRevisions; 508 509 } else { // compare one mode 510 REVAPP._compareOneOrTwo = 1 ; 511 REVAPP._revisionView.draggingLeft = false; 512 // REVAPP._leftDiff = 0; 513 // REVAPP._rightDiff = (REVAPP._revisions.length <= REVAPP._rightDiff ) ? REVAPP._rightDiff + 1 : REVAPP._rightDiff + 1; 514 REVAPP.reloadModelSingle(); 515 } 516 // REVAPP._revisionView.render(); 517 REVAPP._revisionsInteractions.render(); 518 REVAPP._tickmarkView.render(); 519 520 } 521 }), 522 523 // options view for show autosaves and show split view options 524 /* DISABLED for now 525 Options: Backbone.View.extend({ 526 el: $('#backbonerevisionsoptions')[0], 527 tagName: 'revisionoptionsview', 528 className: 'revisionoptions-container', 529 template: wp.template('revisionoptions'), 530 531 // render the options view 532 render: function() { 533 var addHtml = this.template; 534 this.$el.html( addHtml ); 535 return this; 536 }, 537 538 // add options interactions 539 events: { 540 'click #toggleshowautosaves': 'toggleshowautosaves', 541 'click #showsplitview': 'showsplitview' 542 }, 543 544 // toggle include autosaves 545 toggleshowautosaves: function() { 546 var self = this; 547 if ( $( '#toggleshowautosaves' ).is( ':checked' ) ) { 548 REVAPP._autosaves = true ; 549 } else { 550 REVAPP._autosaves = false ; 551 } 552 553 // refresh the model data 554 REVAPP.reloadModel(); 555 }, 556 557 // toggle showing the split diff view 558 showsplitview: function() { 559 var self = this; 560 561 if ( $( 'input#showsplitview' ).is( ':checked' ) ) { 562 REVAPP._showSplitView = 'true'; 563 $('.revisiondiffcontainer').addClass('diffsplit'); 564 } else { 565 REVAPP._showSplitView = ''; 566 $('.revisiondiffcontainer').removeClass('diffsplit'); 567 } 568 569 REVAPP.reloadModel(); 570 } 571 }), 572 */ 573 // main interactions view 574 Interact: Backbone.View.extend({ 575 el: $('#backbonerevisionsinteract')[0], 576 tagName: 'revisionvinteract', 577 className: 'revisionvinteract-container', 578 template: wp.template('revisionvinteract'), 579 580 initialize: function() { 581 }, 582 583 render: function() { 584 var self = this; 585 586 var addHtml = this.template; 587 this.$el.html( addHtml ); 588 589 var modelcount = REVAPP._revisions.length; 590 591 slider = $( "#slider" ); 592 if ( 1 === REVAPP._compareOneOrTwo ) { 593 // set up the slider with a single handle 594 slider.slider({ 595 value: REVAPP._rightDiff - 1, 596 min: 0, 597 max: modelcount - 1, 598 step: 1, 599 600 601 // slide interactions for one handles slider 602 slide: function( event, ui ) { 603 604 REVAPP._rightDiff = ( ui.value + 1 ); 605 REVAPP._revisionView.render(); 606 /* 607 $( 'a.ui-slider-handle' ).tooltip( { 608 content: REVAPP._revisions.at( ui.value ).get( 'revision_date_author_short' ), 609 position: { 610 my: "top-65", 611 using: function( position, feedback ) { 612 $( this ).css( position ); 613 $( "<div>" ) 614 .addClass( "arrow" ) 615 .addClass( feedback.vertical ) 616 .addClass( feedback.horizontal ) 617 .appendTo( this ); 618 } 619 } 620 });// .trigger( 'close' ).trigger( 'open' ); 621 */ 622 } 623 }); 624 $( '.revisiondiffcontainer' ).removeClass( 'comparetwo' ); 625 626 } else { // comparing more than one, eg 2 627 // set up the slider with two handles 628 slider.slider({ 629 values: [ REVAPP._leftDiff, REVAPP._rightDiff + 1 ], 630 min: 1, 631 max: modelcount + 1, 632 step: 1, 633 range: true, 634 635 // in two handled mode when user starts dragging, swap in precalculated diff for handle 636 start: function(event, ui ) { 637 var index = $( ui.handle ).index(); // 0 (left) or 1 (right) 638 switch ( index ) { 639 case 1: // left handle drag 640 if ( REVAPP._leftModelLoading ) // left model still loading, prevent sliding left handle 641 return false; 642 643 REVAPP._revisionView.draggingLeft = true; 644 645 if ( REVAPP._revisionView.model !== REVAPP._leftHandleRevisions && 646 null !== REVAPP._leftHandleRevisions ) { 647 REVAPP._revisionView.model = REVAPP._leftHandleRevisions; 648 REVAPP._tickmarkView.model = REVAPP._leftHandleRevisions; 649 REVAPP._tickmarkView.render(); 650 } 651 652 REVAPP._leftDiffStart = ui.values[ 0 ]; 653 break; 654 655 case 2: // right 656 if ( REVAPP._rightModelLoading || 0 === REVAPP._rightHandleRevisions.length) // right model still loading, prevent sliding right handle 657 return false; 658 659 if ( REVAPP._revisionView.model !== REVAPP._rightHandleRevisions && 660 null !== REVAPP._rightHandleRevisions ) { 661 REVAPP._revisionView.model = REVAPP._rightHandleRevisions; 662 REVAPP._tickmarkView.model = REVAPP._rightHandleRevisions; 663 REVAPP._tickmarkView.render(); 664 } 665 666 REVAPP._revisionView.draggingLeft = false; 667 REVAPP._rightDiffStart = ui.values[1]; 668 break; 669 } 670 }, 671 672 // when sliding in two handled mode change appropriate value 673 slide: function( event, ui ) { 674 if ( ui.values[0] === ui.values[1] ) // prevent compare to self 675 return false; 676 677 var index = $( ui.handle ).index(); // 0 (left) or 1 (right) 678 679 switch ( index ) { 680 case 1: // left 681 if ( REVAPP._leftModelLoading ) // left model still loading, prevent sliding left handle 682 return false; 683 684 REVAPP._leftDiff = ui.values[0]; 685 break; 686 687 case 2: // right 688 if ( REVAPP._rightModelLoading ) // right model still loading, prevent sliding right handle 689 return false; 690 691 REVAPP._rightDiff = ui.values[1]; 692 break; 693 } 694 695 if ( 0 === REVAPP._leftDiff ) { 696 $( '.revisiondiffcontainer' ).addClass( 'currentversion' ); 697 698 } else { 699 $( '.revisiondiffcontainer' ).removeClass( 'currentversion' ); 700 } 701 702 REVAPP._revisionView.render(); 703 704 }, 705 706 // when the user stops sliding in 2 handle mode, recalculate diffs 707 stop: function( event, ui ) { 708 if ( 2 === REVAPP._compareOneOrTwo ) { 709 // calculate and generate a diff for comparing to the left handle 710 // and the right handle, swap out when dragging 711 712 var index = $( ui.handle ).index(); // 0 (left) or 1 (right) 713 714 switch ( index ) { 715 case 1: // left 716 717 // left handle dragged & changed, reload right handle model 718 if ( REVAPP._leftDiffStart !== ui.values[0] ) 719 REVAPP.reloadRight(); 720 721 break; 722 723 case 2: // right 724 // REVAPP._rightDiff = ( 1 >= REVAPP._rightDiff ) ? 1 : REVAPP._rightDiff - 1; 725 // right handle dragged & changed, reload left handle model if changed 726 if ( REVAPP._rightDiffStart !== ui.values[1] ) 727 REVAPP.reloadLeft(); 728 729 break; 730 } 731 } 732 } 733 }); 734 $( '.revisiondiffcontainer' ).addClass( 'comparetwo' ); 735 $( '#diffslider a.ui-slider-handle' ).first().addClass( 'left-handle' ).next().addClass( 'right-handle' ); 736 } 737 738 return this; 739 }, 740 741 // next and previous buttons, only available in compare one mode 742 events: { 743 'click #next': 'nextRevision', 744 'click #previous': 'previousRevision' 745 }, 746 747 // go to the next revision 748 nextRevision: function() { 749 if ( REVAPP._rightDiff < this.model.length ) // unless at right boundry 750 REVAPP._rightDiff = REVAPP._rightDiff + 1 ; 751 752 REVAPP._revisionView.render(); 753 754 $( '#slider' ).slider( 'value', REVAPP._rightDiff - 1 ).trigger( 'slide' ); 755 }, 756 757 // go the the previous revision 758 previousRevision: function() { 759 if ( REVAPP._rightDiff > 1 ) // unless at left boundry 760 REVAPP._rightDiff = REVAPP._rightDiff - 1 ; 761 762 REVAPP._revisionView.render(); 763 764 $( '#slider' ).slider( 'value', REVAPP._rightDiff - 1 ).trigger( 'slide' ); 765 } 766 }) 767 }); 768 769 // instantiate Revision Application 770 REVAPP = new wp.revisions.App(); 767 $( wp.revisions ); 771 768 772 769 }(jQuery)); -
trunk/wp-admin/revision.php
r23834 r23898 80 80 require_once( './admin-header.php' ); 81 81 82 //TODO - Some of the translations below split things into multiple strings that are contextually related and this makes it pretty impossible for RTL translation. 83 //TODO can we pass the context in a better way 84 $wpRevisionsSettings = array( 'post_id' => $post->ID, 85 'nonce' => wp_create_nonce( 'revisions-ajax-nonce' ), 86 'revision_id' => $revision_id ); 87 wp_localize_script( 'revisions', 'wpRevisionsSettings', $wpRevisionsSettings ); 82 $strings = array( 83 'diffFromTitle' => _x( 'From: %s', 'revision from title' ), 84 'diffToTitle' => _x( 'To: %s', 'revision to title' ) 85 ); 86 87 $settings = array( 88 'post_id' => $post->ID, 89 'nonce' => wp_create_nonce( 'revisions-ajax-nonce' ), 90 'revision_id' => $revision_id 91 ); 92 93 $strings['settings'] = $settings; 94 95 wp_localize_script( 'revisions', 'wpRevisionsL10n', $strings ); 88 96 89 97 $comparetworevisionslink = get_edit_post_link( $revision->ID ); … … 113 121 114 122 <script id="tmpl-revision" type="text/html"> 123 <div id="comparetworevisions"> 124 <label> 125 <input type="checkbox" id="comparetwo" /> 126 <?php esc_attr_e( 'Compare two revisions' ); ?> 127 </label> 128 </div> 129 115 130 <div id="diffsubheader" class="diff-left-hand-meta-row"> 116 131 <div id="diff_from_current_revision"> … … 118 133 </div> 119 134 <div id="difftitlefrom"> 120 <div class="diff-from-title"><?php _e( 'From:' ); ?></div>{{{ data. revision_from_date_author}}}135 <div class="diff-from-title"><?php _e( 'From:' ); ?></div>{{{ data.titleFrom }}} 121 136 </div> 122 137 </div> … … 124 139 <div id="diffsubheader"> 125 140 <div id="difftitle"> 126 <div class="diff-to-title"><?php _e( 'To:' ); ?></div>{{{ data. revision_date_author}}}141 <div class="diff-to-title"><?php _e( 'To:' ); ?></div>{{{ data.titleTo }}} 127 142 </div> 128 143 <div id="diffrestore"> 129 <input class="button button-primary restore-button" onClick="document.location='{{{ data.restoreaction }}}'" type="submit" id="restore" value="<?php esc_attr_e( 'Restore This Revision' )?>" /> 130 </div> 131 <div id="comparetworevisions"> 132 <input type="checkbox" id="comparetwo" value="comparetwo" {{{ data.comparetwochecked }}} name="comparetwo"/> 133 <label for="comparetwo"><?php esc_attr_e( 'Compare two revisions' ); ?></a></label> 144 <input class="button button-primary" data-restore-link="{{{ data.restoreLink }}}" type="button" id="restore" value="<?php esc_attr_e( 'Restore This Revision' )?>" /> 134 145 </div> 135 146 </div> … … 139 150 <div id="added"><?php _e( 'Added +' ); ?></div> 140 151 </div 141 <div>{{{ data. revisiondiff }}}</div>152 <div>{{{ data.diff }}}</div> 142 153 </script> 143 154 144 <script id="tmpl-revision vinteract" type="text/html">155 <script id="tmpl-revision-interact" type="text/html"> 145 156 <div id="diffheader"> 146 157 <div id="diffprevious"><input class="button" type="submit" id="previous" value="<?php esc_attr_e( 'Previous' ); ?>" /> … … 154 165 </div> 155 166 </script> 167 156 168 <script id="tmpl-revision-ticks" type="text/html"> 157 169 <div class="revision-tick revision-toload{{{ data.revision_toload }}} revision-scopeofchanges-{{{ data.scope_of_changes }}}"> … … 159 171 </script> 160 172 <?php 161 /*162 TODO Convert these into screen options163 <script id="tmpl-revisionoptions" type="text/html">164 <div id="revisionoptions">165 <div id="showsplitviewoption">166 <input type='checkbox' id="show_split_view" checked="checked" value="1" /> <?php _e( 'Show split diff view' ); ?>167 </div>168 <div id="toggleshowautosavesoption">169 <input type='checkbox' id="toggleshowautosaves" value="1" /> <?php _e( 'Show autosaves' ); ?>170 </div>171 </div>172 </script>173 */174 173 require_once( './admin-footer.php' ); -
trunk/wp-includes/revision.php
r23885 r23898 676 676 $args = wp_parse_args( $args, $defaults ); 677 677 678 if ( ! class_exists( 'WP_Text_Diff_Renderer_Table' ) )678 if ( ! class_exists( 'WP_Text_Diff_Renderer_Table' ) ) 679 679 require( ABSPATH . WPINC . '/wp-diff.php' ); 680 680 … … 686 686 687 687 $text_diff = new Text_Diff($left_lines, $right_lines ); 688 $lines added = $text_diff->countAddedLines();689 $lines deleted = $text_diff->countDeletedLines();688 $lines_added = $text_diff->countAddedLines(); 689 $lines_deleted = $text_diff->countDeletedLines(); 690 690 691 691 $renderer = new WP_Text_Diff_Renderer_Table(); … … 719 719 $r .= "</table>"; 720 720 721 return array( 'html' => $r, 'lines added' => $linesadded, 'linesdeleted' => $linesdeleted );722 } 721 return array( 'html' => $r, 'lines_added' => $lines_added, 'lines_deleted' => $lines_deleted ); 722 }
Note: See TracChangeset
for help on using the changeset viewer.