WordPress.org

Make WordPress Core

Changeset 24549


Ignore:
Timestamp:
07/03/2013 08:27:19 PM (8 years ago)
Author:
ocean90
Message:

Revisions UI update:

  • Restore Compare two mode
  • Restore tooltips
  • RTL support
  • First pass for URL routing and history

props adamsilverstein, see #24425.

Location:
trunk/wp-admin
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/css/colors-fresh.css

    r24429 r24549  
    13801380}
    13811381
    1382 #diff-slider .ui-slider-tooltip,
    1383 #diff-slider-ticks .ui-slider-tooltip {
     1382.ui-slider-tooltip,
     1383.ui-slider-tooltip {
    13841384    border-color: #d7d7d7;
    13851385    background-color: #fff;
  • trunk/wp-admin/css/wp-admin-rtl.css

    r24429 r24549  
    976976}
    977977
    978 #toggle-revision-compare-mode {
     978.revision-toggle-compare-mode {
    979979    right: auto;
    980980    left: 0;
     
    982982}
    983983
    984 #diff-next-revision {
    985     float: left;
    986 }
    987 
    988 #diff-previous-revision {
     984.revisions-next {
     985    float: left;
     986}
     987
     988.revisions-previous {
    989989    float: right;
    990990}
  • trunk/wp-admin/css/wp-admin.css

    r24520 r24549  
    34993499    height: 60px;
    35003500    padding: 40px 0 20px;
    3501     border-bottom: 1px solid #dfdfdf;
     3501    border-bottom: none;
    35023502    margin-bottom: 10px;
     3503}
     3504
     3505.comparing-two-revisions .revisions-controls {
     3506    height: 90px;
    35033507}
    35043508
     
    35113515    right: 0;
    35123516}
     3517.comparing-two-revisions .revisions-previous,
     3518.comparing-two-revisions .revisions-next {
     3519    display: none;
     3520}
    35133521
    35143522.revisions-previous {
     
    35333541table.diff {
    35343542    width: 100%;
     3543    white-space: pre-wrap;
    35353544}
    35363545
     
    35913600}
    35923601
    3593 #diff-slider .ui-slider-tooltip,
    3594 #diff-slider-ticks .ui-slider-tooltip {
    3595     display: none;
     3602.revisions .ui-slider-tooltip {
    35963603    position: absolute;
    3597     bottom: 21px;
    3598     margin-left: -74px;
    3599 }
    3600 
    3601 #diff-slider .ui-state-active .ui-slider-tooltip,
    3602 #diff-slider .ui-state-focus .ui-slider-tooltip,
    3603 #diff-slider .ui-state-hover .ui-slider-tooltip {
    3604     display: block;
     3604    bottom: 86px;
     3605    margin-left: -70px;
     3606    line-height: 28px;
    36053607}
    36063608
     
    36563658}
    36573659
    3658 .comparing-two-revisions #diff-previous-revision,
    3659 .comparing-two-revisions #diff-next-revision,
     3660#diff-previous-revision,
     3661#diff-next-revision,
    36603662#diff-header-from {
    36613663    display: none;
     
    36693671}
    36703672
     3673.comparing-two-revisions .revisions-tooltip div {
     3674    margin-bottom: 30px;
     3675}
    36713676.diff-slider-ticks-wrapper {
    36723677    margin: 0 auto;
     
    37413746    float: left;
    37423747    margin-right: 5px;
    3743     margin-top: 5px;
     3748    margin-top: 2px;
     3749    padding: 0;
     3750    vertical-align: middle;
    37443751}
    37453752
     
    37493756.ui-tooltip,
    37503757.ui-slider-tooltip {
    3751     padding: 8px;
     3758    padding: 4px;
    37523759    position: absolute;
    37533760    z-index: 9999;
     
    37693776.ui-tooltip,
    37703777.ui-slider-tooltip {
    3771     padding: 5px 10px;
     3778    padding: 4px 4px;
     3779}
     3780
     3781.revisions-tooltip {
     3782    display: none;
    37723783}
    37733784
     
    37773788    overflow: hidden;
    37783789    position: absolute;
    3779     left: 50%;
     3790    left: 0;
    37803791    margin-left: -35px;
    3781     bottom: -16px;
    3782     z-index: 99999;
     3792    bottom: 71px;
     3793    z-index: 10000;
    37833794}
    37843795
     
    38723883.wp-slider.ui-slider-horizontal {
    38733884    height: .8em;
     3885    z-index: 10001;
    38743886}
    38753887
  • trunk/wp-admin/js/revisions.js

    r24520 r24549  
    44    var revisions;
    55
    6     revisions = wp.revisions = { model: {}, view: {}, controller: {} };
     6    revisions = wp.revisions = { model: {}, view: {}, controller: {}, router: {} };
    77
    88    // Link settings.
     
    3131        comparator: function( revision ) {
    3232            return revision.id;
    33         },
     33        }
    3434    });
    3535
     
    102102        },
    103103
    104 /**/
    105104        loadLast: function( num ) {
    106105            num     = num || 1;
     
    195194            this.revisions = options.revisions;
    196195            this.diffs     = new revisions.model.Diffs( [], {revisions: this.revisions} );
    197 
    198             this.listenTo( this, 'change:from change:to', this.updateDiffId );
    199         },
    200 
    201         updateDiffId: function() {
     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;
     200        },
     201
     202        updateDiffTo: function() {
    202203            var from = this.get( 'from' );
    203204            var to   = this.get( 'to' );
    204             this.set( 'diffId', (from ? from.id : '0') + ':' + to.id );
     205            this.set( 'diffId', (from ? from.id : '0' ) + ':' + to.id );
     206        },
     207
     208        updateDiffFrom: function() {
     209            if ( this.get( 'compareTwoMode' ) )
     210                this.updateDiffTo();
    205211        }
    206212    });
     
    244250                }, this ) );
    245251            }
     252            Backbone.history.start();
    246253        },
    247254
     
    267274
    268275    // The control view.
    269     // This contains the revision slider, previous/next buttons, and the compare checkbox.
     276    // This contains the revision slider, previous/next buttons, the meta info and the compare checkbox.
    270277    revisions.view.Controls = wp.Backbone.View.extend({
    271278        tagName: 'div',
     
    274281        initialize: function() {
    275282            // Add the button view
    276             this.views.add( new revisions.view.Buttons({ 
     283            this.views.add( new revisions.view.Buttons({
    277284                model: this.model
    278285            }));
    279286
     287            // Add the checkbox view
     288            this.views.add( new revisions.view.Checkbox({
     289                model: this.model
     290            }));
     291
     292            // Add the tooltip view
     293            this.views.add( new revisions.view.Tooltip({
     294                model: this.model
     295            }));
    280296            // Add the Slider view
    281297            this.views.add( new revisions.view.Slider({
     
    297313        template: wp.template('revisions-meta'),
    298314
     315        events: {
     316            'click #restore-revision': 'restoreRevision'
     317        },
     318
    299319        initialize: function() {
    300320            this.listenTo( this.model, 'change:diffId', this.updateMeta );
    301         },
    302 
    303         events: {
    304             'click #restore-revision': 'restoreRevision'
    305321        },
    306322
     
    313329            this.$el.html( this.template( this.model.toJSON() ) );
    314330            if( this.model.get( 'to' ).attributes.current ) {
    315                 $( '#restore-revision' ).prop( 'disabled', true);
    316             } else {
    317                 $( '#restore-revision' ).prop( 'disabled', false)
    318             }
    319         }
    320     });
    321 
     331                $( '#restore-revision' ).prop( 'disabled', true );
     332            } else {
     333                $( '#restore-revision' ).prop( 'disabled', false );
     334            }
     335        }
     336    });
     337
     338    // The checkbox view.
     339    // Encapsulates all of the configuration for the compare checkbox.
     340    revisions.view.Checkbox = wp.Backbone.View.extend({
     341        tagName: 'div',
     342        className: 'revisions-checkbox',
     343        template: wp.template( 'revisions-checkbox' ),
     344
     345        events: {
     346            'click .compare-two-revisions': 'compareTwoToggle'
     347        },
     348
     349        initialize: function() {
     350            this.$el.html( this.template() );
     351            this.listenTo( this.model, 'change:compareTwoMode', this.updateCompareTwoMode );
     352        },
     353
     354        updateCompareTwoMode: function() {
     355            if ( this.model.get( 'compareTwoMode' ) ) {
     356                $( '.compare-two-revisions' ).parent().css('border', '1px solid #f00;').prop( 'checked', true );
     357                $( '.revisions-control-frame' ).addClass( 'comparing-two-revisions' );
     358                // in RTL mode the 'left handle' is the second in the slider, 'right' is first
     359                $( '.wp-slider a.ui-slider-handle' ).first().addClass( isRtl ? 'right-handle' : 'left-handle' );
     360                $( '.wp-slider a.ui-slider-handle' ).last().addClass( isRtl ? 'left-handle' : 'right-handle' );
     361            } else {
     362                $( '.compare-two-revisions' ).prop( 'checked', false );
     363                $( '.revisions-control-frame' ).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
     378            // Update route
     379            this.model.revisionsRouter.navigateRoute( this.model.get( 'to').id, this.model.get( 'from' ).id );
     380        },
     381
     382        ready: function() {
     383            // Hide compare two mode toggle when fewer than three revisions.
     384            if ( this.model.revisions.length < 3 )
     385                $( '.revision-toggle-compare-mode' ).hide();
     386        }
     387
     388    });
     389
     390    // The tooltip view.
     391    // Encapsulates the tooltip.
     392    revisions.view.Tooltip = wp.Backbone.View.extend({
     393        tagName: 'div',
     394        className: 'revisions-tooltip',
     395        template: wp.template( 'revisions-tooltip' ),
     396
     397        initialize: function() {
     398            this.listenTo( this.model, 'change:sliderHovering', this.sliderHoveringChanged );
     399            this.listenTo( this.model, 'change:tooltipPosition', this.tooltipPositionChanged );
     400        },
     401
     402        ready: function() {
     403        },
     404
     405        // Show or hide tooltip based on sliderHovering is true
     406        sliderHoveringChanged: function() {
     407            if ( this.model.get( 'sliderHovering' ) ) {
     408                this.$el.show();
     409            } else {
     410                this.$el.hide();
     411            }
     412        },
     413
     414        tooltipPositionChanged: function() {
     415            this.$el.html( this.template( this.model.revisions.at( this.model.get( 'hoveringAt') ).toJSON() ) );
     416
     417            this.setTooltip( this.model.get( 'tooltipPosition' ) );
     418        },
     419
     420        setTooltip: function( tooltipPosition ) {
     421            var offset = $( '.revisions-buttons' ).offset().left,
     422                calculatedX = tooltipPosition - offset;
     423
     424
     425            this.$el.find( '.ui-slider-tooltip' ).css( 'left', calculatedX );
     426            this.$el.find( '.arrow' ).css( 'left', calculatedX );
     427        }
     428    });
    322429
    323430    // The buttons view.
    324     // Encapsulates all of the configuration for the previous/next buttons, and the compare checkbox.
     431    // Encapsulates all of the configuration for the previous/next buttons.
    325432    revisions.view.Buttons = wp.Backbone.View.extend({
    326433        tagName: 'div',
    327434        className: 'revisions-buttons',
    328         template: wp.template('revisions-controls'),
    329 
    330         initialize: function() {
    331             this.$el.html( this.template() )
    332         },
     435        template: wp.template( 'revisions-buttons' ),
    333436
    334437        events: {
     
    336439            'click #previous': 'previousRevision'
    337440        },
    338        
     441
     442        initialize: function() {
     443            this.$el.html( this.template() );
     444        },
     445
     446        ready: function() {
     447            this.listenTo( this.model, 'change:diffId', this.disabledButtonCheck );
     448        },
     449
     450        // Go to a specific modelindex, taking into account RTL mode.
    339451        gotoModel: function( toIndex ) {
    340452            var attributes = {
    341                 to: this.model.revisions.at( isRtl ? this.model.revisions.length - toIndex - 1 : toIndex ) // Reverse directions for Rtl
     453                to: this.model.revisions.at( isRtl ? this.model.revisions.length - toIndex - 1 : toIndex ) // Reverse directions for RTL.
    342454            };
    343455            // If we're at the first revision, unset 'from'.
    344             if ( isRtl ? this.model.revisions.length - toIndex - 1 : toIndex ) // Reverse directions for Rtl
     456            if ( isRtl ? this.model.revisions.length - toIndex - 1 : toIndex ) // Reverse directions for RTL
    345457                attributes.from = this.model.revisions.at( isRtl ? this.model.revisions.length - toIndex - 2 : toIndex - 1 );
    346458            else
     
    348460
    349461            this.model.set( attributes );
    350         },
    351 
     462
     463            // Update route
     464            this.model.revisionsRouter.navigateRoute( attributes.to.id, attributes.from ? attributes.from.id : 0 );
     465        },
     466
     467        // Go to the 'next' revision, direction takes into account RTL mode.
    352468        nextRevision: function() {
    353             var toIndex = this.model.revisions.indexOf( this.model.get( 'to' ) );
     469            var toIndex = isRtl ? this.model.revisions.length - this.model.revisions.indexOf( this.model.get( 'to' ) ) - 1 : this.model.revisions.indexOf( this.model.get( 'to' ) );
    354470            toIndex     = isRtl ? toIndex - 1 : toIndex + 1;
    355471            this.gotoModel( toIndex );
    356472        },
    357        
     473
     474        // Go to the 'previous' revision, direction takes into account RTL mode.
    358475        previousRevision: function() {
    359             var toIndex = this.model.revisions.indexOf( this.model.get('to') );
     476            var toIndex = isRtl ? this.model.revisions.length - this.model.revisions.indexOf( this.model.get( 'to' ) ) - 1 : this.model.revisions.indexOf( this.model.get( 'to' ) );
    360477            toIndex     = isRtl ? toIndex + 1 : toIndex - 1;
    361478            this.gotoModel( toIndex );
    362479        },
    363480
    364         ready: function() {
    365             this.listenTo( this.model, 'change:diffId', this.disabledButtonCheck );
    366         },
    367 
    368         // Check to see if the Previous or Next buttons need to be disabled or enabled
     481        // Check to see if the Previous or Next buttons need to be disabled or enabled.
    369482        disabledButtonCheck: function() {
    370             var maxVal   = isRtl ? 0 : this.model.revisions.length - 1,
    371                 minVal   = isRtl ? this.model.revisions.length - 1 : 0,
    372                 next     = $( '.revisions-next .button' ),
     483            var maxVal = this.model.revisions.length - 1,
     484                minVal = 0,
     485                next = $( '.revisions-next .button' ),
    373486                previous = $( '.revisions-previous .button' ),
    374                 val      = this.model.revisions.indexOf( this.model.get( 'to' ) );
    375 
    376             // Disable "Next" button if you're on the last node
     487                val = this.model.revisions.indexOf( this.model.get( 'to' ) );
     488
     489            // Disable "Next" button if you're on the last node.
    377490            if ( maxVal === val )
    378491                next.prop( 'disabled', true );
     
    380493                next.prop( 'disabled', false );
    381494
    382             // Disable "Previous" button if you're on the first node
     495            // Disable "Previous" button if you're on the first node.
    383496            if ( minVal === val )
    384497                previous.prop( 'disabled', true );
    385498            else
    386499                previous.prop( 'disabled', false );
    387         },
    388 
    389 
    390     });
     500        }
     501    });
     502
    391503
    392504    // The slider view.
     
    396508        className: 'wp-slider',
    397509
     510        events: {
     511            'mousemove'  : 'mousemove',
     512            'mouseenter' : 'mouseenter',
     513            'mouseleave' : 'mouseleave'
     514        },
     515
    398516        initialize: function() {
    399517            _.bindAll( this, 'start', 'slide', 'stop' );
    400518
    401519            // Create the slider model from the provided collection data.
    402             // TODO: This should actually pull from the model's `to` key.
    403520            var latestRevisionIndex = this.model.revisions.length - 1;
    404521
    405522            // Find the initially selected revision
    406523            var initiallySelectedRevisionIndex =
    407                 this.model.revisions.indexOf( 
     524                this.model.revisions.indexOf(
    408525                    this.model.revisions.findWhere(  { id: Number( revisions.settings.selectedRevision ) } ) );
    409526
     
    419536        ready: function() {
    420537            this.$el.slider( this.settings.toJSON() );
     538
     539            // Listen for changes in Compare Two Mode setting
     540            this.listenTo( this.model, 'change:compareTwoMode', this.updateSliderSettings );
     541
    421542            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
     543                this.updateSliderSettings();
    424544            }, this );
     545
     546            // Listen for changes in the diffId
     547            this.listenTo( this.model, 'change:diffId', this.diffIdChanged );
     548
    425549            // Reset to the initially selected revision
    426550            this.slide( '', this.settings.attributes );
    427551
    428             // Listen for changes in the diffId
    429             this.listenTo( this.model, 'change:diffId', this.diffIdChanged );
    430 
     552        },
     553
     554        mousemove: function( e ) {
     555            var sliderLeft = Math.ceil( this.$el.offset().left ),
     556                sliderWidth = Math.ceil( this.$el.width() ) + 2,
     557                tickWidth = Math.ceil( ( sliderWidth ) / this.model.revisions.length ),
     558                actualX = e.clientX - sliderLeft,
     559                hoveringAt = Math.floor( actualX / tickWidth );
     560
     561                // Reverse direction in Rtl mode.
     562                if ( isRtl )
     563                    hoveringAt = this.model.revisions.length - hoveringAt - 1;
     564
     565            // Ensure sane value for hoveringAt.
     566            if ( hoveringAt < 0 )
     567                hoveringAt = 0;
     568            else if ( hoveringAt >= this.model.revisions.length )
     569                hoveringAt = this.model.revisions.length - 1;
     570
     571            // Update the model
     572            this.model.set( 'hoveringAt', hoveringAt );
     573            this.model.set( 'tooltipPosition', e.clientX );
     574
     575        },
     576
     577        mouseenter: function( e ) {
     578            this.model.set( 'sliderHovering', true );
     579        },
     580
     581        mouseleave: function( e ) {
     582            this.model.set( 'sliderHovering', false );
     583        },
     584
     585        updateSliderSettings: function() {
     586            if ( isRtl ) {
     587                this.$el.slider( { // Order reversed in RTL mode
     588                    value: this.model.revisions.length - this.model.revisions.indexOf( this.model.get( 'to' ) ) - 1
     589                } );
     590            } else {
     591                if ( this.model.get( 'compareTwoMode' ) ) {
     592                    this.$el.slider( { // Set handles to current from/to models
     593                        values: [
     594                            this.model.revisions.indexOf( this.model.get( 'from' ) ),
     595                            this.model.revisions.indexOf( this.model.get( 'to' ) )
     596                                ],
     597                        value: null,
     598                        range: true // Range mode ensures handles can't cross
     599                    } );
     600                } else {
     601                    this.$el.slider( { // Set handle to current to model
     602                        value: this.model.revisions.indexOf( this.model.get( 'to' ) ),
     603                        values: null, // Clear existing two handled values
     604                        range: false
     605                    } );
     606                }
     607            }
     608            if ( this.model.get( 'compareTwoMode' ) ){
     609                $( '.revisions' ).addClass( 'comparing-two-revisions' );
     610
     611                // in RTL mode the 'left handle' is the second in the slider, 'right' is first
     612                $( 'a.ui-slider-handle', this.$el )
     613                    .first()
     614                    .addClass( isRtl ? 'right-handle' : 'left-handle' )
     615                    .removeClass( isRtl ? 'left-handle' : 'right-handle' );
     616                $( 'a.ui-slider-handle', this.$el )
     617                    .last()
     618                    .addClass( isRtl ? 'left-handle' : 'right-handle' )
     619                    .removeClass( isRtl ? 'right-handle' : 'left-handle' );
     620            } else {
     621                $( '.revisions' ).removeClass( 'comparing-two-revisions' );
     622            }
    431623        },
    432624
    433625        diffIdChanged: function() {
    434626            // Reset the view settings when diffId is changed
    435             this.settings.set( { 'value': this.model.revisions.indexOf( this.model.get( 'to' ) ) } );
     627            if ( this.model.get( 'compareTwoMode' ) ) {
     628                this.settings.set( { 'values': [
     629                        this.model.revisions.indexOf( this.model.get( 'from' ) ),
     630                        this.model.revisions.indexOf( this.model.get( 'to' ) )
     631                    ] } );
     632            } else {
     633                this.settings.set( { 'value': this.model.revisions.indexOf( this.model.get( 'to' ) ) } );
     634            }
     635        },
     636
     637        getSliderPosition: function( ui ){
     638            return isRtl ? this.model.revisions.length - ui.value - 1 : ui.value;
    436639        },
    437640
    438641        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();
    443 
    444                 // Follow mouse movements, as long as handle remains inside slider
     642            if ( ! this.model.get( 'compareTwoMode' ) )
     643                return;
     644
     645            // Track the mouse position to enable smooth dragging, overrides default jquery ui step behaviour .
     646            $( window ).mousemove( function( e ) {
     647                var sliderLeft = this.$el.offset().left,
     648                    sliderRight = sliderLeft + this.$el.width();
     649
     650                // Follow mouse movements, as long as handle remains inside slider.
    445651                if ( e.clientX < sliderLeft ) {
    446                     $( ui.handle ).css( 'left', 0 ); // Mouse to left of slider
     652                    $( ui.handle ).css( 'left', 0 ); // Mouse to left of slider.
    447653                } else if ( e.clientX > sliderRight ) {
    448                     $( ui.handle ).css( 'left', sliderRight - sliderLeft); // Mouse to right of slider
     654                    $( ui.handle ).css( 'left', sliderRight - sliderLeft); // Mouse to right of slider.
    449655                } else {
    450                     $( ui.handle ).css( 'left', e.clientX - sliderLeft ); // Mouse in slider
     656                    $( ui.handle ).css( 'left', e.clientX - sliderLeft ); // Mouse in slider.
    451657                }
    452             } ); // End mousemove 
     658            } ); // End mousemove.
    453659        },
    454660
    455661        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             };
    459 
    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 });
    465 
     662            var attributes;
     663            // Compare two revisions mode
     664            if ( 'undefined' !== typeof ui.values && this.model.get( 'compareTwoMode' ) ) {
     665                // Prevent sliders from occupying same spot
     666                if ( ui.values[1] === ui.values[0] )
     667                    return false;
     668
     669                attributes = {
     670                    to: this.model.revisions.at( isRtl ? this.model.revisions.length - ui.values[1] - 1 : ui.values[1] ), // Reverse directions for RTL.
     671                    from: this.model.revisions.at( isRtl ? this.model.revisions.length - ui.values[0] - 1 : ui.values[0] ) // Reverse directions for RTL.
     672                };
     673            } else {
     674                // Compare single revision mode
     675                var sliderPosition = this.getSliderPosition( ui );
     676                attributes = {
     677                    to: this.model.revisions.at( sliderPosition )
     678                };
     679
     680                // If we're at the first revision, unset 'from'.
     681                if ( sliderPosition ) // Reverse directions for RTL.
     682                    attributes.from = this.model.revisions.at( sliderPosition - 1  );
     683                else
     684                    this.model.unset('from', { silent: true });
     685            }
    466686            this.model.set( attributes );
     687
     688            // Maintain state history when dragging
     689            this.model.revisionsRouter.navigateRoute( attributes.to.id, ( attributes.from ? attributes.from.id : 0 ) );
    467690        },
    468691
    469692        stop: function( event, ui ) {
    470             $( window ).unbind( 'mousemove' ); // Stop tracking the mouse
    471             // Reset settings pops handle back to the step position
     693            if ( ! this.model.get( 'compareTwoMode' ) )
     694                return;
     695
     696            // Stop tracking the mouse.
     697            $( window ).unbind( 'mousemove' );
     698
     699            // Reset settings pops handle back to the step position.
    472700            this.settings.trigger( 'change' );
    473701        }
     
    487715    });
    488716
     717    // The revisions router
     718    // takes URLs with #hash fragments and routes them
     719    revisions.router.Router = Backbone.Router.extend({
     720        model: null,
     721
     722        routes: {
     723            'revision/from/:from/to/:to/handles/:handles': 'gotoRevisionId'
     724        },
     725
     726        navigateRoute: function( to, from ) {
     727            var navigateTo = '/revision/from/' + from + '/to/' + to + '/handles/';
     728            if ( this.model.get( 'compareTwoMode' ) ){
     729                navigateTo = navigateTo + '2';
     730            } else {
     731                navigateTo = navigateTo + '1';
     732            }
     733            this.navigate( navigateTo );
     734        },
     735
     736        gotoRevisionId: function( from, to, handles ) {
     737            if ( '2' === handles ) {
     738                this.model.set( { compareTwoMode: true } );
     739            } else {
     740                this.model.set( { compareTwoMode: false } );
     741            }
     742
     743            if ( 'undefined' !== typeof this.model ) {
     744                var selectedToRevision =
     745                    this.model.revisions.findWhere( { 'id': Number( to ) } ),
     746                    selectedFromRevision =
     747                    this.model.revisions.findWhere( { 'id': Number( from ) } );
     748
     749                this.model.set( {
     750                    to:   selectedToRevision,
     751                    from: selectedFromRevision } );
     752            }
     753        }
     754    });
     755
    489756    // Initialize the revisions UI.
    490757    revisions.init = function() {
  • trunk/wp-admin/revision.php

    r24520 r24549  
    116116
    117117<script id="tmpl-revisions-frame" type="text/html">
    118     <span class="spinner"></span>
    119118    <div class="revisions-control-frame"></div>
    120119    <div class="revisions-diff-frame"></div>
    121120</script>
    122121
    123 <script id="tmpl-revisions-controls" type="text/html">
    124 
    125     <div class="revision-toggle-compare-mode">
    126         <label>
    127             <input type="checkbox" class="compare-two-revisions" />
    128             <?php esc_attr_e( 'Compare two revisions' ); ?>
    129         </label>
    130     </div>
    131 
     122<script id="tmpl-revisions-buttons" type="text/html">
    132123    <div class="revisions-previous">
    133124        <input class="button" type="button" id="previous" value="<?php echo esc_attr_x( 'Previous', 'Button label for a previous revision' ); ?>" />
     
    139130</script>
    140131
     132<script id="tmpl-revisions-tooltip" type="text/html">
     133    <div class="ui-slider-tooltip ui-widget-content ui-corner-all ">
     134    <# if ( 'undefined' !== typeof data && 'undefined' !== typeof data.author ) { #>
     135            {{{ data.author.avatar }}} {{{ data.author.name }}},
     136            {{{ data.timeAgo }}} <?php _e( 'ago' ); ?>
     137            ({{{ data.dateShort }}})
     138    <# } #>
     139    </div>
     140    <div class="arrow"></div>
     141</script>
     142
     143<script id="tmpl-revisions-checkbox" type="text/html">
     144    <div class="revision-toggle-compare-mode">
     145        <label>
     146            <input type="checkbox" class="compare-two-revisions"
     147            <#
     148            if ( 'undefined' !== typeof data && data.model.attributes.compareTwoMode ) {
     149                #> checked="checked"<#
     150            }
     151            #>
     152            />
     153            <?php esc_attr_e( 'Compare two revisions' ); ?>
     154        </label>
     155    </div>
     156</script>
    141157
    142158<script id="tmpl-revisions-meta" type="text/html">
     
    144160        <div id="diff-header-from" class="diff-header">
    145161            <div id="diff-title-from" class="diff-title">
    146                 <strong>
    147                 <?php _ex( 'From:', 'Followed by post revision info' ); ?></strong>
    148                     <# if ( 'undefined' !== typeof data.from ) { #>
    149                         {{{ data.from.attributes.author.avatar }}} {{{ data.from.attributes.author.name }}},
    150                         {{{ data.from.attributes.timeAgo }}} <?php _e( 'ago' ); ?>
    151                         ({{{ data.from.attributes.dateShort }}})
    152                     <# } #>
    153 
     162                <strong><?php _ex( 'From:', 'Followed by post revision info' ); ?></strong>
     163                <# if ( 'undefined' !== typeof data.from ) { #>
     164                    {{{ data.from.attributes.author.avatar }}} {{{ data.from.attributes.author.name }}},
     165                    {{{ data.from.attributes.timeAgo }}} <?php _e( 'ago' ); ?>
     166                    ({{{ data.from.attributes.dateShort }}})
     167                <# } #>
    154168            </div>
    155169            <div class="clear"></div>
     
    159173            <div id="diff-title-to" class="diff-title">
    160174                <strong><?php _ex( 'To:', 'Followed by post revision info' ); ?></strong>
    161                     <# if ( 'undefined' !== typeof data.to ) { #>
    162                         {{{ data.to.attributes.author.avatar }}} {{{ data.to.attributes.author.name }}},
    163                         {{{ data.to.attributes.timeAgo }}} <?php _e( 'ago' ); ?>
    164                         ({{{ data.to.attributes.dateShort }}})
    165                     <# } #>
    166         </div>
     175                <# if ( 'undefined' !== typeof data.to ) { #>
     176                    {{{ data.to.attributes.author.avatar }}} {{{ data.to.attributes.author.name }}},
     177                    {{{ data.to.attributes.timeAgo }}} <?php _e( 'ago' ); ?>
     178                    ({{{ data.to.attributes.dateShort }}})
     179                <# } #>
     180            </div>
    167181
    168182            <input type="button" id="restore-revision" class="button button-primary" data-restore-link="{{{ data.restoreLink }}}" value="<?php esc_attr_e( 'Restore This Revision' )?>" />
     
    178192</script>
    179193
    180 <script id="tmpl-revisions-diff-old" type="text/html">
    181     <div id="toggle-revision-compare-mode">
    182         <label>
    183             <input type="checkbox" id="compare-two-revisions" />
    184             <?php esc_attr_e( 'Compare two revisions' ); ?>
    185         </label>
    186     </div>
    187194
    188     <div id="diff-header">
    189         <div id="diff-header-from" class="diff-header">
    190             <div id="diff-title-from" class="diff-title">
    191                 <strong><?php _ex( 'From:', 'Followed by post revision info' ); ?></strong> {{{ data.titleFrom }}}
    192             </div>
    193             <div class="clear"></div>
    194         </div>
    195 
    196         <div id="diff-header-to" class="diff-header">
    197             <div id="diff-title-to" class="diff-title">
    198                 <strong><?php _ex( 'To:', 'Followed by post revision info' ); ?></strong> {{{ data.titleTo }}}
    199             </div>
    200 
    201             <input type="button" id="restore-revision" class="button button-primary" data-restore-link="{{{ data.restoreLink }}}" value="<?php esc_attr_e( 'Restore This Revision' )?>" />
    202             <div class="clear"></div>
    203         </div>
    204     </div>
    205 
    206     <div id="diff-table">{{{ data.diff }}}</div>
    207 </script>
    208 
    209 <script id="tmpl-revision-interact-old" type="text/html">
    210     <div id="diff-previous-revision">
    211         <input class="button" type="button" id="previous" value="<?php echo esc_attr_x( 'Previous', 'Button label for a previous revision' ); ?>" />
    212     </div>
    213 
    214     <div id="diff-next-revision">
    215         <input class="button" type="button" id="next" value="<?php echo esc_attr_x( 'Next', 'Button label for a next revision' ); ?>" />
    216     </div>
    217 
    218 </script>
    219 
    220 <script id="tmpl-revision-ticks" type="text/html">
    221     <div class="revision-tick completed-{{{ data.completed }}} scope-of-changes-{{{ data.scopeOfChanges }}}">
    222         <span class="ui-slider-tooltip ui-widget-content ui-corner-all hidden"></span>
    223     </div>
    224 </script>
    225195<?php
    226196require_once( './admin-footer.php' );
Note: See TracChangeset for help on using the changeset viewer.