Ticket #24425: 24425.draft.18.diff
File 24425.draft.18.diff, 16.6 KB (added by , 12 years ago) |
---|
-
wp-admin/js/revisions.js
3 3 (function($) { 4 4 var revisions; 5 5 6 revisions = wp.revisions = { model: {}, view: {}, controller: {} };6 revisions = wp.revisions = { model: {}, view: {}, controller: {}, router: {} }; 7 7 8 8 // Link settings. 9 9 revisions.settings = typeof _wpRevisionsSettings === 'undefined' ? {} : _wpRevisionsSettings; … … 101 101 return this.fetch({ data: { compare: comparisons }, remove: false }); 102 102 }, 103 103 104 /**/105 104 loadLast: function( num ) { 106 105 num = num || 1; 107 106 var ids = this.getProximalDiffIds(); … … 194 193 initialize: function( attributes, options ) { 195 194 this.revisions = options.revisions; 196 195 this.diffs = new revisions.model.Diffs( [], {revisions: this.revisions} ); 196 this.listenTo( this, 'change:from', this.updateDiffFrom ); 197 this.listenTo( this, 'change:to', this.updateDiffTo ); 198 this.revisionsRouter = new revisions.router.Router(); 199 this.revisionsRouter.model = this; 197 200 198 this.listenTo( this, 'change:from change:to', this.updateDiffId );199 201 }, 200 202 201 updateDiff Id: function() {203 updateDiffTo: function() { 202 204 var from = this.get( 'from' ); 203 205 var to = this.get( 'to' ); 204 this.set( 'diffId', (from ? from.id : '0') + ':' + to.id ); 206 this.set( 'diffId', (from ? from.id : '0' ) + ':' + to.id ); 207 }, 208 209 updateDiffFrom: function() { 210 if ( true === this.get( 'compareTwoMode' ) ) { 211 this.updateDiffTo(); 212 } 205 213 } 214 206 215 }); 207 216 208 217 … … 243 252 this.model.diffs.loadAllBy( 50 ); 244 253 }, this ) ); 245 254 } 255 Backbone.history.start(); 256 246 257 }, 247 258 248 259 render: function() { … … 266 277 }); 267 278 268 279 // The control view. 269 // This contains the revision slider, previous/next buttons, and the compare checkbox.280 // This contains the revision slider, previous/next buttons, the meta info and the compare checkbox. 270 281 revisions.view.Controls = wp.Backbone.View.extend({ 271 282 tagName: 'div', 272 283 className: 'revisions-controls', 273 284 274 285 initialize: function() { 275 286 // Add the button view 276 this.views.add( new revisions.view.Buttons({ 287 this.views.add( new revisions.view.Buttons({ 277 288 model: this.model 278 289 })); 279 290 … … 282 293 model: this.model 283 294 }) ); 284 295 296 285 297 // Add the Meta view 286 298 this.views.add( new revisions.view.Meta({ 287 299 model: this.model 288 300 }) ); 301 302 303 289 304 } 290 305 }); 291 306 … … 319 334 } 320 335 }); 321 336 322 323 337 // The buttons view. 324 338 // Encapsulates all of the configuration for the previous/next buttons, and the compare checkbox. 325 339 revisions.view.Buttons = wp.Backbone.View.extend({ … … 329 343 330 344 initialize: function() { 331 345 this.$el.html( this.template() ) 346 this.listenTo( this.model, 'change:compareTwoMode', this.updateCompareTwoMode ); 347 332 348 }, 333 349 334 350 events: { 335 351 'click #next': 'nextRevision', 336 'click #previous': 'previousRevision' 352 'click #previous': 'previousRevision', 353 'click .compare-two-revisions': 'compareTwoToggle' 337 354 }, 338 355 356 updateCompareTwoMode: function(){ 357 if ( true === this.model.get( 'compareTwoMode' ) ){ 358 $( '#revision-diff-container' ).addClass( 'comparing-two-revisions' ); 359 // in RTL mode the 'left handle' is the second in the slider, 'right' is first 360 $( '.wp-slider a.ui-slider-handle' ).first().addClass( isRtl ? 'right-handle' : 'left-handle' ); 361 $( '.wp-slider a.ui-slider-handle' ).last().addClass( isRtl ? 'left-handle' : 'right-handle' ); 362 } else { 363 $( '#revision-diff-container' ).removeClass( 'comparing-two-revisions' ); 364 $( '.wp-slider a.ui-slider-handle' ).removeClass( 'left-handle' ).removeClass( 'right-handle' ); 365 } 366 367 }, 368 369 // Toggle the compare two mode feature when the compare two checkbox is checked. 370 compareTwoToggle: function( event ){ 371 // Activate compare two mode? 372 if ( $( '.compare-two-revisions' ).is( ':checked' ) ) { 373 this.model.set( { compareTwoMode: true } ); 374 } else { 375 this.model.set( { compareTwoMode: false } ); 376 } 377 this.updateCompareTwoMode(); 378 this.model.revisionsRouter.navigateRoute( this.model.get( 'to').id, this.model.get( 'from' ).id ); 379 380 }, 381 382 // Go to a specific modelindex, taking into account Rtl mode. 339 383 gotoModel: function( toIndex ) { 340 384 var attributes = { 341 to: this.model.revisions.at( isRtl ? this.model.revisions.length - toIndex - 1 : toIndex ) // Reverse directions for Rtl 385 to: this.model.revisions.at( isRtl ? this.model.revisions.length - toIndex - 1 : toIndex ) // Reverse directions for Rtl. 342 386 }; 343 387 // If we're at the first revision, unset 'from'. 344 388 if ( isRtl ? this.model.revisions.length - toIndex - 1 : toIndex ) // Reverse directions for Rtl … … 347 391 this.model.unset('from', { silent: true }); 348 392 349 393 this.model.set( attributes ); 394 395 this.model.revisionsRouter.navigateRoute( attributes.to.id, attributes.from ? attributes.from.id : 0 ); 396 350 397 }, 351 398 399 // Go to the 'next' revision, direction takes into account Rtl mode. 352 400 nextRevision: function() { 353 var toIndex = this.model.revisions.indexOf( this.model.get( 'to' ) );401 var toIndex = isRtl ? this.model.revisions.length - this.model.revisions.indexOf( this.model.get( 'to' ) ) - 1 : this.model.revisions.indexOf( this.model.get( 'to' ) ); 354 402 toIndex = isRtl ? toIndex - 1 : toIndex + 1; 355 403 this.gotoModel( toIndex ); 356 404 }, 357 405 406 // Go to the 'previous' revision, direction takes into account Rtl mode. 358 407 previousRevision: function() { 359 var toIndex = this.model.revisions.indexOf( this.model.get('to') );408 var toIndex = isRtl ? this.model.revisions.length - this.model.revisions.indexOf( this.model.get( 'to' ) ) - 1 : this.model.revisions.indexOf( this.model.get( 'to' ) ); 360 409 toIndex = isRtl ? toIndex + 1 : toIndex - 1; 361 410 this.gotoModel( toIndex ); 362 411 }, 363 412 364 413 ready: function() { 365 414 this.listenTo( this.model, 'change:diffId', this.disabledButtonCheck ); 415 416 // Hide compare two mode toggle when fewer than three revisions. 417 if ( this.model.revisions.length < 3 ) { 418 $( '.revision-toggle-compare-mode' ).hide(); 419 } 366 420 }, 367 421 368 // Check to see if the Previous or Next buttons need to be disabled or enabled 422 // Check to see if the Previous or Next buttons need to be disabled or enabled. 369 423 disabledButtonCheck: function() { 370 var maxVal = isRtl ? 0 :this.model.revisions.length - 1,371 minVal = isRtl ? this.model.revisions.length - 1 :0,372 next 424 var maxVal = this.model.revisions.length - 1, 425 minVal = 0, 426 next = $( '.revisions-next .button' ), 373 427 previous = $( '.revisions-previous .button' ), 374 val 428 val = this.model.revisions.indexOf( this.model.get( 'to' ) ); 375 429 376 // Disable "Next" button if you're on the last node 430 // Disable "Next" button if you're on the last node. 377 431 if ( maxVal === val ) 378 432 next.prop( 'disabled', true ); 379 433 else 380 434 next.prop( 'disabled', false ); 381 435 382 // Disable "Previous" button if you're on the first node 436 // Disable "Previous" button if you're on the first node. 383 437 if ( minVal === val ) 384 438 previous.prop( 'disabled', true ); 385 439 else … … 404 458 405 459 // Find the initially selected revision 406 460 var initiallySelectedRevisionIndex = 407 this.model.revisions.indexOf( 461 this.model.revisions.indexOf( 408 462 this.model.revisions.findWhere( { id: Number( revisions.settings.selectedRevision ) } ) ); 409 463 410 464 this.settings = new revisions.model.Slider({ … … 418 472 419 473 ready: function() { 420 474 this.$el.slider( this.settings.toJSON() ); 475 476 // Listen for changes in Compare Two Mode setting 477 this.listenTo( this.model, 'change:compareTwoMode', this.updateSliderSettings ); 478 421 479 this.settings.on( 'change', function( model, options ) { 422 // Apply changes to slider settings here. 423 this.$el.slider( { value: this.model.revisions.indexOf( this.model.get( 'to' ) ) } ); // Set handle to current to model 480 this.updateSliderSettings(); 424 481 }, this ); 425 // Reset to the initially selected revision426 this.slide( '', this.settings.attributes );427 482 428 483 // Listen for changes in the diffId 429 484 this.listenTo( this.model, 'change:diffId', this.diffIdChanged ); 430 485 486 // Reset to the initially selected revision 487 this.slide( '', this.settings.attributes ); 488 489 if ( true === this.model.get( 'compareTwoMode' ) ) 490 $( '.compare-two-revisions' ).trigger( 'click' ); 431 491 }, 432 492 493 updateSliderSettings: function() { 494 if ( isRtl ) { 495 this.$el.slider( { // Order reversed in Rtl mode 496 value: this.model.revisions.length - this.model.revisions.indexOf( this.model.get( 'to' ) ) - 1 497 } ); 498 } else { 499 if ( true === this.model.get( 'compareTwoMode' ) ) { 500 this.$el.slider( { // Set handles to current from/to models 501 values: [ 502 this.model.revisions.indexOf( this.model.get( 'from' ) ), 503 this.model.revisions.indexOf( this.model.get( 'to' ) ) 504 ], 505 value: null, 506 range: true // Range mode ensures handles can't cross 507 } ); 508 } else { 509 this.$el.slider( { // Set handle to current to model 510 value: this.model.revisions.indexOf( this.model.get( 'to' ) ), 511 values: null, // Clear existing two handled values 512 range: false 513 } ); 514 } 515 } 516 if ( true === this.model.get( 'compareTwoMode' ) ){ 517 $( '.revisions' ).addClass( 'comparing-two-revisions' ); 518 // in RTL mode the 'left handle' is the second in the slider, 'right' is first 519 520 $( '.wp-slider a.ui-slider-handle' ) 521 .first() 522 .addClass( isRtl ? 'right-handle' : 'left-handle' ) 523 .removeClass( isRtl ? 'left-handle' : 'right-handle' ); 524 $( '.wp-slider a.ui-slider-handle' ) 525 .last() 526 .addClass( isRtl ? 'left-handle' : 'right-handle' ) 527 .removeClass( isRtl ? 'right-handle' : 'left-handle' ); 528 } else { 529 $( '.revisions' ).removeClass( 'comparing-two-revisions' ); 530 } 531 }, 532 433 533 diffIdChanged: function() { 434 534 // Reset the view settings when diffId is changed 435 this.settings.set( { 'value': this.model.revisions.indexOf( this.model.get( 'to' ) ) } ); 535 if ( true === this.model.get( 'compareTwoMode' ) ) { 536 this.settings.set( { 'values': [ 537 this.model.revisions.indexOf( this.model.get( 'from' ) ), 538 this.model.revisions.indexOf( this.model.get( 'to' ) ) 539 ] } ); 540 } else { 541 this.settings.set( { 'value': this.model.revisions.indexOf( this.model.get( 'to' ) ) } ); 542 } 436 543 }, 437 544 438 545 start: function( event, ui ) { 439 // Track the mouse position to enable smooth dragging, overrides default jquery ui step behaviour 440 $( window ).mousemove( function( e ) { 441 var sliderLeft = $( '.wp-slider' ).offset().left, 442 sliderRight = sliderLeft + $( '.wp-slider' ).width(); 546 if ( true !== this.model.get( 'compareTwoMode' )) { 547 // Track the mouse position to enable smooth dragging, overrides default jquery ui step behaviour . 548 $( window ).mousemove( function( e ) { 549 var sliderLeft = $( '.wp-slider' ).offset().left, 550 sliderRight = sliderLeft + $( '.wp-slider' ).width(); 443 551 444 // Follow mouse movements, as long as handle remains inside slider 445 if ( e.clientX < sliderLeft ) { 446 $( ui.handle ).css( 'left', 0 ); // Mouse to left of slider 447 } else if ( e.clientX > sliderRight ) { 448 $( ui.handle ).css( 'left', sliderRight - sliderLeft); // Mouse to right of slider 449 } else { 450 $( ui.handle ).css( 'left', e.clientX - sliderLeft ); // Mouse in slider 451 } 452 } ); // End mousemove 552 // Follow mouse movements, as long as handle remains inside slider. 553 if ( e.clientX < sliderLeft ) { 554 $( ui.handle ).css( 'left', 0 ); // Mouse to left of slider. 555 } else if ( e.clientX > sliderRight ) { 556 $( ui.handle ).css( 'left', sliderRight - sliderLeft); // Mouse to right of slider. 557 } else { 558 $( ui.handle ).css( 'left', e.clientX - sliderLeft ); // Mouse in slider. 559 } 560 } ); // End mousemove. 561 } 453 562 }, 454 563 564 getSliderPosition: function( ui ){ 565 return isRtl ? this.model.revisions.length - ui.value - 1 : ui.value; 566 }, 567 455 568 slide: function( event, ui ) { 456 var attributes = { 457 to: this.model.revisions.at( isRtl ? this.model.revisions.length - ui.value - 1 : ui.value ) // Reverse directions for Rtl 458 }; 569 var attributes; 570 // Compare two revisions mode 571 if ( 'undefined' !== typeof ui.values && true == this.model.get( 'compareTwoMode' )) { 572 // Prevent sliders from occupying same spot 573 if ( ui.values[1] === ui.values[0] ) 574 return false; 575 attributes = { 576 to: this.model.revisions.at( isRtl ? this.model.revisions.length - ui.values[1] - 1 : ui.values[1] ), // Reverse directions for Rtl. 577 from: this.model.revisions.at( isRtl ? this.model.revisions.length - ui.values[0] - 1 : ui.values[0] ) // Reverse directions for Rtl. 578 }; 459 579 460 // If we're at the first revision, unset 'from'. 461 if ( isRtl ? this.model.revisions.length - ui.value - 1 : ui.value ) // Reverse directions for Rtl 462 attributes.from = this.model.revisions.at( isRtl ? this.model.revisions.length - ui.value - 2 : ui.value - 1 ); 463 else 464 this.model.unset('from', { silent: true }); 580 } else { 581 // Compare single revision mode 582 var sliderPosition = this.getSliderPosition( ui ); 583 attributes = { 584 to: this.model.revisions.at( sliderPosition ) 585 }; 465 586 587 // If we're at the first revision, unset 'from'. 588 if ( sliderPosition ) // Reverse directions for Rtl. 589 attributes.from = this.model.revisions.at( sliderPosition - 1 ); 590 else 591 this.model.unset('from', { silent: true }); 592 593 } 466 594 this.model.set( attributes ); 595 596 // Maintain state history when dragging 597 this.model.revisionsRouter.navigateRoute( attributes.to.id, ( attributes.from ? attributes.from.id : 0 ) ); 598 467 599 }, 468 600 469 601 stop: function( event, ui ) { 470 $( window ).unbind( 'mousemove' ); // Stop tracking the mouse 471 // Reset settings pops handle back to the step position 472 this.settings.trigger( 'change' ); 602 if ( true !== this.model.get( 'compareTwoMode' )) { 603 $( window ).unbind( 'mousemove' ); // Stop tracking the mouse. 604 // Reset settings pops handle back to the step position. 605 this.settings.trigger( 'change' ); 606 } 473 607 } 474 608 }); 475 609 … … 486 620 } 487 621 }); 488 622 623 // The revisions router 624 // takes URLs with #hash fragments and routes them 625 revisions.router.Router = Backbone.Router.extend({ 626 model: null, 627 628 routes: { 629 'revision/from/:from/to/:to/handles/:handles': 'gotoRevisionId' 630 }, 631 632 navigateRoute: function( to, from ) { 633 var navigateTo = '/revision/from/' + from + '/to/' + to + '/handles/'; 634 if ( true === this.model.get( 'compareTwoMode' ) ){ 635 navigateTo = navigateTo + '2'; 636 } else { 637 navigateTo = navigateTo + '1'; 638 } 639 this.navigate( navigateTo ); 640 }, 641 642 gotoRevisionId: function( to, from, handles ) { 643 if ( '2' === handles ) { 644 this.model.set( { compareTwoMode: true } ); 645 $( '.compare-two-revisions' ).attr( 'checked', true ); 646 } else { 647 this.model.set( { compareTwoMode: false } ); 648 $( '.compare-two-revisions' ).attr( 'checked', false ); 649 } 650 if ('undefined' !== typeof this.model ) { 651 var selectedToRevision = 652 this.model.revisions.findWhere( { 'id': Number( to ) } ), 653 selectedFromRevision = 654 this.model.revisions.findWhere( { 'id': Number( from ) } ); 655 656 this.model.set( { 657 to: selectedToRevision, 658 from: selectedFromRevision } ); 659 660 } 661 662 }, 663 664 }); 665 489 666 // Initialize the revisions UI. 490 667 revisions.init = function() { 491 668 revisions.view.frame = new revisions.view.Frame({ 492 669 collection: new revisions.model.Revisions( revisions.settings.revisionData ) 493 670 }).render(); 671 // Only allow compare two mode if three or more revisions 494 672 }; 495 673 496 674 $( revisions.init ); -
wp-admin/css/wp-admin-rtl.css
975 975 left: 6px; 976 976 } 977 977 978 #toggle-revision-compare-mode {978 .revision-toggle-compare-mode { 979 979 right: auto; 980 980 left: 0; 981 981 padding: 9px 0 0 9px; 982 982 } 983 983 984 #diff-next-revision{984 .revisions-next { 985 985 float: left; 986 986 } 987 987 988 #diff-previous-revision{988 .revisions-previous { 989 989 float: right; 990 990 } 991 991 -
wp-admin/css/wp-admin.css
3502 3502 margin-bottom: 10px; 3503 3503 } 3504 3504 3505 .comparing-two-revisions .revisions-controls { 3506 height: 90px; 3507 } 3508 3505 3509 .revisions-meta { 3506 3510 margin-top: 15px; 3507 3511 } … … 3655 3659 margin-top: 20px; 3656 3660 } 3657 3661 3658 .comparing-two-revisions#diff-previous-revision,3659 .comparing-two-revisions#diff-next-revision,3662 #diff-previous-revision, 3663 #diff-next-revision, 3660 3664 #diff-header-from { 3661 3665 display: none; 3662 3666 }