WordPress.org

Make WordPress Core

Ticket #34391: 34391_1.patch

File 34391_1.patch, 103.2 KB (added by delawski, 3 years ago)
  • src/wp-admin/css/customize-controls.css

    From 21273f97bb893e32c232681f717e6d6c12737cbe Mon Sep 17 00:00:00 2001
    From: Piotr Delawski <piotr.delawski@xwp.co>
    Date: Sat, 6 Feb 2016 16:02:02 +0100
    Subject: [PATCH 1/9] Tac-34391 - Under development, so far a dirty solution
    
    ---
     src/wp-admin/css/customize-controls.css | 109 +++++++++++--
     src/wp-admin/customize.php              |   2 +-
     src/wp-admin/js/customize-controls.js   | 263 ++++++++++++++++++++++----------
     3 files changed, 277 insertions(+), 97 deletions(-)
    
    diff --git a/src/wp-admin/css/customize-controls.css b/src/wp-admin/css/customize-controls.css
    index ced9735..db7e561 100644
    a b body { 
    217217        box-sizing: border-box;
    218218}
    219219
     220
     221
     222
     223#customize-info,
     224#customize-theme-controls .customize-pane-parent,
     225#customize-theme-controls .customize-pane-child {
     226        width: 100%;
     227        margin: 0;
     228        padding: 0;
     229        -webkit-box-sizing: border-box;
     230        -moz-box-sizing: border-box;
     231        box-sizing: border-box;
     232
     233        transition: 0.36s transform cubic-bezier(0.19, 1, 0.22, 1);
     234        /*visibility: visible !important;*/
     235        overflow: visible !important;
     236}
     237
     238#customize-info,
     239#customize-theme-controls .customize-pane-parent {
     240        position: relative;
     241        visibility: visible;
     242        transform: translateX(0);
     243}
     244
     245.section-open #customize-theme-controls .customize-pane-parent,
     246.in-sub-panel #customize-theme-controls .customize-pane-parent,
     247.section-open #customize-info,
     248.in-sub-panel #customize-info,
     249.in-sub-panel.section-open #customize-theme-controls .customize-pane-child.current-panel {
     250        transform: translateX(-100%);
     251        /*visibility: hidden;*/
     252}
     253
     254.section-open #customize-theme-controls .customize-pane-parent,
     255.in-sub-panel #customize-theme-controls .customize-pane-parent,
     256.section-open #customize-info,
     257.in-sub-panel #customize-info,
     258.animating.section-open.in-sub-panel #customize-theme-controls .customize-pane-parent,
     259.animating.section-open.in-sub-panel #customize-info, {
     260        visibility: hidden;
     261}
     262
     263.animating.section-open #customize-theme-controls .customize-pane-parent,
     264.animating.in-sub-panel #customize-theme-controls .customize-pane-parent,
     265.animating.section-open #customize-info,
     266.animating.in-sub-panel #customize-info {
     267        visibility: visible;
     268}
     269
     270#customize-theme-controls .customize-pane-child {
     271        position: absolute;
     272        top: 0;
     273        left: 0;
     274        transform: translateX(100%);
     275        visibility: hidden;
     276}
     277
     278#customize-theme-controls .customize-pane-child.accordion-section-content,
     279#customize-theme-controls .customize-pane-child.accordion-sub-container {
     280        display: block;
     281}
     282
     283#customize-theme-controls .customize-pane-child.accordion-section-content {
     284        padding: 12px;
     285}
     286
     287#customize-theme-controls .customize-pane-child.open,
     288#customize-theme-controls .customize-pane-child.current-panel {
     289        transform: translateX(0);
     290}
     291
     292#customize-theme-controls .customize-pane-child.open,
     293#customize-theme-controls .customize-pane-child.current-panel,
     294#customize-theme-controls .customize-pane-child.animating {
     295        visibility: visible;
     296}
     297
     298
     299
     300
    220301.customize-section-description-container {
    221302        margin-bottom: 15px;
    222303}
    h3.customize-section-title { 
    256337        color: #555;
    257338}
    258339
    259 #customize-theme-controls {
     340/*#customize-theme-controls {
    260341        position: relative;
    261342        left: 0;
    262343        -webkit-transition: .18s left ease-in-out;
    263344        transition: .18s left ease-in-out;
    264 }
     345}*/
    265346
    266 .ios #customize-theme-controls {
     347/*.ios #customize-theme-controls {
    267348        -webkit-transition: left 0s;
    268349        transition: left 0s;
    269 }
     350}*/
    270351
    271 .section-open #customize-info,
     352/*.section-open #customize-info,
    272353.section-open #customize-theme-controls {
    273354        left: -100%;
    274 }
     355}*/
    275356
    276357.accordion-sub-container.control-panel-content {
    277358        display: none;
    h3.customize-section-title { 
    410491        padding-left: 62px;
    411492}
    412493
    413 #customize-info,
     494/*#customize-info,
    414495#customize-theme-controls > ul > .accordion-section {
    415496        position: relative;
    416497        left: 0;
    h3.customize-section-title { 
    423504        -webkit-transition: left 0s;
    424505        transition: left 0s;
    425506}
    426 
    427 .in-sub-panel #customize-info,
     507*/
     508/*.in-sub-panel #customize-info,
    428509.in-sub-panel #customize-theme-controls > ul > .accordion-section {
    429510        left: -300px;
    430511        width: 300px;
    431 }
     512}*/
    432513
    433 .in-sub-panel #customize-theme-controls .accordion-section.current-panel {
     514/*.in-sub-panel #customize-theme-controls .accordion-section.current-panel {
    434515        width: 100%;
    435516}
    436 
     517*/
    437518#customize-theme-controls .control-section.current-panel {
    438519        padding: 0;
    439520}
    h3.customize-section-title { 
    459540        overflow-y: hidden;
    460541}
    461542
    462 .wp-full-overlay.section-open .wp-full-overlay-sidebar-content .accordion-section.open {
     543/*.wp-full-overlay.section-open .wp-full-overlay-sidebar-content .accordion-section.open {
    463544        visibility: visible;
    464545}
    465546
    466547.wp-full-overlay.section-open .wp-full-overlay-sidebar-content .accordion-section.open .accordion-section-content {
    467548        overflow-y: auto;
    468 }
     549}*/
    469550
    470551p.customize-section-description {
    471552        font-style: normal;
  • src/wp-admin/customize.php

    diff --git a/src/wp-admin/customize.php b/src/wp-admin/customize.php
    index aa949e5..39b35f3 100644
    a b  
    142142                        </div>
    143143
    144144                        <div id="customize-theme-controls">
    145                                 <ul><?php // Panels and sections are managed here via JavaScript ?></ul>
     145                                <ul class="customize-pane-parent"><?php // Panels and sections are managed here via JavaScript ?></ul>
    146146                        </div>
    147147                </div>
    148148                </div>
  • src/wp-admin/js/customize-controls.js

    diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js
    index e78d2c9..19f508d 100644
    a b  
    163163        };
    164164
    165165        /**
     166         * Return browser supported `transitionend` event name
     167         *
     168         * @since
     169         *
     170         * @returns {String}
     171         */
     172        api.utils.getNormalizedTransitionendEvent = function () {
     173                var t,
     174                        undefined,
     175                        el = document.createElement( 'div' ),
     176                        transitions = {
     177                                'transition'      : 'transitionend',
     178                                'OTransition'     : 'oTransitionEnd',
     179                                'MozTransition'   : 'transitionend',
     180                                'WebkitTransition': 'webkitTransitionEnd'
     181                        };
     182
     183                for ( t in transitions ) {
     184                        if ( transitions.hasOwnProperty( t ) && undefined !== el.style[ t ] ) {
     185                                return transitions[t];
     186                        }
     187                }
     188        };
     189
     190        /**
    166191         * Base class for Panel and Section.
    167192         *
    168193         * @since 4.1.0
     
    214239                                container.container = $( container.getContainer() );
    215240                        }
    216241
     242                        container.content = container.getContent();
     243
    217244                        container.deferred = {
    218245                                embedded: new $.Deferred()
    219246                        };
     
    481508                        }
    482509
    483510                        return '<li></li>';
     511                },
     512
     513                getContent: function () {
     514                        var container = this,
     515                                list = container.container.find( 'ul:first' ),
     516                                contentId = 'sub-accordion-list-' + container.id;
     517
     518                        container.setOwnership( contentId );
     519
     520                        return list.detach().attr( {
     521                                id: contentId,
     522                                class: 'customize-pane-child ' + list.attr( 'class' )
     523                        } );
     524                },
     525
     526                setOwnership: function ( elementId ) {
     527                        var container = this.container,
     528                                ownedElements = container.attr( 'aria-owns' );
     529
     530                        if ( _.isUndefined( ownedElements ) ) {
     531                                container.attr( {
     532                                        'aria-owns': elementId
     533                                } );
     534                        } else {
     535                                container.attr( {
     536                                        'aria-owns': ownedElements + ' ' + elementId
     537                                } );
     538                        }
    484539                }
    485540        });
    486541
     
    543598                 * @since 4.1.0
    544599                 */
    545600                embed: function () {
    546                         var section = this, inject;
     601                        var inject,
     602                                section = this,
     603                                container = $( '#customize-theme-controls' );
    547604
    548605                        // Watch for changes to the panel state
    549606                        inject = function ( panelId ) {
     
    553610                                        api.panel( panelId, function ( panel ) {
    554611                                                // The panel has been registered, wait for it to become ready/initialized
    555612                                                panel.deferred.embedded.done( function () {
    556                                                         parentContainer = panel.container.find( 'ul:first' );
     613                                                        parentContainer = panel.content; // panel.container.find( 'ul:first' );
    557614                                                        if ( ! section.container.parent().is( parentContainer ) ) {
    558615                                                                parentContainer.append( section.container );
     616                                                                //section.setOwnership( section.content.attr( 'id' ) );
     617                                                                container.append( section.content );
    559618                                                        }
    560619                                                        section.deferred.embedded.resolve();
    561620                                                });
    562621                                        } );
    563622                                } else {
    564623                                        // There is no panel, so embed the section in the root of the customizer
    565                                         parentContainer = $( '#customize-theme-controls' ).children( 'ul' ); // @todo This should be defined elsewhere, and to be configurable
     624                                        parentContainer = $( '.customize-pane-parent' ); // @todo This should be defined elsewhere, and to be configurable
    566625                                        if ( ! section.container.parent().is( parentContainer ) ) {
    567626                                                parentContainer.append( section.container );
     627                                                container.append( section.content );
    568628                                        }
    569629                                        section.deferred.embedded.resolve();
    570630                                }
     
    586646                 * @since 4.1.0
    587647                 */
    588648                attachEvents: function () {
    589                         var section = this;
     649                        var section = this,
     650                                expandCollapseEventTypes = 'click keydown',
     651                                expandCollapseEventHandler,
     652                                overlay = section.content.closest( '.wp-full-overlay' ),
     653                                normalizedTransitionendEventName = api.utils.getNormalizedTransitionendEvent();
    590654
    591655                        // Expand/Collapse accordion sections on click.
    592                         section.container.find( '.accordion-section-title, .customize-section-back' ).on( 'click keydown', function( event ) {
     656                        expandCollapseEventHandler = function ( event ) {
    593657                                if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
    594658                                        return;
    595659                                }
     
    600664                                } else {
    601665                                        section.expand();
    602666                                }
     667                        };
     668
     669                        section.container.find( '.accordion-section-title' ).on( expandCollapseEventTypes, expandCollapseEventHandler );
     670                        section.content.find( '.customize-section-back' ).on( expandCollapseEventTypes, expandCollapseEventHandler );
     671
     672                        section.content.on( normalizedTransitionendEventName, function() {
     673                                section.content.removeClass( 'animating' );
     674                                overlay.removeClass( 'animating' );
    603675                        });
    604676                },
    605677
     
    644716                onChangeExpanded: function ( expanded, args ) {
    645717                        var section = this,
    646718                                container = section.container.closest( '.wp-full-overlay-sidebar-content' ),
    647                                 content = section.container.find( '.accordion-section-content' ),
     719                                content = section.content, //section.container.find( '.accordion-section-content' ),
    648720                                overlay = section.container.closest( '.wp-full-overlay' ),
    649                                 backBtn = section.container.find( '.customize-section-back' ),
    650                                 sectionTitle = section.container.find( '.accordion-section-title' ).first(),
    651                                 headerActionsHeight = $( '#customize-header-actions' ).height(),
    652                                 resizeContentHeight, expand, position, scroll;
     721                                backBtn = content.find( '.customize-section-back' ), //section.container.find( '.customize-section-back' ),
     722                                sectionTitle = content.find( '.accordion-section-title' ).first(), // section.container.find( '.accordion-section-title' ).first(),
     723                                // headerActionsHeight = $( '#customize-header-actions' ).height(),
     724                                // resizeContentHeight,
     725                                expand, position, scroll;
    653726
    654                         if ( expanded && ! section.container.hasClass( 'open' ) ) {
     727                        // if ( expanded && ! section.container.hasClass( 'open' ) ) {
     728                        if ( expanded && ! content.hasClass( 'open' ) ) {
    655729
    656730                                if ( args.unchanged ) {
    657731                                        expand = args.completeCallback;
    658732                                } else {
    659733                                        container.scrollTop( 0 );
    660                                         resizeContentHeight = function() {
    661                                                 var matchMedia, offset;
    662                                                 matchMedia = window.matchMedia || window.msMatchMedia;
    663                                                 offset = 90; // 45px for customize header actions + 45px for footer actions.
    664 
    665                                                 // No footer on small screens.
    666                                                 if ( matchMedia && matchMedia( '(max-width: 640px)' ).matches ) {
    667                                                         offset = 45;
    668                                                 }
    669                                                 content.css( 'height', ( window.innerHeight - offset ) );
    670                                         };
     734                                        // resizeContentHeight = function() {
     735                                        //      var matchMedia, offset;
     736                                        //      matchMedia = window.matchMedia || window.msMatchMedia;
     737                                        //      offset = 90; // 45px for customize header actions + 45px for footer actions.
     738
     739                                        //      // No footer on small screens.
     740                                        //      if ( matchMedia && matchMedia( '(max-width: 640px)' ).matches ) {
     741                                        //              offset = 45;
     742                                        //      }
     743                                        //      content.css( 'height', ( window.innerHeight - offset ) );
     744                                        // };
    671745                                        expand = function() {
    672                                                 section.container.addClass( 'open' );
     746                                                // section.container.addClass( 'open' );
     747                                                content.addClass( 'open' );
     748                                                content.addClass( 'animating' );
    673749                                                overlay.addClass( 'section-open' );
    674                                                 position = content.offset().top;
    675                                                 scroll = container.scrollTop();
    676                                                 content.css( 'margin-top', ( headerActionsHeight - position - scroll ) );
    677                                                 resizeContentHeight();
     750                                                overlay.addClass( 'animating' );
     751                                                // position = content.offset().top;
     752                                                // scroll = container.scrollTop();
     753                                                // content.css( 'margin-top', ( headerActionsHeight - position - scroll ) );
     754                                                // resizeContentHeight();
    678755                                                sectionTitle.attr( 'tabindex', '-1' );
    679756                                                backBtn.attr( 'tabindex', '0' );
    680                                                 backBtn.focus();
     757                                                // backBtn.focus();
    681758                                                if ( args.completeCallback ) {
    682759                                                        args.completeCallback();
    683760                                                }
    684761
    685762                                                // Fix the height after browser resize.
    686                                                 $( window ).on( 'resize.customizer-section', _.debounce( resizeContentHeight, 100 ) );
     763                                                // $( window ).on( 'resize.customizer-section', _.debounce( resizeContentHeight, 100 ) );
    687764
    688765                                                section._recalculateTopMargin();
    689766                                        };
     
    709786                                        expand();
    710787                                }
    711788
    712                         } else if ( ! expanded && section.container.hasClass( 'open' ) ) {
    713                                 section.container.removeClass( 'open' );
     789                        // } else if ( ! expanded && section.container.hasClass( 'open' ) ) {
     790                        } else if ( ! expanded && content.hasClass( 'open' ) ) {
     791                                // section.container.removeClass( 'open' );
     792                                content.removeClass( 'open' );
     793                                content.addClass( 'animating' );
    714794                                overlay.removeClass( 'section-open' );
    715                                 content.css( 'margin-top', '' );
    716                                 container.scrollTop( 0 );
     795                                overlay.addClass( 'animating' );
     796                                // content.css( 'margin-top', '' );
     797                                // container.scrollTop( 0 );
    717798                                backBtn.attr( 'tabindex', '-1' );
    718799                                sectionTitle.attr( 'tabindex', '0' );
    719                                 sectionTitle.focus();
     800                                // sectionTitle.focus();
    720801                                if ( args.completeCallback ) {
    721802                                        args.completeCallback();
    722803                                }
    723                                 $( window ).off( 'resize.customizer-section' );
     804                                // $( window ).off( 'resize.customizer-section' );
    724805                        } else {
    725806                                if ( args.completeCallback ) {
    726807                                        args.completeCallback();
     
    735816                 * @private
    736817                 */
    737818                _recalculateTopMargin: function() {
    738                         var section = this, content, offset, headerActionsHeight;
    739                         content = section.container.find( '.accordion-section-content' );
    740                         if ( 0 === content.length ) {
    741                                 return;
    742                         }
    743                         headerActionsHeight = $( '#customize-header-actions' ).height();
    744                         offset = ( content.offset().top - headerActionsHeight );
    745                         if ( 0 < offset ) {
    746                                 content.css( 'margin-top', ( parseInt( content.css( 'margin-top' ), 10 ) - offset ) );
    747                         }
     819                        return;
     820                        // var section = this, content, offset, headerActionsHeight;
     821                        // content = section.container.find( '.accordion-section-content' );
     822                        // if ( 0 === content.length ) {
     823                        //      return;
     824                        // }
     825                        // headerActionsHeight = $( '#customize-header-actions' ).height();
     826                        // offset = ( content.offset().top - headerActionsHeight );
     827                        // if ( 0 < offset ) {
     828                        //      content.css( 'margin-top', ( parseInt( content.css( 'margin-top' ), 10 ) - offset ) );
     829                        // }
    748830                }
    749831        });
    750832
     
    9821064                 * @private
    9831065                 */
    9841066                _recalculateTopMargin: function() {
    985                         api.Panel.prototype._recalculateTopMargin.call( this );
     1067                        return;
     1068                        // api.Panel.prototype._recalculateTopMargin.call( this );
    9861069                },
    9871070
    9881071                /**
     
    12111294                 */
    12121295                embed: function () {
    12131296                        var panel = this,
    1214                                 parentContainer = $( '#customize-theme-controls > ul' ); // @todo This should be defined elsewhere, and to be configurable
     1297                                container = $( '#customize-theme-controls' ),
     1298                                parentContainer = $( '.customize-pane-parent' ); // @todo This should be defined elsewhere, and to be configurable
    12151299
    12161300                        if ( ! panel.container.parent().is( parentContainer ) ) {
    12171301                                parentContainer.append( panel.container );
     1302                                container.append( panel.content );
    12181303                                panel.renderContent();
    12191304                        }
    12201305
    1221                         api.bind( 'pane-contents-reflowed', _.debounce( function() {
    1222                                 panel._recalculateTopMargin();
    1223                         }, 100 ) );
     1306                        // api.bind( 'pane-contents-reflowed', _.debounce( function() {
     1307                        //      panel._recalculateTopMargin();
     1308                        // }, 100 ) );
    12241309
    12251310                        panel.deferred.embedded.resolve();
    12261311                },
     
    12291314                 * @since 4.1.0
    12301315                 */
    12311316                attachEvents: function () {
    1232                         var meta, panel = this;
     1317                        var meta, panel = this,
     1318                                overlay = panel.content.closest( '.wp-full-overlay' ),
     1319                                normalizedTransitionendEventName = api.utils.getNormalizedTransitionendEvent();
    12331320
    12341321                        // Expand/Collapse accordion sections on click.
    12351322                        panel.container.find( '.accordion-section-title' ).on( 'click keydown', function( event ) {
     
    12441331                        });
    12451332
    12461333                        // Close panel.
    1247                         panel.container.find( '.customize-panel-back' ).on( 'click keydown', function( event ) {
     1334                        // panel.container.find( '.customize-panel-back' ).on( 'click keydown', function( event ) {
     1335                        panel.content.find( '.customize-panel-back' ).on( 'click keydown', function( event ) {
    12481336                                if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
    12491337                                        return;
    12501338                                }
     
    12551343                                }
    12561344                        });
    12571345
    1258                         meta = panel.container.find( '.panel-meta:first' );
     1346                        meta = panel.content.find( '.panel-meta:first' );
    12591347
    12601348                        meta.find( '> .accordion-section-title .customize-help-toggle' ).on( 'click keydown', function( event ) {
    12611349                                if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
     
    12631351                                }
    12641352                                event.preventDefault(); // Keep this AFTER the key filter above
    12651353
    1266                                 meta = panel.container.find( '.panel-meta' );
     1354                                // meta = panel.container.find( '.panel-meta' );
    12671355                                if ( meta.hasClass( 'cannot-expand' ) ) {
    12681356                                        return;
    12691357                                }
     
    12801368                                }
    12811369                        });
    12821370
     1371                        panel.content.on( normalizedTransitionendEventName, function() {
     1372                                panel.content.removeClass( 'animating' );
     1373                                overlay.removeClass( 'animating' );
     1374                        });
     1375
    12831376                },
    12841377
    12851378                /**
     
    13351428                        // Note: there is a second argument 'args' passed
    13361429                        var position, scroll,
    13371430                                panel = this,
    1338                                 accordionSection = panel.container.closest( '.accordion-section' ),
     1431                                accordionSection = panel.content; // .closest( '.accordion-section' ),
    13391432                                overlay = accordionSection.closest( '.wp-full-overlay' ),
    13401433                                container = accordionSection.closest( '.wp-full-overlay-sidebar-content' ),
    13411434                                siblings = container.find( '.open' ),
    1342                                 topPanel = overlay.find( '#customize-theme-controls > ul > .accordion-section > .accordion-section-title' ),
     1435                                // topPanel = overlay.find( '#customize-theme-controls > ul > .accordion-section > .accordion-section-title' ),
     1436                                topPanel = accordionSection.find( '.accordion-section-title' ),
    13431437                                backBtn = accordionSection.find( '.customize-panel-back' ),
    1344                                 panelTitle = accordionSection.find( '.accordion-section-title' ).first(),
    1345                                 content = accordionSection.find( '.control-panel-content' ),
    1346                                 headerActionsHeight = $( '#customize-header-actions' ).height();
     1438                                panelTitle = accordionSection.find( '.accordion-section-title' ).first();
     1439                                // content = panel.content, // accordionSection.find( '.control-panel-content' ),
     1440                                // headerActionsHeight = $( '#customize-header-actions' ).height();
    13471441
    13481442                        if ( expanded ) {
    13491443
     
    13591453                                        }
    13601454                                });
    13611455
    1362                                 content.show( 0, function() {
    1363                                         content.parent().show();
    1364                                         position = content.offset().top;
    1365                                         scroll = container.scrollTop();
    1366                                         content.css( 'margin-top', ( headerActionsHeight - position - scroll ) );
     1456                                // content.show( 0, function() {
     1457                                        // content.parent().show();
     1458                                        // position = content.offset().top;
     1459                                        // scroll = container.scrollTop();
     1460                                        // content.css( 'margin-top', ( headerActionsHeight - position - scroll ) );
    13671461                                        accordionSection.addClass( 'current-panel' );
    13681462                                        overlay.addClass( 'in-sub-panel' );
    1369                                         container.scrollTop( 0 );
     1463                                        accordionSection.addClass( 'animating' );
     1464                                        overlay.addClass( 'animating' );
     1465                                        // container.scrollTop( 0 );
    13701466                                        if ( args.completeCallback ) {
    13711467                                                args.completeCallback();
    13721468                                        }
    1373                                 } );
     1469                                // } );
    13741470                                topPanel.attr( 'tabindex', '-1' );
    13751471                                backBtn.attr( 'tabindex', '0' );
    1376                                 backBtn.focus();
    1377                                 panel._recalculateTopMargin();
     1472                                // backBtn.focus();
     1473                                // panel._recalculateTopMargin();
    13781474                        } else {
    13791475                                siblings.removeClass( 'open' );
    13801476                                accordionSection.removeClass( 'current-panel' );
    13811477                                overlay.removeClass( 'in-sub-panel' );
    1382                                 content.delay( 180 ).hide( 0, function() {
    1383                                         content.css( 'margin-top', 'inherit' ); // Reset
     1478                                accordionSection.addClass( 'animating' );
     1479                                overlay.addClass( 'animating' );
     1480                                // content.delay( 180 ).hide( 0, function() {
     1481                                //      content.css( 'margin-top', 'inherit' ); // Reset
    13841482                                        if ( args.completeCallback ) {
    13851483                                                args.completeCallback();
    13861484                                        }
    1387                                 } );
     1485                                // } );
    13881486                                topPanel.attr( 'tabindex', '0' );
    13891487                                backBtn.attr( 'tabindex', '-1' );
    1390                                 panelTitle.focus();
     1488                                // panelTitle.focus();
    13911489                                container.scrollTop( 0 );
    13921490                        }
    13931491                },
     
    13991497                 * @private
    14001498                 */
    14011499                _recalculateTopMargin: function() {
    1402                         var panel = this, headerActionsHeight, content, accordionSection;
    1403                         headerActionsHeight = $( '#customize-header-actions' ).height();
    1404                         accordionSection = panel.container.closest( '.accordion-section' );
    1405                         content = accordionSection.find( '.control-panel-content' );
    1406                         content.css( 'margin-top', ( parseInt( content.css( 'margin-top' ), 10 ) - ( content.offset().top - headerActionsHeight ) ) );
     1500                        return;
     1501                        // var panel = this, headerActionsHeight, content, accordionSection;
     1502                        // headerActionsHeight = $( '#customize-header-actions' ).height();
     1503                        // accordionSection = panel.container.closest( '.accordion-section' );
     1504                        // content = accordionSection.find( '.control-panel-content' );
     1505                        // content.css( 'margin-top', ( parseInt( content.css( 'margin-top' ), 10 ) - ( content.offset().top - headerActionsHeight ) ) );
    14071506                },
    14081507
    14091508                /**
     
    14241523                                template = wp.template( 'customize-panel-default-content' );
    14251524                        }
    14261525                        if ( template && panel.container ) {
    1427                                 panel.container.find( '.accordion-sub-container' ).html( template( panel.params ) );
     1526                                panel.content.html( template( panel.params ) );
    14281527                        }
    14291528                }
    14301529        });
     
    15571656                                api.section( sectionId, function ( section ) {
    15581657                                        // Wait for the section to be ready/initialized
    15591658                                        section.deferred.embedded.done( function () {
    1560                                                 parentContainer = section.container.find( 'ul:first' );
     1659                                                parentContainer = section.content; // section.container.find( 'ul:first' );
    15611660                                                if ( ! control.container.parent().is( parentContainer ) ) {
    15621661                                                        parentContainer.append( control.container );
    15631662                                                        control.renderContent();
     
    34513550                                var sections = panel.sections(),
    34523551                                        sectionContainers = _.pluck( sections, 'container' );
    34533552                                rootNodes.push( panel );
    3454                                 appendContainer = panel.container.find( 'ul:first' );
     3553                                appendContainer = panel.content; // panel.container.find( 'ul:first' );
    34553554                                if ( ! api.utils.areElementListsEqual( sectionContainers, appendContainer.children( '[id]' ) ) ) {
    34563555                                        _( sections ).each( function ( section ) {
    34573556                                                appendContainer.append( section.container );
     
    34673566                                if ( ! section.panel() ) {
    34683567                                        rootNodes.push( section );
    34693568                                }
    3470                                 appendContainer = section.container.find( 'ul:first' );
     3569                                appendContainer = section.content; // section.container.find( 'ul:first' );
    34713570                                if ( ! api.utils.areElementListsEqual( controlContainers, appendContainer.children( '[id]' ) ) ) {
    34723571                                        _( controls ).each( function ( control ) {
    34733572                                                appendContainer.append( control.container );
     
    34793578                        // Sort the root panels and sections
    34803579                        rootNodes.sort( api.utils.prioritySort );
    34813580                        rootContainers = _.pluck( rootNodes, 'container' );
    3482                         appendContainer = $( '#customize-theme-controls' ).children( 'ul' ); // @todo This should be defined elsewhere, and to be configurable
     3581                        appendContainer = $( '.customize-pane-parent' ); //$( '#customize-theme-controls' ).children( 'ul' ); // @todo This should be defined elsewhere, and to be configurable
    34833582                        if ( ! api.utils.areElementListsEqual( rootContainers, appendContainer.children() ) ) {
    34843583                                _( rootNodes ).each( function ( rootNode ) {
    34853584                                        appendContainer.append( rootNode.container );
  • src/wp-admin/js/customize-controls.js

    From 5d422a665c05721fb6b66f8c23230807e4d1ec43 Mon Sep 17 00:00:00 2001
    From: Piotr Delawski <piotr.delawski@xwp.co>
    Date: Fri, 12 Feb 2016 21:49:47 +0100
    Subject: [PATCH 2/9] WIP: Harden panel/section UI code by removing contents
     from being logically nested
    
    ---
     src/wp-admin/js/customize-controls.js | 48 ++++++++++++++++++++++++-----------
     1 file changed, 33 insertions(+), 15 deletions(-)
    
    diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js
    index 19f508d..695771d 100644
    a b  
    649649                        var section = this,
    650650                                expandCollapseEventTypes = 'click keydown',
    651651                                expandCollapseEventHandler,
    652                                 overlay = section.content.closest( '.wp-full-overlay' ),
    653                                 normalizedTransitionendEventName = api.utils.getNormalizedTransitionendEvent();
     652                                overlay = section.content.closest( '.wp-full-overlay' );
     653                                //normalizedTransitionendEventName = api.utils.getNormalizedTransitionendEvent();
    654654
    655655                        // Expand/Collapse accordion sections on click.
    656656                        expandCollapseEventHandler = function ( event ) {
     
    669669                        section.container.find( '.accordion-section-title' ).on( expandCollapseEventTypes, expandCollapseEventHandler );
    670670                        section.content.find( '.customize-section-back' ).on( expandCollapseEventTypes, expandCollapseEventHandler );
    671671
    672                         section.content.on( normalizedTransitionendEventName, function() {
    673                                 section.content.removeClass( 'animating' );
    674                                 overlay.removeClass( 'animating' );
    675                         });
     672                        // section.content.on( normalizedTransitionendEventName, function() {
     673                        //      section.content.removeClass( 'animating' );
     674                        //      overlay.removeClass( 'animating' );
     675                        // });
    676676                },
    677677
    678678                /**
     
    722722                                sectionTitle = content.find( '.accordion-section-title' ).first(), // section.container.find( '.accordion-section-title' ).first(),
    723723                                // headerActionsHeight = $( '#customize-header-actions' ).height(),
    724724                                // resizeContentHeight,
     725                                normalizedTransitionendEventName = api.utils.getNormalizedTransitionendEvent(),
    725726                                expand, position, scroll;
    726727
    727728                        // if ( expanded && ! section.container.hasClass( 'open' ) ) {
     
    745746                                        expand = function() {
    746747                                                // section.container.addClass( 'open' );
    747748                                                content.addClass( 'open' );
    748                                                 content.addClass( 'animating' );
    749749                                                overlay.addClass( 'section-open' );
     750                                                content.addClass( 'animating' );
    750751                                                overlay.addClass( 'animating' );
     752                                                content.one( normalizedTransitionendEventName, function() {
     753                                                        content.removeClass( 'animating' );
     754                                                        overlay.removeClass( 'animating' );
     755                                                });
    751756                                                // position = content.offset().top;
    752757                                                // scroll = container.scrollTop();
    753758                                                // content.css( 'margin-top', ( headerActionsHeight - position - scroll ) );
     
    790795                        } else if ( ! expanded && content.hasClass( 'open' ) ) {
    791796                                // section.container.removeClass( 'open' );
    792797                                content.removeClass( 'open' );
    793                                 content.addClass( 'animating' );
    794798                                overlay.removeClass( 'section-open' );
     799                                content.addClass( 'animating' );
    795800                                overlay.addClass( 'animating' );
     801                                content.one( normalizedTransitionendEventName, function() {
     802                                        content.removeClass( 'animating' );
     803                                        overlay.removeClass( 'animating' );
     804                                });
    796805                                // content.css( 'margin-top', '' );
    797806                                // container.scrollTop( 0 );
    798807                                backBtn.attr( 'tabindex', '-1' );
     
    13151324                 */
    13161325                attachEvents: function () {
    13171326                        var meta, panel = this,
    1318                                 overlay = panel.content.closest( '.wp-full-overlay' ),
    1319                                 normalizedTransitionendEventName = api.utils.getNormalizedTransitionendEvent();
     1327                                overlay = panel.content.closest( '.wp-full-overlay' );
     1328                                //normalizedTransitionendEventName = api.utils.getNormalizedTransitionendEvent();
    13201329
    13211330                        // Expand/Collapse accordion sections on click.
    13221331                        panel.container.find( '.accordion-section-title' ).on( 'click keydown', function( event ) {
     
    13681377                                }
    13691378                        });
    13701379
    1371                         panel.content.on( normalizedTransitionendEventName, function() {
    1372                                 panel.content.removeClass( 'animating' );
    1373                                 overlay.removeClass( 'animating' );
    1374                         });
     1380                        // panel.content.on( normalizedTransitionendEventName, function() {
     1381                        //      panel.content.removeClass( 'animating' );
     1382                        //      overlay.removeClass( 'animating' );
     1383                        // });
    13751384
    13761385                },
    13771386
     
    14351444                                // topPanel = overlay.find( '#customize-theme-controls > ul > .accordion-section > .accordion-section-title' ),
    14361445                                topPanel = accordionSection.find( '.accordion-section-title' ),
    14371446                                backBtn = accordionSection.find( '.customize-panel-back' ),
    1438                                 panelTitle = accordionSection.find( '.accordion-section-title' ).first();
     1447                                panelTitle = accordionSection.find( '.accordion-section-title' ).first(),
     1448                                normalizedTransitionendEventName = api.utils.getNormalizedTransitionendEvent();
    14391449                                // content = panel.content, // accordionSection.find( '.control-panel-content' ),
    14401450                                // headerActionsHeight = $( '#customize-header-actions' ).height();
    14411451
     
    14621472                                        overlay.addClass( 'in-sub-panel' );
    14631473                                        accordionSection.addClass( 'animating' );
    14641474                                        overlay.addClass( 'animating' );
     1475                                        accordionSection.one( normalizedTransitionendEventName, function() {
     1476                                                accordionSection.removeClass( 'animating' );
     1477                                                overlay.removeClass( 'animating' );
     1478                                        });
    14651479                                        // container.scrollTop( 0 );
    14661480                                        if ( args.completeCallback ) {
    14671481                                                args.completeCallback();
     
    14771491                                overlay.removeClass( 'in-sub-panel' );
    14781492                                accordionSection.addClass( 'animating' );
    14791493                                overlay.addClass( 'animating' );
     1494                                accordionSection.one( normalizedTransitionendEventName, function() {
     1495                                        accordionSection.removeClass( 'animating' );
     1496                                        overlay.removeClass( 'animating' );
     1497                                });
    14801498                                // content.delay( 180 ).hide( 0, function() {
    14811499                                //      content.css( 'margin-top', 'inherit' ); // Reset
    14821500                                        if ( args.completeCallback ) {
  • src/wp-admin/css/common.css

    From 6055301c7fbfbee0387d5e92cc9108399d62501d Mon Sep 17 00:00:00 2001
    From: Piotr Delawski <piotr.delawski@xwp.co>
    Date: Sat, 20 Feb 2016 23:52:02 +0100
    Subject: [PATCH 3/9] Fix transitioning and class handling. Add focus()
     support. Not browser tested yet.
    
    ---
     src/wp-admin/css/common.css             |   6 +-
     src/wp-admin/css/customize-controls.css |  48 +++---
     src/wp-admin/js/customize-controls.js   | 261 ++++++++++++--------------------
     3 files changed, 120 insertions(+), 195 deletions(-)
    
    diff --git a/src/wp-admin/css/common.css b/src/wp-admin/css/common.css
    index 679b0b9..3886902 100644
    a b img { 
    32133213        display: none;
    32143214}
    32153215
    3216 .control-section .accordion-section-title {
     3216.control-section .accordion-section-title,
     3217.customize-pane-child .accordion-section-title {
    32173218        border-left: none;
    32183219        border-right: none;
    32193220        padding: 10px 10px 11px 14px;
    img { 
    32213222        background: #fff;
    32223223}
    32233224
    3224 .control-section .accordion-section-title:after {
     3225.control-section .accordion-section-title:after,
     3226.customize-pane-child .accordion-section-title:after {
    32253227        top: 11px;
    32263228}
    32273229
  • src/wp-admin/css/customize-controls.css

    diff --git a/src/wp-admin/css/customize-controls.css b/src/wp-admin/css/customize-controls.css
    index 70f4f13..a45c228 100644
    a b body { 
    7777        line-height: 24px;
    7878}
    7979
    80 #customize-controls .control-section .customize-section-title h3,
    81 #customize-controls .control-section h3.customize-section-title,
     80#customize-controls .customize-pane-child .customize-section-title h3,
     81#customize-controls .customize-pane-child h3.customize-section-title,
    8282#customize-controls .customize-info .panel-title {
    8383        font-size: 20px;
    8484        font-weight: 200;
    body { 
    217217        box-sizing: border-box;
    218218}
    219219
    220 
    221 
    222 
    223220#customize-info,
    224221#customize-theme-controls .customize-pane-parent,
    225222#customize-theme-controls .customize-pane-child {
     223        overflow: visible;
    226224        width: 100%;
    227225        margin: 0;
    228226        padding: 0;
    229227        -webkit-box-sizing: border-box;
    230228        -moz-box-sizing: border-box;
    231229        box-sizing: border-box;
    232 
    233         transition: 0.36s transform cubic-bezier(0.19, 1, 0.22, 1);
    234         /*visibility: visible !important;*/
    235         overflow: visible !important;
     230        transition: 0.36s transform cubic-bezier(0.19, 1, 0.22, 1); /* http://easings.net/#easeOutExpo */
    236231}
    237232
    238233#customize-info,
    body { 
    248243.in-sub-panel #customize-info,
    249244.in-sub-panel.section-open #customize-theme-controls .customize-pane-child.current-panel {
    250245        transform: translateX(-100%);
    251         /*visibility: hidden;*/
     246}
     247
     248#customize-theme-controls .customize-pane-child.open,
     249#customize-theme-controls .customize-pane-child.current-panel {
     250        transform: translateX(0);
    252251}
    253252
    254253.section-open #customize-theme-controls .customize-pane-parent,
    255254.in-sub-panel #customize-theme-controls .customize-pane-parent,
    256255.section-open #customize-info,
    257256.in-sub-panel #customize-info,
    258 .animating.section-open.in-sub-panel #customize-theme-controls .customize-pane-parent,
    259 .animating.section-open.in-sub-panel #customize-info, {
     257.section-open.in-sub-panel #customize-theme-controls .customize-pane-child.current-panel {
    260258        visibility: hidden;
    261259}
    262260
    263 .animating.section-open #customize-theme-controls .customize-pane-parent,
    264 .animating.in-sub-panel #customize-theme-controls .customize-pane-parent,
    265 .animating.section-open #customize-info,
    266 .animating.in-sub-panel #customize-info {
     261.section-open #customize-theme-controls .customize-pane-parent.closing,
     262.in-sub-panel #customize-theme-controls .customize-pane-parent.closing,
     263.section-open #customize-info.closing,
     264.in-sub-panel #customize-info.closing,
     265.transitioning.section-open.in-sub-panel #customize-theme-controls .customize-pane-child.current-panel,
     266#customize-theme-controls .customize-pane-child.open,
     267#customize-theme-controls .customize-pane-child.current-panel,
     268#customize-theme-controls .customize-pane-child.closing {
    267269        visibility: visible;
    268270}
    269271
    body { 
    284286        padding: 12px;
    285287}
    286288
    287 #customize-theme-controls .customize-pane-child.open,
    288 #customize-theme-controls .customize-pane-child.current-panel {
    289         transform: translateX(0);
    290 }
    291 
    292 #customize-theme-controls .customize-pane-child.open,
    293 #customize-theme-controls .customize-pane-child.current-panel,
    294 #customize-theme-controls .customize-pane-child.animating {
    295         visibility: visible;
    296 }
    297 
    298 
    299 
    300 
    301289.customize-section-description-container {
    302290        margin-bottom: 15px;
    303291}
  • src/wp-admin/js/customize-controls.js

    diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js
    index ce4e83c..1c1ec8e 100644
    a b  
    11/* global _wpCustomizeHeader, _wpCustomizeBackground, _wpMediaViewsL10n, MediaElementPlayer */
    22(function( exports, $ ){
    3         var Container, focus, api = wp.customize;
     3        var Container, focus, normalizedTransitionendEventName, api = wp.customize;
     4
     5        normalizedTransitionendEventName = (function () {
     6                var el, transitions, prop;
     7                el = document.createElement( 'div' );
     8                transitions = {
     9                        'transition'      : 'transitionend',
     10                        'OTransition'     : 'oTransitionEnd',
     11                        'MozTransition'   : 'transitionend',
     12                        'WebkitTransition': 'webkitTransitionEnd'
     13                };
     14                prop = _.find( _.keys( transitions ), function( prop ) {
     15                        return ! _.isUndefined( el.style[ prop ] );
     16                } );
     17                if ( prop ) {
     18                        return transitions[ prop ];
     19                } else {
     20                        return null;
     21                }
     22        })();
    423
    524        /**
    625         * A Customizer Setting.
     
    610629                                        api.panel( panelId, function ( panel ) {
    611630                                                // The panel has been registered, wait for it to become ready/initialized
    612631                                                panel.deferred.embedded.done( function () {
    613                                                         parentContainer = panel.content; // panel.container.find( 'ul:first' );
     632                                                        parentContainer = panel.content;
    614633                                                        if ( ! section.container.parent().is( parentContainer ) ) {
    615634                                                                parentContainer.append( section.container );
    616                                                                 //section.setOwnership( section.content.attr( 'id' ) );
    617635                                                                container.append( section.content );
    618636                                                        }
    619637                                                        section.deferred.embedded.resolve();
     
    631649                        };
    632650                        section.panel.bind( inject );
    633651                        inject( section.panel.get() ); // Since a section may never get a panel, assume that it won't ever get one
    634 
    635                         section.deferred.embedded.done(function() {
    636                                 // Fix the top margin after reflow.
    637                                 api.bind( 'pane-contents-reflowed', _.debounce( function() {
    638                                         section._recalculateTopMargin();
    639                                 }, 100 ) );
    640                         });
    641652                },
    642653
    643654                /**
     
    650661                                expandCollapseEventTypes = 'click keydown',
    651662                                expandCollapseEventHandler,
    652663                                overlay = section.content.closest( '.wp-full-overlay' );
    653                                 //normalizedTransitionendEventName = api.utils.getNormalizedTransitionendEvent();
    654664
    655665                        // Expand/Collapse accordion sections on click.
    656666                        expandCollapseEventHandler = function ( event ) {
     
    668678
    669679                        section.container.find( '.accordion-section-title' ).on( expandCollapseEventTypes, expandCollapseEventHandler );
    670680                        section.content.find( '.customize-section-back' ).on( expandCollapseEventTypes, expandCollapseEventHandler );
    671 
    672                         // section.content.on( normalizedTransitionendEventName, function() {
    673                         //      section.content.removeClass( 'animating' );
    674                         //      overlay.removeClass( 'animating' );
    675                         // });
    676681                },
    677682
    678683                /**
     
    716721                onChangeExpanded: function ( expanded, args ) {
    717722                        var section = this,
    718723                                container = section.container.closest( '.wp-full-overlay-sidebar-content' ),
    719                                 content = section.content, //section.container.find( '.accordion-section-content' ),
     724                                content = section.content,
    720725                                overlay = section.container.closest( '.wp-full-overlay' ),
    721                                 backBtn = content.find( '.customize-section-back' ), //section.container.find( '.customize-section-back' ),
    722                                 sectionTitle = content.find( '.accordion-section-title' ).first(), // section.container.find( '.accordion-section-title' ).first(),
    723                                 // headerActionsHeight = $( '#customize-header-actions' ).height(),
    724                                 // resizeContentHeight,
    725                                 normalizedTransitionendEventName = api.utils.getNormalizedTransitionendEvent(),
    726                                 expand, position, scroll;
    727 
    728                         // if ( expanded && ! section.container.hasClass( 'open' ) ) {
     726                                info = overlay.find( '#customize-info' ),
     727                                parent = overlay.find( '.customize-pane-parent' ),
     728                                backBtn = content.find( '.customize-section-back' ),
     729                                sectionTitle = content.find( '.accordion-section-title' ).first(),
     730                                expand;
     731
    729732                        if ( expanded && ! content.hasClass( 'open' ) ) {
    730733
    731734                                if ( args.unchanged ) {
    732735                                        expand = args.completeCallback;
    733736                                } else {
    734737                                        container.scrollTop( 0 );
    735                                         // resizeContentHeight = function() {
    736                                         //      var matchMedia, offset;
    737                                         //      matchMedia = window.matchMedia || window.msMatchMedia;
    738                                         //      offset = 90; // 45px for customize header actions + 45px for footer actions.
    739 
    740                                         //      // No footer on small screens.
    741                                         //      if ( matchMedia && matchMedia( '(max-width: 640px)' ).matches ) {
    742                                         //              offset = 45;
    743                                         //      }
    744                                         //      content.css( 'height', ( window.innerHeight - offset ) );
    745                                         // };
    746738                                        expand = function() {
    747                                                 // section.container.addClass( 'open' );
     739                                                content.one( normalizedTransitionendEventName, function () {
     740                                                        info.removeClass( 'closing' );
     741                                                        parent.removeClass( 'closing' );
     742                                                        overlay.removeClass( 'transitioning' );
     743                                                        backBtn.focus();
     744                                                } );
     745
    748746                                                content.addClass( 'open' );
    749                                                 overlay.addClass( 'section-open' );
    750                                                 content.addClass( 'animating' );
    751                                                 overlay.addClass( 'animating' );
    752                                                 content.one( normalizedTransitionendEventName, function() {
    753                                                         content.removeClass( 'animating' );
    754                                                         overlay.removeClass( 'animating' );
    755                                                 });
    756                                                 // position = content.offset().top;
    757                                                 // scroll = container.scrollTop();
    758                                                 // content.css( 'margin-top', ( headerActionsHeight - position - scroll ) );
    759                                                 // resizeContentHeight();
     747                                                info.addClass( 'closing' );
     748                                                parent.addClass( 'closing' );
     749                                                overlay.addClass( 'section-open transitioning' );
     750
    760751                                                sectionTitle.attr( 'tabindex', '-1' );
    761752                                                backBtn.attr( 'tabindex', '0' );
    762                                                 // backBtn.focus();
     753
    763754                                                if ( args.completeCallback ) {
    764755                                                        args.completeCallback();
    765756                                                }
    766 
    767                                                 // Fix the height after browser resize.
    768                                                 // $( window ).on( 'resize.customizer-section', _.debounce( resizeContentHeight, 100 ) );
    769 
    770                                                 section._recalculateTopMargin();
    771757                                        };
    772758                                }
    773759
     
    791777                                        expand();
    792778                                }
    793779
    794                         // } else if ( ! expanded && section.container.hasClass( 'open' ) ) {
    795780                        } else if ( ! expanded && content.hasClass( 'open' ) ) {
    796                                 // section.container.removeClass( 'open' );
    797                                 content.removeClass( 'open' );
    798                                 overlay.removeClass( 'section-open' );
    799                                 content.addClass( 'animating' );
    800                                 overlay.addClass( 'animating' );
    801                                 content.one( normalizedTransitionendEventName, function() {
    802                                         content.removeClass( 'animating' );
    803                                         overlay.removeClass( 'animating' );
    804                                 });
    805                                 // content.css( 'margin-top', '' );
    806                                 // container.scrollTop( 0 );
     781
     782                                content.one( normalizedTransitionendEventName, function () {
     783                                        content.removeClass( 'closing' );
     784                                        info.removeClass( 'closing' );
     785                                        parent.removeClass( 'closing' );
     786                                        overlay.removeClass( 'transitioning' );
     787                                        sectionTitle.focus();
     788                                } );
     789
     790                                content.removeClass( 'open' ).addClass( 'closing' );
     791                                info.addClass( 'closing' );
     792                                parent.addClass( 'closing' );
     793                                overlay.removeClass( 'section-open transitioning' );
     794
    807795                                backBtn.attr( 'tabindex', '-1' );
    808796                                sectionTitle.attr( 'tabindex', '0' );
    809                                 // sectionTitle.focus();
     797
    810798                                if ( args.completeCallback ) {
    811799                                        args.completeCallback();
    812800                                }
    813                                 // $( window ).off( 'resize.customizer-section' );
    814801                        } else {
    815802                                if ( args.completeCallback ) {
    816803                                        args.completeCallback();
    817804                                }
    818805                        }
    819                 },
    820 
    821                 /**
    822                  * Recalculate the top margin.
    823                  *
    824                  * @since 4.4.0
    825                  * @private
    826                  */
    827                 _recalculateTopMargin: function() {
    828                         return;
    829                         // var section = this, content, offset, headerActionsHeight;
    830                         // content = section.container.find( '.accordion-section-content' );
    831                         // if ( 0 === content.length ) {
    832                         //      return;
    833                         // }
    834                         // headerActionsHeight = $( '#customize-header-actions' ).height();
    835                         // offset = ( content.offset().top - headerActionsHeight );
    836                         // if ( 0 < offset ) {
    837                         //      content.css( 'margin-top', ( parseInt( content.css( 'margin-top' ), 10 ) - offset ) );
    838                         // }
    839806                }
    840807        });
    841808
     
    13121279                                panel.renderContent();
    13131280                        }
    13141281
    1315                         // api.bind( 'pane-contents-reflowed', _.debounce( function() {
    1316                         //      panel._recalculateTopMargin();
    1317                         // }, 100 ) );
    1318 
    13191282                        panel.deferred.embedded.resolve();
    13201283                },
    13211284
     
    13251288                attachEvents: function () {
    13261289                        var meta, panel = this,
    13271290                                overlay = panel.content.closest( '.wp-full-overlay' );
    1328                                 //normalizedTransitionendEventName = api.utils.getNormalizedTransitionendEvent();
    13291291
    13301292                        // Expand/Collapse accordion sections on click.
    13311293                        panel.container.find( '.accordion-section-title' ).on( 'click keydown', function( event ) {
     
    13401302                        });
    13411303
    13421304                        // Close panel.
    1343                         // panel.container.find( '.customize-panel-back' ).on( 'click keydown', function( event ) {
    13441305                        panel.content.find( '.customize-panel-back' ).on( 'click keydown', function( event ) {
    13451306                                if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
    13461307                                        return;
     
    13601321                                }
    13611322                                event.preventDefault(); // Keep this AFTER the key filter above
    13621323
    1363                                 // meta = panel.container.find( '.panel-meta' );
    13641324                                if ( meta.hasClass( 'cannot-expand' ) ) {
    13651325                                        return;
    13661326                                }
     
    13761336                                        $( this ).attr( 'aria-expanded', true );
    13771337                                }
    13781338                        });
    1379 
    1380                         // panel.content.on( normalizedTransitionendEventName, function() {
    1381                         //      panel.content.removeClass( 'animating' );
    1382                         //      overlay.removeClass( 'animating' );
    1383                         // });
    1384 
    13851339                },
    13861340
    13871341                /**
     
    14351389                        }
    14361390
    14371391                        // Note: there is a second argument 'args' passed
    1438                         var position, scroll,
    1439                                 panel = this,
    1440                                 accordionSection = panel.content; // .closest( '.accordion-section' ),
     1392                        var panel = this,
     1393                                accordionSection = panel.content,
    14411394                                overlay = accordionSection.closest( '.wp-full-overlay' ),
    14421395                                container = accordionSection.closest( '.wp-full-overlay-sidebar-content' ),
    1443                                 siblings = container.find( '.open' ),
    1444                                 // topPanel = overlay.find( '#customize-theme-controls > ul > .accordion-section > .accordion-section-title' ),
     1396                                info = overlay.find( '#customize-info' ),
     1397                                parent = overlay.find( '.customize-pane-parent' ),
    14451398                                topPanel = accordionSection.find( '.accordion-section-title' ),
    14461399                                backBtn = accordionSection.find( '.customize-panel-back' ),
    1447                                 panelTitle = accordionSection.find( '.accordion-section-title' ).first(),
    1448                                 normalizedTransitionendEventName = api.utils.getNormalizedTransitionendEvent();
    1449                                 // content = panel.content, // accordionSection.find( '.control-panel-content' ),
    1450                                 // headerActionsHeight = $( '#customize-header-actions' ).height();
     1400                                panelTitle = accordionSection.find( '.accordion-section-title' ).first();
    14511401
    1452                         if ( expanded ) {
     1402                        if ( expanded && ! accordionSection.hasClass( 'current-panel' ) ) {
    14531403
    14541404                                // Collapse any sibling sections/panels
    14551405                                api.section.each( function ( section ) {
     
    14631413                                        }
    14641414                                });
    14651415
    1466                                 // content.show( 0, function() {
    1467                                         // content.parent().show();
    1468                                         // position = content.offset().top;
    1469                                         // scroll = container.scrollTop();
    1470                                         // content.css( 'margin-top', ( headerActionsHeight - position - scroll ) );
    1471                                         accordionSection.addClass( 'current-panel' );
    1472                                         overlay.addClass( 'in-sub-panel' );
    1473                                         accordionSection.addClass( 'animating' );
    1474                                         overlay.addClass( 'animating' );
    1475                                         accordionSection.one( normalizedTransitionendEventName, function() {
    1476                                                 accordionSection.removeClass( 'animating' );
    1477                                                 overlay.removeClass( 'animating' );
    1478                                         });
    1479                                         // container.scrollTop( 0 );
    1480                                         if ( args.completeCallback ) {
    1481                                                 args.completeCallback();
    1482                                         }
    1483                                 // } );
     1416                                accordionSection.one( normalizedTransitionendEventName, function () {
     1417                                        info.removeClass( 'closing' );
     1418                                        parent.removeClass( 'closing' );
     1419                                        overlay.removeClass( 'transitioning' );
     1420                                        backBtn.focus();
     1421                                } );
     1422
     1423                                accordionSection.addClass( 'current-panel' );
     1424                                info.addClass( 'closing' );
     1425                                parent.addClass( 'closing' );
     1426                                overlay.addClass( 'in-sub-panel transitioning' );
     1427
     1428                                container.scrollTop( 0 );
     1429                                if ( args.completeCallback ) {
     1430                                        args.completeCallback();
     1431                                }
     1432
    14841433                                topPanel.attr( 'tabindex', '-1' );
    14851434                                backBtn.attr( 'tabindex', '0' );
    1486                                 // backBtn.focus();
    1487                                 // panel._recalculateTopMargin();
    1488                         } else {
    1489                                 siblings.removeClass( 'open' );
    1490                                 accordionSection.removeClass( 'current-panel' );
    1491                                 overlay.removeClass( 'in-sub-panel' );
    1492                                 accordionSection.addClass( 'animating' );
    1493                                 overlay.addClass( 'animating' );
    1494                                 accordionSection.one( normalizedTransitionendEventName, function() {
    1495                                         accordionSection.removeClass( 'animating' );
    1496                                         overlay.removeClass( 'animating' );
    1497                                 });
    1498                                 // content.delay( 180 ).hide( 0, function() {
    1499                                 //      content.css( 'margin-top', 'inherit' ); // Reset
    1500                                         if ( args.completeCallback ) {
    1501                                                 args.completeCallback();
    1502                                         }
    1503                                 // } );
     1435
     1436                        } else if ( ! expanded && accordionSection.hasClass( 'current-panel' ) ) {
     1437                                accordionSection.one( normalizedTransitionendEventName, function () {
     1438                                        accordionSection.removeClass( 'closing' );
     1439                                        info.removeClass( 'closing' );
     1440                                        parent.removeClass( 'closing' );
     1441                                        overlay.removeClass( 'transitioning' );
     1442                                        panelTitle.focus();
     1443                                } );
     1444
     1445                                accordionSection.removeClass( 'current-panel' ).addClass( 'closing' );
     1446                                info.addClass( 'closing' );
     1447                                parent.addClass( 'closing' );
     1448                                overlay.removeClass( 'in-sub-panel' ).addClass( 'transitioning' );
     1449
     1450                                if ( args.completeCallback ) {
     1451                                        args.completeCallback();
     1452                                }
     1453
    15041454                                topPanel.attr( 'tabindex', '0' );
    15051455                                backBtn.attr( 'tabindex', '-1' );
    1506                                 // panelTitle.focus();
     1456
    15071457                                container.scrollTop( 0 );
    15081458                        }
    15091459                },
    15101460
    15111461                /**
    1512                  * Recalculate the top margin.
    1513                  *
    1514                  * @since 4.4.0
    1515                  * @private
    1516                  */
    1517                 _recalculateTopMargin: function() {
    1518                         return;
    1519                         // var panel = this, headerActionsHeight, content, accordionSection;
    1520                         // headerActionsHeight = $( '#customize-header-actions' ).height();
    1521                         // accordionSection = panel.container.closest( '.accordion-section' );
    1522                         // content = accordionSection.find( '.control-panel-content' );
    1523                         // content.css( 'margin-top', ( parseInt( content.css( 'margin-top' ), 10 ) - ( content.offset().top - headerActionsHeight ) ) );
    1524                 },
    1525 
    1526                 /**
    15271462                 * Render the panel from its JS template, if it exists.
    15281463                 *
    15291464                 * The panel's container must already exist in the DOM.
  • src/wp-admin/css/customize-controls.css

    From 04662b902d6db816876c7b5a4568a6f66268087d Mon Sep 17 00:00:00 2001
    From: Piotr Delawski <piotr.delawski@xwp.co>
    Date: Sun, 28 Feb 2016 20:45:17 +0100
    Subject: [PATCH 4/9] WIP. Make themes panel work. Fix minor issues with scroll
     bar. Still pending code cleanup and cross-browser testing.
    
    ---
     src/wp-admin/css/customize-controls.css | 121 +++++++++++++++-------------
     src/wp-admin/js/customize-controls.js   | 135 +++++++++++++++++---------------
     2 files changed, 140 insertions(+), 116 deletions(-)
    
    diff --git a/src/wp-admin/css/customize-controls.css b/src/wp-admin/css/customize-controls.css
    index 1ae1aa2..60b4000 100644
    a b body { 
    227227        -webkit-box-sizing: border-box;
    228228        -moz-box-sizing: border-box;
    229229        box-sizing: border-box;
    230         transition: 0.36s transform cubic-bezier(0.19, 1, 0.22, 1); /* http://easings.net/#easeOutExpo */
     230        transition: 0.48s transform cubic-bezier(0.19, 1, 0.22, 1); /* easeOutExpo */
    231231}
    232232
    233233#customize-info,
    234234#customize-theme-controls .customize-pane-parent {
    235235        position: relative;
    236236        visibility: visible;
     237        height: auto;
     238        max-height: none;
     239        overflow: auto;
    237240        transform: translateX(0);
    238241}
    239242
    body { 
    245248        transform: translateX(-100%);
    246249}
    247250
    248 #customize-theme-controls .customize-pane-child.open,
    249 #customize-theme-controls .customize-pane-child.current-panel {
    250         transform: translateX(0);
     251.in-themes-panel #customize-theme-controls .customize-pane-parent,
     252.in-themes-panel #customize-info {
     253        transform: translateX(100%);
    251254}
    252255
    253256.section-open #customize-theme-controls .customize-pane-parent,
    body { 
    256259.in-sub-panel #customize-info,
    257260.section-open.in-sub-panel #customize-theme-controls .customize-pane-child.current-panel {
    258261        visibility: hidden;
     262        height: 0;
     263        overflow: hidden;
    259264}
    260265
    261266.section-open #customize-theme-controls .customize-pane-parent.closing,
    body { 
    267272#customize-theme-controls .customize-pane-child.current-panel,
    268273#customize-theme-controls .customize-pane-child.closing {
    269274        visibility: visible;
     275        height: auto;
     276        overflow: auto;
    270277}
    271278
    272279#customize-theme-controls .customize-pane-child {
    body { 
    275282        left: 0;
    276283        transform: translateX(100%);
    277284        visibility: hidden;
     285        height: 0;
     286        max-height: none;
     287        overflow: hidden;
     288}
     289
     290#customize-theme-controls .customize-pane-parent.closing,
     291#customize-info.closing,
     292#customize-theme-controls .customize-pane-child.closing {
     293        max-height: 100%;
     294}
     295
     296#customize-theme-controls .customize-pane-child.open,
     297#customize-theme-controls .customize-pane-child.current-panel {
     298        transform: translateX(0);
     299}
     300
     301#customize-theme-controls .customize-themes-panel.customize-pane-child {
     302        transform: translateX(-100%);
     303}
     304
     305#customize-theme-controls .customize-themes-panel.customize-pane-child.current-panel {
     306        transform: translateX(0);
    278307}
    279308
    280309#customize-theme-controls .customize-pane-child.accordion-section-content,
    body { 
    286315        padding: 12px;
    287316}
    288317
     318.wp-full-overlay #customize-controls .wp-full-overlay-sidebar-content {
     319        /* Promote to separate layer to avoid full-screen repaints */
     320        transform: translate3d(0,0,0);
     321}
     322
    289323.customize-section-description-container {
    290324        margin-bottom: 15px;
    291325}
    h3.customize-section-title { 
    357391        transition: left 0s;
    358392}
    359393
    360 .accordion-sub-container.control-panel-content.animating {
     394.accordion-sub-container.control-panel-content.closing {
    361395        display: block;
    362396}
    363397
    h3.customize-section-title { 
    479513        padding-left: 62px;
    480514}
    481515
    482 /*#customize-info,
    483 #customize-theme-controls > ul > .accordion-section {
    484         position: relative;
    485         left: 0;
    486         -webkit-transition: left ease-in-out .18s;
    487         transition: left ease-in-out .18s;
    488 }
    489 
    490 .ios #customize-info,
    491 .ios #customize-theme-controls > ul > .accordion-section {
    492         -webkit-transition: left 0s;
    493         transition: left 0s;
    494 }
    495 */
    496 /*.in-sub-panel #customize-info,
    497 .in-sub-panel #customize-theme-controls > ul > .accordion-section {
    498         left: -300px;
    499         width: 300px;
    500 }*/
    501 
    502 /*.in-sub-panel #customize-theme-controls .accordion-section.current-panel {
    503         width: 100%;
    504 }
    505 */
    506516#customize-theme-controls .control-section.current-panel {
    507517        padding: 0;
    508518}
    h3.customize-section-title { 
    523533        transition: left 0s;
    524534}
    525535
    526 .wp-full-overlay.section-open #customize-controls .wp-full-overlay-sidebar-content {
     536/*.wp-full-overlay.section-open #customize-controls .wp-full-overlay-sidebar-content {
    527537        visibility: hidden;
    528538        overflow-y: hidden;
    529539}
    530 
     540*/
    531541/*.wp-full-overlay.section-open .wp-full-overlay-sidebar-content .accordion-section.open {
    532542        visibility: visible;
    533543}
    p.customize-section-description { 
    10891099        animation: customize-reload .75s;
    10901100}
    10911101
    1092 .control-section-themes .accordion-section-title {
     1102#customize-controls .control-section-themes .accordion-section-title {
    10931103        cursor: default;
    10941104}
    10951105
    p.customize-section-description { 
    10991109        background-color: #fff;
    11001110}
    11011111
    1102 .control-section-themes .accordion-section-title {
     1112#customize-controls .control-section-themes .accordion-section-title {
    11031113        margin: 15px 0;
    11041114}
    11051115
    1106 .customize-themes-panel .accordion-section-title {
     1116#customize-controls .customize-themes-panel .accordion-section-title {
    11071117        margin: 15px -8px;
    11081118}
    11091119
    1110 .control-section-themes .accordion-section-title {
     1120#customize-controls .control-section-themes .accordion-section-title,
     1121#customize-controls .customize-themes-panel .accordion-section-title {
    11111122        padding-right: 100px; /* Space for the button */
    11121123}
    11131124
    1114 .control-section-themes .accordion-section-title span.customize-action,
     1125#customize-controls .control-section-themes .accordion-section-title span.customize-action,
    11151126#customize-controls .customize-section-title span.customize-action {
    11161127        font-size: 13px;
    11171128        display: block;
    11181129        font-weight: 400;
    11191130}
    11201131
    1121 .control-section-themes .accordion-section-title .change-theme,
    1122 .control-section-themes .accordion-section-title .customize-theme {
     1132#customize-controls .control-section-themes .accordion-section-title .change-theme,
     1133#customize-controls .customize-themes-panel .accordion-section-title .customize-theme {
    11231134        position: absolute;
    11241135        right: 10px;
    11251136        top: 50%;
    p.customize-section-description { 
    11271138        font-weight: normal;
    11281139}
    11291140
    1130 .control-section-themes .accordion-section-title:before {
     1141#customize-controls .control-section-themes .accordion-section-title:before {
    11311142        display: none;
    11321143}
    11331144
    1134 .customize-themes-panel {
    1135         display: none;
     1145#customize-controls .customize-themes-panel {
    11361146        padding: 0 8px;
    11371147        background: #f1f1f1;
    11381148        -webkit-box-sizing: border-box;
    p.customize-section-description { 
    11401150        box-sizing: border-box;
    11411151}
    11421152
    1143 .customize-themes-panel .accordion-section-title:first-child {
     1153#customize-controls .customize-themes-panel .accordion-section-title:first-child {
    11441154        margin-top: 0;
    11451155}
    11461156
    p.customize-section-description { 
    11491159        font-weight: 600;
    11501160}
    11511161
    1152 .customize-themes-panel > h2 {
     1162#customize-controls .customize-themes-panel > h2 {
    11531163        padding: 15px 8px 0 8px;
    11541164}
    11551165
    1156 .control-section.open .customize-themes-panel {
     1166/*.control-section.open .customize-themes-panel {
    11571167        display: block;
    1158 }
     1168}*/
    11591169
    11601170#customize-theme-controls .customize-themes-panel .accordion-section-content {
    11611171        background: transparent;
    p.customize-section-description { 
    12021212        width: 100%;
    12031213}
    12041214
    1205 #accordion-section-themes .accordion-section-title:after {
     1215/*#accordion-section-themes .accordion-section-title:after {*/
     1216.control-section-themes .accordion-section-title:after,
     1217.customize-themes-panel .accordion-section-title:after {
    12061218        display: none;
    12071219}
    12081220
    1209 #customize-theme-controls .control-section-themes.current-panel > h3.accordion-section-title {
     1221/*#customize-theme-controls .control-section-themes.current-panel > h3.accordion-section-title {
    12101222        left: 0;
    1211 }
     1223}*/
    12121224
    12131225.customize-themes-panel.control-panel-content {
    1214         position: absolute;
     1226/*      position: absolute;
    12151227        left: -100%;
    12161228        top: 0;
    1217         width: 100%;
     1229        width: 100%;*/
    12181230        border-top: 1px solid #ddd;
    12191231}
    12201232
    1221 .in-themes-panel #customize-info,
     1233/*.in-themes-panel #customize-info,
    12221234.in-themes-panel #customize-theme-controls > ul > .accordion-section {
    12231235        left: 100%;
    1224 }
     1236}*/
    12251237
    12261238/* Details View */
    12271239.wp-customizer .theme-overlay {
    p.customize-section-description { 
    12561268        text-align: right; /* Because there's only one action, match the pattern of media modals and right-align the action. */
    12571269}
    12581270
    1259 .modal-open .in-themes-panel #customize-controls .wp-full-overlay-sidebar-content {
    1260         overflow: visible; /* Prevent the top-level Customizer controls from becoming visible when elements on the right of the details modal are focused. */
     1271.in-themes-panel #customize-controls .wp-full-overlay-sidebar-content,
     1272.in-themes-panel #customize-controls #customize-theme-controls .control-panel-content {
     1273        transform: none; /* Prevent creating new stacking contexts and containing blocks for themes modal. */
    12611274}
    12621275
    12631276.ie8 .wp-customizer .theme-overlay .theme-header,
  • src/wp-admin/js/customize-controls.js

    diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js
    index 2b5a7a3..249114b 100644
    a b  
    257257                        if ( 0 === container.container.length ) {
    258258                                container.container = $( container.getContainer() );
    259259                        }
    260 
    261260                        container.content = container.getContent();
    262261
    263262                        container.deferred = {
     
    529528                        return '<li></li>';
    530529                },
    531530
     531                /**
     532                 * Detach and return the content html, extracted from the container html, if it exists.
     533                 *
     534                 * @since
     535                 */
    532536                getContent: function () {
    533537                        var container = this,
    534                                 list = container.container.find( 'ul:first' ),
     538                                list = container.container.find( '.accordion-section-content, .control-panel-content' ).first(), // container.container.find( 'ul:first' ),
    535539                                contentId = 'sub-accordion-list-' + container.id;
    536540
    537541                        container.setOwnership( contentId );
     
    542546                        } );
    543547                },
    544548
     549                /**
     550                 * Add new element to `aria-owned` property of the container.
     551                 *
     552                 * @since
     553                 */
    545554                setOwnership: function ( elementId ) {
    546555                        var container = this.container,
    547556                                ownedElements = container.attr( 'aria-owns' );
     
    658667                 */
    659668                attachEvents: function () {
    660669                        var section = this,
    661                                 expandCollapseEventTypes = 'click keydown',
    662                                 expandCollapseEventHandler,
    663                                 overlay = section.content.closest( '.wp-full-overlay' );
     670                                toggleHandler;
    664671
    665672                        // Expand/Collapse accordion sections on click.
    666                         expandCollapseEventHandler = function ( event ) {
     673                        toggleHandler = function ( event ) {
    667674                                if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
    668675                                        return;
    669676                                }
     
    676683                                }
    677684                        };
    678685
    679                         section.container.find( '.accordion-section-title' ).on( expandCollapseEventTypes, expandCollapseEventHandler );
    680                         section.content.find( '.customize-section-back' ).on( expandCollapseEventTypes, expandCollapseEventHandler );
     686                        section.container.find( '.accordion-section-title' ).on( 'click keydown', toggleHandler );
     687                        section.content.find( '.customize-section-back' ).on( 'click keydown', toggleHandler );
    681688                },
    682689
    683690                /**
     
    836843                 */
    837844                ready: function () {
    838845                        var section = this;
    839                         section.overlay = section.container.find( '.theme-overlay' );
     846                        section.overlay = section.content.find( '.theme-overlay' );
    840847                        section.template = wp.template( 'customize-themes-details-view' );
    841848
    842849                        // Bind global keyboard events.
     
    883890                 * @since 4.2.0
    884891                 */
    885892                attachEvents: function () {
    886                         var section = this;
     893                        var section = this,
     894                                content = section.content,
     895                                toggleHandler;
    887896
    888897                        // Expand/Collapse section/panel.
    889                         section.container.find( '.change-theme, .customize-theme' ).on( 'click keydown', function( event ) {
     898                        toggleHandler = function ( event ) {
    890899                                if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
    891900                                        return;
    892901                                }
     
    897906                                } else {
    898907                                        section.expand();
    899908                                }
    900                         });
     909                        };
     910
     911                        section.container.find( '.change-theme' ).on( 'click keydown', toggleHandler );
     912                        content.find( '.customize-theme' ).on( 'click keydown', toggleHandler );
    901913
    902914                        // Theme navigation in details view.
    903                         section.container.on( 'click keydown', '.left', function( event ) {
     915                        content.on( 'click keydown', '.left', function( event ) {
    904916                                if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
    905917                                        return;
    906918                                }
     
    910922                                section.previousTheme();
    911923                        });
    912924
    913                         section.container.on( 'click keydown', '.right', function( event ) {
     925                        content.on( 'click keydown', '.right', function( event ) {
    914926                                if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
    915927                                        return;
    916928                                }
     
    920932                                section.nextTheme();
    921933                        });
    922934
    923                         section.container.on( 'click keydown', '.theme-backdrop, .close', function( event ) {
     935                        content.on( 'click keydown', '.theme-backdrop, .close', function( event ) {
    924936                                if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
    925937                                        return;
    926938                                }
     
    931943                        });
    932944
    933945                        var renderScreenshots = _.throttle( _.bind( section.renderScreenshots, this ), 100 );
    934                         section.container.on( 'input', '#themes-filter', function( event ) {
     946                        content.on( 'input', '#themes-filter', function( event ) {
    935947                                var count,
    936948                                        term = event.currentTarget.value.toLowerCase().trim().replace( '-', ' ' ),
    937949                                        controls = section.controls();
     
    943955                                renderScreenshots();
    944956
    945957                                // Update theme count.
    946                                 count = section.container.find( 'li.customize-control:visible' ).length;
    947                                 section.container.find( '.theme-count' ).text( count );
     958                                count = content.find( 'li.customize-control:visible' ).length;
     959                                content.find( '.theme-count' ).text( count );
    948960                        });
    949961
    950962                        // Pre-load the first 3 theme screenshots.
     
    980992                        }
    981993
    982994                        // Note: there is a second argument 'args' passed
    983                         var position, scroll,
    984                                 panel = this,
    985                                 section = panel.container.closest( '.accordion-section' ),
     995                        var panel = this,
     996                                section = panel.content,
    986997                                overlay = section.closest( '.wp-full-overlay' ),
    987998                                container = section.closest( '.wp-full-overlay-sidebar-content' ),
    988                                 siblings = container.find( '.open' ),
     999                                info = overlay.find( '#customize-info' ),
     1000                                parent = overlay.find( '.customize-pane-parent' ),
    9891001                                customizeBtn = section.find( '.customize-theme' ),
    990                                 changeBtn = section.find( '.change-theme' ),
    991                                 content = section.find( '.control-panel-content' );
     1002                                changeBtn = section.find( '.change-theme' );
    9921003
    9931004                        if ( expanded ) {
    994 
    9951005                                // Collapse any sibling sections/panels
    9961006                                api.section.each( function ( otherSection ) {
    9971007                                        if ( otherSection !== panel ) {
     
    10021012                                        otherPanel.collapse( { duration: 0 } );
    10031013                                });
    10041014
    1005                                 content.show( 0, function() {
    1006                                         position = content.offset().top;
    1007                                         scroll = container.scrollTop();
    1008                                         content.css( 'margin-top', ( $( '#customize-header-actions' ).height() - position - scroll ) );
    1009                                         section.addClass( 'current-panel' );
    1010                                         overlay.addClass( 'in-themes-panel' );
    1011                                         container.scrollTop( 0 );
    1012                                         _.delay( panel.renderScreenshots, 10 ); // Wait for the controls
    1013                                         panel.$customizeSidebar.on( 'scroll.customize-themes-section', _.throttle( panel.renderScreenshots, 300 ) );
    1014                                         if ( args.completeCallback ) {
    1015                                                 args.completeCallback();
    1016                                         }
     1015                                section.one( normalizedTransitionendEventName, function () {
     1016                                        info.removeClass( 'closing' );
     1017                                        parent.removeClass( 'closing' );
     1018                                        overlay.removeClass( 'transitioning' );
     1019                                        customizeBtn.focus();
     1020                                        _.delay( panel.renderScreenshots, 10 );
    10171021                                } );
    1018                                 customizeBtn.focus();
     1022
     1023                                section.addClass( 'current-panel' );
     1024                                info.addClass( 'closing' );
     1025                                parent.addClass( 'closing' );
     1026                                overlay.addClass( 'in-themes-panel transitioning' );
     1027
     1028                                container.scrollTop( 0 );
     1029                                panel.$customizeSidebar.on( 'scroll.customize-themes-section', _.throttle( panel.renderScreenshots, 300 ) );
     1030
     1031                                if ( args.completeCallback ) {
     1032                                        args.completeCallback();
     1033                                }
    10191034                        } else {
    1020                                 siblings.removeClass( 'open' );
    1021                                 section.removeClass( 'current-panel' );
    1022                                 overlay.removeClass( 'in-themes-panel' );
    1023                                 panel.$customizeSidebar.off( 'scroll.customize-themes-section' );
    1024                                 content.delay( 180 ).hide( 0, function() {
    1025                                         content.css( 'margin-top', 'inherit' ); // Reset
    1026                                         if ( args.completeCallback ) {
    1027                                                 args.completeCallback();
    1028                                         }
     1035                                section.one( normalizedTransitionendEventName, function () {
     1036                                        section.removeClass( 'closing' );
     1037                                        info.removeClass( 'closing' );
     1038                                        parent.removeClass( 'closing' );
     1039                                        overlay.removeClass( 'transitioning' );
     1040                                        changeBtn.focus();
    10291041                                } );
     1042
     1043                                section.removeClass( 'current-panel' ).addClass( 'closing' );
     1044                                info.addClass( 'closing' );
     1045                                parent.addClass( 'closing' );
     1046                                overlay.removeClass( 'in-themes-panel' ).addClass( 'transitioning' );
     1047                                panel.$customizeSidebar.off( 'scroll.customize-themes-section' );
     1048
    10301049                                customizeBtn.attr( 'tabindex', '0' );
    1031                                 changeBtn.focus();
    10321050                                container.scrollTop( 0 );
     1051                               
     1052                                if ( args.completeCallback ) {
     1053                                        args.completeCallback();
     1054                                }
    10331055                        }
    10341056                },
    10351057
    10361058                /**
    1037                  * Recalculate the top margin.
    1038                  *
    1039                  * @since 4.4.0
    1040                  * @private
    1041                  */
    1042                 _recalculateTopMargin: function() {
    1043                         return;
    1044                         // api.Panel.prototype._recalculateTopMargin.call( this );
    1045                 },
    1046 
    1047                 /**
    10481059                 * Render control's screenshot if the control comes into view.
    10491060                 *
    10501061                 * @since 4.2.0
     
    16091620                                api.section( sectionId, function ( section ) {
    16101621                                        // Wait for the section to be ready/initialized
    16111622                                        section.deferred.embedded.done( function () {
    1612                                                 parentContainer = section.content; // section.container.find( 'ul:first' );
     1623                                                parentContainer = ( section.content.is( 'ul' ) ) ? section.content : section.content.find( 'ul:first' );
    16131624                                                if ( ! control.container.parent().is( parentContainer ) ) {
    16141625                                                        parentContainer.append( control.container );
    16151626                                                        control.renderContent();
     
    35073518                                var sections = panel.sections(),
    35083519                                        sectionContainers = _.pluck( sections, 'container' );
    35093520                                rootNodes.push( panel );
    3510                                 appendContainer = panel.content; // panel.container.find( 'ul:first' );
     3521                                appendContainer = ( panel.content.is( 'ul' ) ) ? panel.content : panel.content.find( 'ul:first' );
    35113522                                if ( ! api.utils.areElementListsEqual( sectionContainers, appendContainer.children( '[id]' ) ) ) {
    35123523                                        _( sections ).each( function ( section ) {
    35133524                                                appendContainer.append( section.container );
     
    35233534                                if ( ! section.panel() ) {
    35243535                                        rootNodes.push( section );
    35253536                                }
    3526                                 appendContainer = section.content; // section.container.find( 'ul:first' );
     3537                                appendContainer = ( section.content.is( 'ul' ) ) ? section.content : section.content.find( 'ul:first' );
    35273538                                if ( ! api.utils.areElementListsEqual( controlContainers, appendContainer.children( '[id]' ) ) ) {
    35283539                                        _( controls ).each( function ( control ) {
    35293540                                                appendContainer.append( control.container );
  • src/wp-admin/css/customize-controls.css

    From 667947a73e80266d8ea7d1605e1a3bf31e21d613 Mon Sep 17 00:00:00 2001
    From: Piotr Delawski <piotr.delawski@xwp.co>
    Date: Sat, 5 Mar 2016 21:24:21 +0100
    Subject: [PATCH 5/9] Fix 'Menus' panel to work with new sliding panes
     implementation. Fix `tabindex` and `focus` implementation.
    
    ---
     src/wp-admin/css/customize-controls.css  |  1 +
     src/wp-admin/css/customize-nav-menus.css |  8 +++---
     src/wp-admin/js/customize-controls.js    | 19 +++++++-------
     src/wp-admin/js/customize-nav-menus.js   | 43 ++++++++++++++++++++------------
     4 files changed, 42 insertions(+), 29 deletions(-)
    
    diff --git a/src/wp-admin/css/customize-controls.css b/src/wp-admin/css/customize-controls.css
    index b1b6ef5..8a92ba2 100644
    a b body { 
    309309#customize-theme-controls .customize-pane-child.accordion-section-content,
    310310#customize-theme-controls .customize-pane-child.accordion-sub-container {
    311311        display: block;
     312        overflow-x: hidden;
    312313}
    313314
    314315#customize-theme-controls .customize-pane-child.accordion-section-content {
  • src/wp-admin/css/customize-nav-menus.css

    diff --git a/src/wp-admin/css/customize-nav-menus.css b/src/wp-admin/css/customize-nav-menus.css
    index 16480e9..5f07560 100644
    a b  
    355355.reordering .menu-item-depth-10 > .menu-item-bar { margin-right: 150px; }
    356356.reordering .menu-item-depth-11 > .menu-item-bar { margin-right: 165px; }
    357357
    358 .control-section-nav_menu .menu .menu-item-edit-active {
     358.accordion-section-content.menu .menu-item-edit-active {
    359359        margin-left: 0;
    360360}
    361361
    362 .control-section-nav_menu .menu .menu-item-edit-active .menu-item-bar {
     362.accordion-section-content.menu .menu-item-edit-active .menu-item-bar {
    363363        margin-right: 0;
    364364}
    365365
    366 .control-section-nav_menu .menu .sortable-placeholder {
     366.accordion-section-content.menu .sortable-placeholder {
    367367        margin-top: 0;
    368368        margin-bottom: 1px;
    369369        max-width: -webkit-calc(100% - 2px);
     
    377377        float: none;
    378378}
    379379
    380 .control-section-nav_menu .menu ul.menu-item-transport .menu-item-bar {
     380.accordion-section-content.menu ul.menu-item-transport .menu-item-bar {
    381381        margin-top: 0;
    382382}
    383383
  • src/wp-admin/js/customize-controls.js

    diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js
    index 045cc57..09571a7 100644
    a b  
    392392                                        construct.container.stop( true, true ).slideUp( duration, args.completeCallback );
    393393                                }
    394394                        }
    395 
    396                         // Recalculate the margin-top immediately, not waiting for debounced reflow, to prevent momentary (100ms) vertical jiggle.
    397                         if ( expandedOtherPanel ) {
    398                                 expandedOtherPanel._recalculateTopMargin();
    399                         }
    400395                },
    401396
    402397                /**
     
    641636                                                        parentContainer = panel.content;
    642637                                                        if ( ! section.container.parent().is( parentContainer ) ) {
    643638                                                                parentContainer.append( section.container );
     639                                                        }
     640                                                        if ( ! section.content.parent().is( section.container ) ) {
    644641                                                                container.append( section.content );
    645642                                                        }
    646643                                                        section.deferred.embedded.resolve();
     
    651648                                        parentContainer = $( '.customize-pane-parent' ); // @todo This should be defined elsewhere, and to be configurable
    652649                                        if ( ! section.container.parent().is( parentContainer ) ) {
    653650                                                parentContainer.append( section.container );
     651                                        }
     652                                        if ( ! section.content.parent().is( section.container ) ) {
    654653                                                container.append( section.content );
    655654                                        }
    656655                                        section.deferred.embedded.resolve();
     
    733732                                info = overlay.find( '#customize-info' ),
    734733                                parent = overlay.find( '.customize-pane-parent' ),
    735734                                backBtn = content.find( '.customize-section-back' ),
    736                                 sectionTitle = content.find( '.accordion-section-title' ).first(),
     735                                sectionTitle = section.container.find( '.accordion-section-title' ).first(),
    737736                                expand;
    738737
    739738                        if ( expanded && ! content.hasClass( 'open' ) ) {
     
    999998                                info = overlay.find( '#customize-info' ),
    1000999                                parent = overlay.find( '.customize-pane-parent' ),
    10011000                                customizeBtn = section.find( '.customize-theme' ),
    1002                                 changeBtn = section.find( '.change-theme' );
     1001                                changeBtn = panel.container.find( '.change-theme' );
    10031002
    10041003                        if ( expanded ) {
    10051004                                // Collapse any sibling sections/panels
     
    12861285
    12871286                        if ( ! panel.container.parent().is( parentContainer ) ) {
    12881287                                parentContainer.append( panel.container );
     1288                        }
     1289                        if ( ! panel.content.parent().is( panel.container ) ) {
    12891290                                container.append( panel.content );
    12901291                                panel.renderContent();
    12911292                        }
     
    14061407                                container = accordionSection.closest( '.wp-full-overlay-sidebar-content' ),
    14071408                                info = overlay.find( '#customize-info' ),
    14081409                                parent = overlay.find( '.customize-pane-parent' ),
    1409                                 topPanel = accordionSection.find( '.accordion-section-title' ),
     1410                                topPanel = panel.container.find( '.accordion-section-title' ),
    14101411                                backBtn = accordionSection.find( '.customize-panel-back' ),
    14111412                                panelTitle = accordionSection.find( '.accordion-section-title' ).first();
    14121413
     
    14501451                                        info.removeClass( 'closing' );
    14511452                                        parent.removeClass( 'closing' );
    14521453                                        overlay.removeClass( 'transitioning' );
    1453                                         panelTitle.focus();
     1454                                        topPanel.focus();
    14541455                                } );
    14551456
    14561457                                accordionSection.removeClass( 'current-panel' ).addClass( 'closing' );
  • src/wp-admin/js/customize-nav-menus.js

    diff --git a/src/wp-admin/js/customize-nav-menus.js b/src/wp-admin/js/customize-nav-menus.js
    index cad39c6..cdeeac4 100644
    a b  
    539539                        api.Panel.prototype.attachEvents.call( this );
    540540
    541541                        var panel = this,
    542                                 panelMeta = panel.container.find( '.panel-meta' ),
     542                                panelMeta = panel.content.find( '.panel-meta' ),
    543543                                help = panelMeta.find( '.customize-help-toggle' ),
    544544                                content = panelMeta.find( '.customize-panel-description' ),
    545545                                options = $( '#screen-options-wrap' ),
     
    712712
    713713                        api.bind( 'pane-contents-reflowed', function() {
    714714                                // Skip menus that have been removed.
    715                                 if ( ! section.container.parent().length ) {
     715                                if ( ! section.content.parent().length ) {
    716716                                        return;
    717717                                }
    718                                 section.container.find( '.menu-item .menu-item-reorder-nav button' ).attr({ 'tabindex': '0', 'aria-hidden': 'false' });
    719                                 section.container.find( '.menu-item.move-up-disabled .menus-move-up' ).attr({ 'tabindex': '-1', 'aria-hidden': 'true' });
    720                                 section.container.find( '.menu-item.move-down-disabled .menus-move-down' ).attr({ 'tabindex': '-1', 'aria-hidden': 'true' });
    721                                 section.container.find( '.menu-item.move-left-disabled .menus-move-left' ).attr({ 'tabindex': '-1', 'aria-hidden': 'true' });
    722                                 section.container.find( '.menu-item.move-right-disabled .menus-move-right' ).attr({ 'tabindex': '-1', 'aria-hidden': 'true' });
     718                                section.content.find( '.menu-item .menu-item-reorder-nav button' ).attr({ 'tabindex': '0', 'aria-hidden': 'false' });
     719                                section.content.find( '.menu-item.move-up-disabled .menus-move-up' ).attr({ 'tabindex': '-1', 'aria-hidden': 'true' });
     720                                section.content.find( '.menu-item.move-down-disabled .menus-move-down' ).attr({ 'tabindex': '-1', 'aria-hidden': 'true' });
     721                                section.content.find( '.menu-item.move-left-disabled .menus-move-left' ).attr({ 'tabindex': '-1', 'aria-hidden': 'true' });
     722                                section.content.find( '.menu-item.move-right-disabled .menus-move-right' ).attr({ 'tabindex': '-1', 'aria-hidden': 'true' });
    723723                        } );
    724724                },
    725725
     
    830830                        var section = this;
    831831
    832832                        if ( expanded ) {
    833                                 wpNavMenu.menuList = section.container.find( '.accordion-section-content:first' );
     833                                wpNavMenu.menuList = section.content;
    834834                                wpNavMenu.targetList = wpNavMenu.menuList;
    835835
    836836                                // Add attributes needed by wpNavMenu
     
    892892                onChangeExpanded: function( expanded ) {
    893893                        var section = this,
    894894                                button = section.container.find( '.add-menu-toggle' ),
    895                                 content = section.container.find( '.new-menu-section-content' ),
     895                                content = section.content,
    896896                                customizer = section.container.closest( '.wp-full-overlay-sidebar-content' );
    897897                        if ( expanded ) {
    898898                                button.addClass( 'open' );
     
    906906                                content.slideUp( 'fast' );
    907907                                content.find( '.menu-name-field' ).removeClass( 'invalid' );
    908908                        }
     909                },
     910
     911                /**
     912                 * Detach and return the content html, extracted from the container html, if it exists.
     913                 *
     914                 * @since
     915                 */
     916                getContent: function () {
     917                        return this.container.find( 'ul:first' );
    909918                }
    910919        });
    911920
     
    17971806                 */
    17981807                ready: function() {
    17991808                        var control = this,
     1809                                section = api.section( control.section() ),
    18001810                                menuId = control.params.menu_id,
    18011811                                menu = control.setting(),
    18021812                                name,
     
    18131823                         * being deactivated.
    18141824                         */
    18151825                        control.active.validate = function() {
    1816                                 var value, section = api.section( control.section() );
     1826                                var value;
    18171827                                if ( section ) {
    18181828                                        value = section.active();
    18191829                                } else {
     
    18221832                                return value;
    18231833                        };
    18241834
    1825                         control.$controlSection = control.container.closest( '.control-section' );
     1835                        control.$controlSection = section.container;
    18261836                        control.$sectionContent = control.container.closest( '.accordion-section-content' );
    18271837
    18281838                        this._setupModel();
     
    20052015                        section = api.section( control.section() );
    20062016                        removeSection = function() {
    20072017                                section.container.remove();
     2018                                section.content.remove();
    20082019                                api.section.remove( section.id );
    20092020                        };
    20102021
     
    20962107                                        return;
    20972108                                }
    20982109
    2099                                 var section = control.container.closest( '.accordion-section' ),
     2110                                var section = api.section( control.section() ),
    21002111                                        menuId = control.params.menu_id,
    2101                                         controlTitle = section.find( '.accordion-section-title' ),
    2102                                         sectionTitle = section.find( '.customize-section-title h3' ),
    2103                                         location = section.find( '.menu-in-location' ),
     2112                                        controlTitle = section.container.find( '.accordion-section-title' ),
     2113                                        sectionTitle = section.content.find( '.customize-section-title h3' ),
     2114                                        location = section.container.find( '.menu-in-location' ),
    21042115                                        action = sectionTitle.find( '.customize-action' ),
    21052116                                        name = displayNavMenuName( menu.name );
    21062117
     
    21242135                                } );
    21252136
    21262137                                // Update the nav menu name in all location checkboxes.
    2127                                 section.find( '.customize-control-checkbox input' ).each( function() {
     2138                                section.content.find( '.customize-control-checkbox input' ).each( function() {
    21282139                                        if ( $( this ).prop( 'checked' ) ) {
    21292140                                                $( '.current-menu-location-name-' + $( this ).data( 'location-id' ) ).text( name );
    21302141                                        }
  • src/wp-admin/js/customize-controls.js

    From 0b64cfd4194259786eab51dc5fe9c20adf360c7e Mon Sep 17 00:00:00 2001
    From: Piotr Delawski <piotr.delawski@xwp.co>
    Date: Fri, 22 Apr 2016 18:57:56 +0200
    Subject: [PATCH 6/9] Fix expanding/collapsing of Themes panel. Remove unused
     `getNormalizedTransitionendEvent` function.
    
    ---
     src/wp-admin/js/customize-controls.js | 56 ++++++++++++-----------------------
     1 file changed, 19 insertions(+), 37 deletions(-)
    
    diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js
    index 74e8191..8e9fdad 100644
    a b  
    22(function( exports, $ ){
    33        var Container, focus, normalizedTransitionendEventName, api = wp.customize;
    44
    5         normalizedTransitionendEventName = (function () {
    6                 var el, transitions, prop;
    7                 el = document.createElement( 'div' );
    8                 transitions = {
    9                         'transition'      : 'transitionend',
    10                         'OTransition'     : 'oTransitionEnd',
    11                         'MozTransition'   : 'transitionend',
    12                         'WebkitTransition': 'webkitTransitionEnd'
    13                 };
    14                 prop = _.find( _.keys( transitions ), function( prop ) {
    15                         return ! _.isUndefined( el.style[ prop ] );
    16                 } );
    17                 if ( prop ) {
    18                         return transitions[ prop ];
    19                 } else {
    20                         return null;
    21                 }
    22         })();
    23 
    245        /**
    256         * A Customizer Setting.
    267         *
     
    192173         *
    193174         * @returns {String}
    194175         */
    195         api.utils.getNormalizedTransitionendEvent = function () {
    196                 var t,
    197                         undefined,
    198                         el = document.createElement( 'div' ),
    199                         transitions = {
    200                                 'transition'      : 'transitionend',
    201                                 'OTransition'     : 'oTransitionEnd',
    202                                 'MozTransition'   : 'transitionend',
    203                                 'WebkitTransition': 'webkitTransitionEnd'
    204                         };
    205 
    206                 for ( t in transitions ) {
    207                         if ( transitions.hasOwnProperty( t ) && undefined !== el.style[ t ] ) {
    208                                 return transitions[t];
    209                         }
     176        normalizedTransitionendEventName = (function () {
     177                var el, transitions, prop;
     178                el = document.createElement( 'div' );
     179                transitions = {
     180                        'transition'      : 'transitionend',
     181                        'OTransition'     : 'oTransitionEnd',
     182                        'MozTransition'   : 'transitionend',
     183                        'WebkitTransition': 'webkitTransitionEnd'
     184                };
     185                prop = _.find( _.keys( transitions ), function( prop ) {
     186                        return ! _.isUndefined( el.style[ prop ] );
     187                } );
     188                if ( prop ) {
     189                        return transitions[ prop ];
     190                } else {
     191                        return null;
    210192                }
    211         };
     193        })();
    212194
    213195        /**
    214196         * Base class for Panel and Section.
     
    1004986                                customizeBtn = section.find( '.customize-theme' ),
    1005987                                changeBtn = panel.container.find( '.change-theme' );
    1006988
    1007                         if ( expanded ) {
     989                        if ( expanded && ! section.hasClass( 'current-panel' ) ) {
    1008990                                // Collapse any sibling sections/panels
    1009991                                api.section.each( function ( otherSection ) {
    1010992                                        if ( otherSection !== panel ) {
     
    10341016                                if ( args.completeCallback ) {
    10351017                                        args.completeCallback();
    10361018                                }
    1037                         } else {
     1019                        } else if ( ! expanded && section.hasClass( 'current-panel' ) ) {
    10381020                                section.one( normalizedTransitionendEventName, function () {
    10391021                                        section.removeClass( 'closing' );
    10401022                                        info.removeClass( 'closing' );
  • src/wp-admin/js/customize-controls.js

    From 128aeac27023e957db781cb6295679c059adec35 Mon Sep 17 00:00:00 2001
    From: Piotr Delawski <piotr.delawski@xwp.co>
    Date: Fri, 22 Apr 2016 20:36:12 +0200
    Subject: [PATCH 7/9] Fix bugs related to focusing on control (particularly on
     shift+click).
    
    ---
     src/wp-admin/js/customize-controls.js | 26 +++++++++++++-------------
     1 file changed, 13 insertions(+), 13 deletions(-)
    
    diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js
    index 8e9fdad..3a6464b 100644
    a b  
    7777         * @param {Function} [params.completeCallback]
    7878         */
    7979        focus = function ( params ) {
    80                 var construct, completeCallback, focus, focusElement;
    81                 construct = this;
     80                var construct = this,
     81                        completeCallback, focus;
     82
    8283                params = params || {};
    8384                focus = function () {
    84                         var focusContainer;
    85                         if ( construct.extended( api.Panel ) && construct.expanded && construct.expanded() ) {
    86                                 focusContainer = construct.container.find( 'ul.control-panel-content' );
    87                         } else if ( construct.extended( api.Section ) && construct.expanded && construct.expanded() ) {
    88                                 focusContainer = construct.container.find( 'ul.accordion-section-content' );
    89                         } else {
    90                                 focusContainer = construct.container;
    91                         }
     85                        var focusContainer = construct.container,
     86                                focusElement;
    9287
    93                         focusElement = focusContainer.find( '.control-focus:first' );
     88                        if ( ( construct.extended( api.Panel ) || construct.extended( api.Section ) ) && construct.expanded && construct.expanded() ) {
     89                                focusContainer = ( construct.content.is( 'ul' ) ) ? construct.content : construct.content.find( 'ul:first' );
     90                        }
     91                        focusElement = focusContainer.find( '.control-focus, input, select, textarea, button' ).filter( ':visible' ).first();
    9492                        if ( 0 === focusElement.length ) {
    9593                                // Note that we can't use :focusable due to a jQuery UI issue. See: https://github.com/jquery/jquery-ui/pull/1583
    96                                 focusElement = focusContainer.find( 'input, select, textarea, button, object, a[href], [tabindex]' ).filter( ':visible' ).first();
     94                                focusElement = focusContainer.find( 'object, a[href], [tabindex]' ).filter( ':visible' ).first();
    9795                        }
    9896                        focusElement.focus();
    9997                };
     98
    10099                if ( params.completeCallback ) {
    101100                        completeCallback = params.completeCallback;
    102101                        params.completeCallback = function () {
     
    516515                 */
    517516                getContent: function () {
    518517                        var container = this,
    519                                 list = container.container.find( '.accordion-section-content, .control-panel-content' ).first(), // container.container.find( 'ul:first' ),
     518                                list = container.container.find( '.accordion-section-content, .control-panel-content' ).first(),
    520519                                contentId = 'sub-accordion-list-' + container.id;
    521520
    522521                        container.setOwnership( contentId );
     
    790789                                if ( args.completeCallback ) {
    791790                                        args.completeCallback();
    792791                                }
     792
    793793                        } else {
    794794                                if ( args.completeCallback ) {
    795795                                        args.completeCallback();
  • src/wp-admin/js/customize-controls.js

    From 540e939472de426abbc4c9640c565c1086449132 Mon Sep 17 00:00:00 2001
    From: Piotr Delawski <piotr.delawski@xwp.co>
    Date: Wed, 4 May 2016 22:33:49 +0200
    Subject: [PATCH 8/9] Clear jshint errors.
    
    ---
     src/wp-admin/js/customize-controls.js | 10 ++++------
     1 file changed, 4 insertions(+), 6 deletions(-)
    
    diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js
    index 245bf06..39de2d2 100644
    a b  
    521521                        container.setOwnership( contentId );
    522522
    523523                        return list.detach().attr( {
    524                                 id: contentId,
    525                                 class: 'customize-pane-child ' + list.attr( 'class' )
     524                                'id': contentId,
     525                                'class': 'customize-pane-child ' + list.attr( 'class' )
    526526                        } );
    527527                },
    528528
     
    12841284                 * @since 4.1.0
    12851285                 */
    12861286                attachEvents: function () {
    1287                         var meta, panel = this,
    1288                                 overlay = panel.content.closest( '.wp-full-overlay' );
     1287                        var meta, panel = this;
    12891288
    12901289                        // Expand/Collapse accordion sections on click.
    12911290                        panel.container.find( '.accordion-section-title' ).on( 'click keydown', function( event ) {
     
    13941393                                info = overlay.find( '#customize-info' ),
    13951394                                parent = overlay.find( '.customize-pane-parent' ),
    13961395                                topPanel = panel.container.find( '.accordion-section-title' ),
    1397                                 backBtn = accordionSection.find( '.customize-panel-back' ),
    1398                                 panelTitle = accordionSection.find( '.accordion-section-title' ).first();
     1396                                backBtn = accordionSection.find( '.customize-panel-back' );
    13991397
    14001398                        if ( expanded && ! accordionSection.hasClass( 'current-panel' ) ) {
    14011399
  • src/wp-admin/css/customize-controls.css

    From a8e46e18b3676314afd7c7e61b63fd3e21186536 Mon Sep 17 00:00:00 2001
    From: Piotr Delawski <piotr.delawski@xwp.co>
    Date: Sat, 7 May 2016 22:09:48 +0200
    Subject: [PATCH 9/9] Refine transitions handling in new panel/section
     structure. Clean JS and CSS code.
    
    ---
     src/wp-admin/css/customize-controls.css | 163 +++++-----------------
     src/wp-admin/js/customize-controls.js   | 238 +++++++++++++++++++++-----------
     2 files changed, 195 insertions(+), 206 deletions(-)
    
    diff --git a/src/wp-admin/css/customize-controls.css b/src/wp-admin/css/customize-controls.css
    index d38e02a..9b9e001 100644
    a b body { 
    218218        box-sizing: border-box;
    219219}
    220220
     221.wp-full-overlay #customize-controls .wp-full-overlay-sidebar-content {
     222        /* Promote to separate layer to avoid full-screen repaints */
     223        transform: translate3d(0,0,0);
     224}
     225
    221226#customize-info,
    222227#customize-theme-controls .customize-pane-parent,
    223228#customize-theme-controls .customize-pane-child {
    body { 
    228233        -webkit-box-sizing: border-box;
    229234        -moz-box-sizing: border-box;
    230235        box-sizing: border-box;
    231         transition: 0.48s transform cubic-bezier(0.19, 1, 0.22, 1); /* easeOutExpo */
     236        transition: 0.6s transform cubic-bezier(0.19, 1, 0.22, 1); /* easeOutExpo */
    232237}
    233238
    234239#customize-info,
    body { 
    238243        height: auto;
    239244        max-height: none;
    240245        overflow: auto;
    241         transform: translateX(0);
     246        transform: none;
    242247}
    243248
    244 .section-open #customize-theme-controls .customize-pane-parent,
    245 .in-sub-panel #customize-theme-controls .customize-pane-parent,
    246 .section-open #customize-info,
    247 .in-sub-panel #customize-info,
    248 .in-sub-panel.section-open #customize-theme-controls .customize-pane-child.current-panel {
    249         transform: translateX(-100%);
     249#customize-theme-controls .customize-pane-child {
     250        position: absolute;
     251        top: 0;
     252        left: 0;
     253        transform: translateX(100%);
     254        visibility: hidden;
     255        height: 0;
     256        max-height: none;
     257        overflow: hidden;
    250258}
    251259
    252 .in-themes-panel #customize-theme-controls .customize-pane-parent,
    253 .in-themes-panel #customize-info {
    254         transform: translateX(100%);
     260#customize-theme-controls .customize-pane-child.open,
     261#customize-theme-controls .customize-pane-child.current-panel,
     262#customize-theme-controls .customize-themes-panel.customize-pane-child.current-panel {
     263        transform: none;
    255264}
    256265
     266#customize-theme-controls .customize-themes-panel.customize-pane-child,
    257267.section-open #customize-theme-controls .customize-pane-parent,
    258268.in-sub-panel #customize-theme-controls .customize-pane-parent,
    259269.section-open #customize-info,
    260270.in-sub-panel #customize-info,
    261 .section-open.in-sub-panel #customize-theme-controls .customize-pane-child.current-panel {
     271.in-sub-panel.section-open #customize-theme-controls .customize-pane-child.current-panel,
     272.in-themes-panel #customize-theme-controls .customize-pane-parent,
     273.in-themes-panel #customize-info {
    262274        visibility: hidden;
    263275        height: 0;
    264276        overflow: hidden;
     277        transform: translateX(-100%);
    265278}
    266279
    267 .section-open #customize-theme-controls .customize-pane-parent.closing,
    268 .in-sub-panel #customize-theme-controls .customize-pane-parent.closing,
    269 .section-open #customize-info.closing,
    270 .in-sub-panel #customize-info.closing,
     280.section-open #customize-theme-controls .customize-pane-parent.transitioning,
     281.in-sub-panel #customize-theme-controls .customize-pane-parent.transitioning,
     282.in-themes-panel #customize-theme-controls .customize-pane-parent.transitioning,
     283.section-open #customize-info.transitioning,
     284.in-sub-panel #customize-info.transitioning,
     285.in-themes-panel #customize-info.transitioning,
    271286.transitioning.section-open.in-sub-panel #customize-theme-controls .customize-pane-child.current-panel,
    272287#customize-theme-controls .customize-pane-child.open,
    273288#customize-theme-controls .customize-pane-child.current-panel,
    274 #customize-theme-controls .customize-pane-child.closing {
     289#customize-theme-controls .customize-pane-child.transitioning {
    275290        visibility: visible;
    276291        height: auto;
    277292        overflow: auto;
    278293}
    279294
    280 #customize-theme-controls .customize-pane-child {
    281         position: absolute;
    282         top: 0;
    283         left: 0;
     295.in-themes-panel #customize-theme-controls .customize-pane-parent,
     296.in-themes-panel #customize-info {
    284297        transform: translateX(100%);
    285         visibility: hidden;
    286         height: 0;
    287         max-height: none;
    288         overflow: hidden;
    289 }
    290 
    291 #customize-theme-controls .customize-pane-parent.closing,
    292 #customize-info.closing,
    293 #customize-theme-controls .customize-pane-child.closing {
    294         max-height: 100%;
    295 }
    296 
    297 #customize-theme-controls .customize-pane-child.open,
    298 #customize-theme-controls .customize-pane-child.current-panel {
    299         transform: translateX(0);
    300 }
    301 
    302 #customize-theme-controls .customize-themes-panel.customize-pane-child {
    303         transform: translateX(-100%);
    304 }
    305 
    306 #customize-theme-controls .customize-themes-panel.customize-pane-child.current-panel {
    307         transform: translateX(0);
    308298}
    309299
    310300#customize-theme-controls .customize-pane-child.accordion-section-content,
    body { 
    317307        padding: 12px;
    318308}
    319309
    320 .wp-full-overlay #customize-controls .wp-full-overlay-sidebar-content {
    321         /* Promote to separate layer to avoid full-screen repaints */
    322         transform: translate3d(0,0,0);
    323 }
    324 
    325310.customize-section-description-container {
    326311        margin-bottom: 15px;
    327312}
    h3.customize-section-title { 
    361346        color: #555;
    362347}
    363348
    364 /*#customize-theme-controls {
    365         position: relative;
    366         left: 0;
    367         -webkit-transition: .18s left ease-in-out;
    368         transition: .18s left ease-in-out;
    369 }*/
    370 
    371 /*.ios #customize-theme-controls {
    372         -webkit-transition: left 0s;
    373         transition: left 0s;
    374 }*/
    375 
    376 /*.section-open #customize-info,
    377 .section-open #customize-theme-controls {
    378         left: -100%;
    379 }*/
    380 
    381349.accordion-sub-container.control-panel-content {
    382350        display: none;
    383351        position: absolute;
    h3.customize-section-title { 
    393361        transition: left 0s;
    394362}
    395363
    396 .accordion-sub-container.control-panel-content.closing {
     364.accordion-sub-container.control-panel-content.transitioning {
    397365        display: block;
    398366}
    399367
    h3.customize-section-title { 
    436404        -webkit-box-shadow: none;
    437405        box-shadow: none;
    438406        cursor: pointer;
    439         -webkit-transition: left .18s ease-in-out, color .1s ease-in-out, background .1s ease-in-out;
    440         transition: left .18s ease-in-out, color .1s ease-in-out, background .1s ease-in-out;
     407        -webkit-transition: color .1s ease-in-out, background .1s ease-in-out;
     408        transition: color .1s ease-in-out, background .1s ease-in-out;
    441409}
    442410
    443411.customize-section-back {
    444412        height: 74px;
    445413}
    446414
    447 .ios .customize-panel-back,
    448 .ios .customize-section-back {
    449         -webkit-transition: left 0s;
    450         transition: left 0s;
    451 }
    452 
    453415.ios .customize-panel-back {
    454416        display: none;
    455417}
    h3.customize-section-title { 
    515477        padding-left: 62px;
    516478}
    517479
    518 #customize-theme-controls .control-section.current-panel {
    519         padding: 0;
    520 }
    521 
    522 #customize-theme-controls .control-section > h3.accordion-section-title {
    523         position: relative;
    524         left: 0;
    525 }
    526 
    527 #customize-theme-controls .control-section.current-panel > h3.accordion-section-title {
    528         left: -354px;
    529         -webkit-transition: left ease-in-out .18s;
    530         transition: left ease-in-out .18s;
    531 }
    532 
    533 .ios #customize-theme-controls .control-section.current-panel > h3.accordion-section-title {
    534         -webkit-transition: left 0s;
    535         transition: left 0s;
    536 }
    537 
    538 /*.wp-full-overlay.section-open #customize-controls .wp-full-overlay-sidebar-content {
    539         visibility: hidden;
    540         overflow-y: hidden;
    541 }
    542 */
    543 /*.wp-full-overlay.section-open .wp-full-overlay-sidebar-content .accordion-section.open {
    544         visibility: visible;
    545 }
    546 
    547 .wp-full-overlay.section-open .wp-full-overlay-sidebar-content .accordion-section.open .accordion-section-content {
    548         overflow-y: auto;
    549 }*/
    550 
    551480p.customize-section-description {
    552481        font-style: normal;
    553482        margin-top: 22px;
    p.customize-section-description { 
    11591088        padding: 15px 8px 0 8px;
    11601089}
    11611090
    1162 /*.control-section.open .customize-themes-panel {
    1163         display: block;
    1164 }*/
    1165 
    11661091#customize-theme-controls .customize-themes-panel .accordion-section-content {
    11671092        background: transparent;
    11681093        display: block;
    p.customize-section-description { 
    12081133        width: 100%;
    12091134}
    12101135
    1211 /*#accordion-section-themes .accordion-section-title:after {*/
    12121136.control-section-themes .accordion-section-title:after,
    12131137.customize-themes-panel .accordion-section-title:after {
    12141138        display: none;
    12151139}
    12161140
    1217 /*#customize-theme-controls .control-section-themes.current-panel > h3.accordion-section-title {
    1218         left: 0;
    1219 }*/
    1220 
    12211141.customize-themes-panel.control-panel-content {
    1222 /*      position: absolute;
    1223         left: -100%;
    1224         top: 0;
    1225         width: 100%;*/
    12261142        border-top: 1px solid #ddd;
    12271143}
    12281144
    1229 /*.in-themes-panel #customize-info,
    1230 .in-themes-panel #customize-theme-controls > ul > .accordion-section {
    1231         left: 100%;
    1232 }*/
    1233 
    12341145/* Details View */
    12351146.wp-customizer .theme-overlay {
    12361147        display: none;
  • src/wp-admin/js/customize-controls.js

    diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js
    index 39de2d2..bec58c5 100644
    a b  
    718718                                parent = overlay.find( '.customize-pane-parent' ),
    719719                                backBtn = content.find( '.customize-section-back' ),
    720720                                sectionTitle = section.container.find( '.accordion-section-title' ).first(),
    721                                 expand;
     721                                expand, handleTransition;
     722
     723                        /**
     724                         * Handle transitions if they are supported by the browser.
     725                         *
     726                         * @param  {object} args
     727                         * @param  {object} args.focusElement  Object gaining focus on after transition.
     728                         */
     729                        handleTransition = function ( args ) {
     730                                var focus;
     731
     732                                focus = function () {
     733                                        if ( ! _.isUndefined( args.focusElement ) ) {
     734                                                args.focusElement.focus();
     735                                        }
     736                                };
     737
     738                                container.scrollTop( 0 );
     739                                if ( normalizedTransitionendEventName ) {
     740                                        _.each( [ content, overlay ], function ( el ) {
     741                                                el.addClass( 'transitioning' );
     742                                        } );
     743
     744                                        if ( ! overlay.hasClass( 'in-sub-panel' ) ) {
     745                                                _.each( [ info, parent ], function ( el ) {
     746                                                        el.addClass( 'transitioning' );
     747                                                } );
     748                                        }
     749
     750                                        content.on( normalizedTransitionendEventName, function ( event ) {
     751                                                if ( ! content.is( event.target ) || 'transform' !== event.originalEvent.propertyName ) {
     752                                                        return this;
     753                                                }
     754                                                content.off( normalizedTransitionendEventName );
     755
     756                                                _.each( [ content, overlay ], function ( el ) {
     757                                                        el.removeClass( 'transitioning' );
     758                                                } );
     759
     760                                                if ( info.hasClass( 'transitioning' ) ) {
     761                                                        _.each( [ info, parent ], function ( el ) {
     762                                                                el.removeClass( 'transitioning' );
     763                                                        } );
     764                                                }
     765
     766                                                focus();
     767                                                return this;
     768                                        } );
     769                                } else {
     770                                        focus();
     771                                }
     772                        };
    722773
    723774                        if ( expanded && ! content.hasClass( 'open' ) ) {
    724775
    725776                                if ( args.unchanged ) {
    726777                                        expand = args.completeCallback;
    727778                                } else {
    728                                         container.scrollTop( 0 );
    729779                                        expand = function() {
    730                                                 content.one( normalizedTransitionendEventName, function () {
    731                                                         info.removeClass( 'closing' );
    732                                                         parent.removeClass( 'closing' );
    733                                                         overlay.removeClass( 'transitioning' );
    734                                                         backBtn.focus();
    735                                                 } );
    736 
     780                                                handleTransition( { focusElement: backBtn } );
    737781                                                content.addClass( 'open' );
    738                                                 info.addClass( 'closing' );
    739                                                 parent.addClass( 'closing' );
    740                                                 overlay.addClass( 'section-open transitioning' );
     782                                                overlay.addClass( 'section-open' );
    741783
    742784                                                sectionTitle.attr( 'tabindex', '-1' );
    743785                                                backBtn.attr( 'tabindex', '0' );
     
    770812
    771813                        } else if ( ! expanded && content.hasClass( 'open' ) ) {
    772814
    773                                 content.one( normalizedTransitionendEventName, function () {
    774                                         content.removeClass( 'closing' );
    775                                         info.removeClass( 'closing' );
    776                                         parent.removeClass( 'closing' );
    777                                         overlay.removeClass( 'transitioning' );
    778                                         sectionTitle.focus();
    779                                 } );
    780 
    781                                 content.removeClass( 'open' ).addClass( 'closing' );
    782                                 info.addClass( 'closing' );
    783                                 parent.addClass( 'closing' );
    784                                 overlay.removeClass( 'section-open transitioning' );
     815                                handleTransition( { focusElement: sectionTitle } );
     816                                content.removeClass( 'open' );
     817                                overlay.removeClass( 'section-open' );
    785818
    786819                                backBtn.attr( 'tabindex', '-1' );
    787820                                sectionTitle.attr( 'tabindex', '0' );
     
    9841017                                info = overlay.find( '#customize-info' ),
    9851018                                parent = overlay.find( '.customize-pane-parent' ),
    9861019                                customizeBtn = section.find( '.customize-theme' ),
    987                                 changeBtn = panel.container.find( '.change-theme' );
     1020                                changeBtn = panel.container.find( '.change-theme' ),
     1021                                handleTransition;
     1022
     1023                        /**
     1024                         * Handle transitions if they are supported by the browser.
     1025                         *
     1026                         * @param  {object} args
     1027                         * @param  {object} args.focusElement  Object gaining focus on after transition.
     1028                         */
     1029                        handleTransition = function ( args ) {
     1030                                var focus, transitionedElements = [ section, info, parent, overlay ];
     1031                               
     1032                                focus = function () {
     1033                                        if ( ! _.isUndefined( args.focusElement ) ) {
     1034                                                args.focusElement.focus();
     1035                                        }
     1036                                };
     1037
     1038                                container.scrollTop( 0 );
     1039                                if ( normalizedTransitionendEventName ) {
     1040                                        _.each( transitionedElements, function ( el ) {
     1041                                                el.addClass( 'transitioning' );
     1042                                        } );
     1043
     1044                                        section.on( normalizedTransitionendEventName, function ( event ) {
     1045                                                if ( ! section.is( event.target ) || 'transform' !== event.originalEvent.propertyName ) {
     1046                                                        return this;
     1047                                                }
     1048                                                section.off( normalizedTransitionendEventName );
     1049
     1050                                                _.each( transitionedElements, function ( el ) {
     1051                                                        el.removeClass( 'transitioning' );
     1052                                                } );
     1053
     1054                                                focus();
     1055                                                _.delay( panel.renderScreenshots, 10 );
     1056                                                return this;
     1057                                        } );
     1058                                } else {
     1059                                        focus();
     1060                                }
     1061                        };
    9881062
    9891063                        if ( expanded && ! section.hasClass( 'current-panel' ) ) {
     1064
    9901065                                // Collapse any sibling sections/panels
    9911066                                api.section.each( function ( otherSection ) {
    9921067                                        if ( otherSection !== panel ) {
     
    9971072                                        otherPanel.collapse( { duration: 0 } );
    9981073                                });
    9991074
    1000                                 section.one( normalizedTransitionendEventName, function () {
    1001                                         info.removeClass( 'closing' );
    1002                                         parent.removeClass( 'closing' );
    1003                                         overlay.removeClass( 'transitioning' );
    1004                                         customizeBtn.focus();
    1005                                         _.delay( panel.renderScreenshots, 10 );
    1006                                 } );
    1007 
     1075                                handleTransition( { focusElement: customizeBtn } );
    10081076                                section.addClass( 'current-panel' );
    1009                                 info.addClass( 'closing' );
    1010                                 parent.addClass( 'closing' );
    1011                                 overlay.addClass( 'in-themes-panel transitioning' );
     1077                                overlay.addClass( 'in-themes-panel' );
    10121078
    1013                                 container.scrollTop( 0 );
    10141079                                panel.$customizeSidebar.on( 'scroll.customize-themes-section', _.throttle( panel.renderScreenshots, 300 ) );
    10151080
    10161081                                if ( args.completeCallback ) {
    10171082                                        args.completeCallback();
    10181083                                }
    10191084                        } else if ( ! expanded && section.hasClass( 'current-panel' ) ) {
    1020                                 section.one( normalizedTransitionendEventName, function () {
    1021                                         section.removeClass( 'closing' );
    1022                                         info.removeClass( 'closing' );
    1023                                         parent.removeClass( 'closing' );
    1024                                         overlay.removeClass( 'transitioning' );
    1025                                         changeBtn.focus();
    1026                                 } );
    10271085
    1028                                 section.removeClass( 'current-panel' ).addClass( 'closing' );
    1029                                 info.addClass( 'closing' );
    1030                                 parent.addClass( 'closing' );
    1031                                 overlay.removeClass( 'in-themes-panel' ).addClass( 'transitioning' );
     1086                                handleTransition( { focusElement: changeBtn } );
     1087                                section.removeClass( 'current-panel' );
     1088                                overlay.removeClass( 'in-themes-panel' );
     1089
    10321090                                panel.$customizeSidebar.off( 'scroll.customize-themes-section' );
    10331091
    10341092                                customizeBtn.attr( 'tabindex', '0' );
    1035                                 container.scrollTop( 0 );
    10361093                               
    10371094                                if ( args.completeCallback ) {
    10381095                                        args.completeCallback();
     
    13931450                                info = overlay.find( '#customize-info' ),
    13941451                                parent = overlay.find( '.customize-pane-parent' ),
    13951452                                topPanel = panel.container.find( '.accordion-section-title' ),
    1396                                 backBtn = accordionSection.find( '.customize-panel-back' );
     1453                                backBtn = accordionSection.find( '.customize-panel-back' ),
     1454                                handleTransition;
     1455
     1456                        /**
     1457                         * Handle transitions if they are supported by the browser.
     1458                         *
     1459                         * @param  {object} args
     1460                         * @param  {object} args.focusElement  Object gaining focus on after transition.
     1461                         */
     1462                        handleTransition = function ( args ) {
     1463                                var focus, transitionedElements = [ accordionSection, info, parent, overlay ];
     1464                               
     1465                                focus = function () {
     1466                                        if ( ! _.isUndefined( args.focusElement ) ) {
     1467                                                args.focusElement.focus();
     1468                                        }
     1469                                };
     1470
     1471                                container.scrollTop( 0 );
     1472                                if ( normalizedTransitionendEventName ) {
     1473                                        _.each( transitionedElements, function ( el ) {
     1474                                                el.addClass( 'transitioning' );
     1475                                        } );
     1476
     1477                                        accordionSection.on( normalizedTransitionendEventName, function ( event ) {
     1478                                                if ( ! accordionSection.is( event.target ) || 'transform' !== event.originalEvent.propertyName ) {
     1479                                                        return this;
     1480                                                }
     1481                                                accordionSection.off( normalizedTransitionendEventName );
     1482
     1483                                                _.each( transitionedElements, function ( el ) {
     1484                                                        el.removeClass( 'transitioning' );
     1485                                                } );
     1486
     1487                                                focus();
     1488                                                return this;
     1489                                        } );
     1490                                } else {
     1491                                        focus();
     1492                                }
     1493                        };
    13971494
    13981495                        if ( expanded && ! accordionSection.hasClass( 'current-panel' ) ) {
    13991496
     
    14091506                                        }
    14101507                                });
    14111508
    1412                                 accordionSection.one( normalizedTransitionendEventName, function () {
    1413                                         info.removeClass( 'closing' );
    1414                                         parent.removeClass( 'closing' );
    1415                                         overlay.removeClass( 'transitioning' );
    1416                                         backBtn.focus();
    1417                                 } );
    1418 
     1509                                handleTransition( { focusElement: backBtn } );
     1510                                overlay.addClass( 'in-sub-panel' );
    14191511                                accordionSection.addClass( 'current-panel' );
    1420                                 info.addClass( 'closing' );
    1421                                 parent.addClass( 'closing' );
    1422                                 overlay.addClass( 'in-sub-panel transitioning' );
    1423 
    1424                                 container.scrollTop( 0 );
    1425                                 if ( args.completeCallback ) {
    1426                                         args.completeCallback();
    1427                                 }
    14281512
    14291513                                topPanel.attr( 'tabindex', '-1' );
    14301514                                backBtn.attr( 'tabindex', '0' );
    14311515
    1432                         } else if ( ! expanded && accordionSection.hasClass( 'current-panel' ) ) {
    1433                                 accordionSection.one( normalizedTransitionendEventName, function () {
    1434                                         accordionSection.removeClass( 'closing' );
    1435                                         info.removeClass( 'closing' );
    1436                                         parent.removeClass( 'closing' );
    1437                                         overlay.removeClass( 'transitioning' );
    1438                                         topPanel.focus();
    1439                                 } );
    1440 
    1441                                 accordionSection.removeClass( 'current-panel' ).addClass( 'closing' );
    1442                                 info.addClass( 'closing' );
    1443                                 parent.addClass( 'closing' );
    1444                                 overlay.removeClass( 'in-sub-panel' ).addClass( 'transitioning' );
    1445 
    14461516                                if ( args.completeCallback ) {
    14471517                                        args.completeCallback();
    14481518                                }
    14491519
     1520                        } else if ( ! expanded && accordionSection.hasClass( 'current-panel' ) ) {
     1521
     1522                                handleTransition( { focusElement: topPanel } );
     1523                                overlay.removeClass( 'in-sub-panel' );
     1524                                accordionSection.removeClass( 'current-panel' );
     1525
    14501526                                topPanel.attr( 'tabindex', '0' );
    14511527                                backBtn.attr( 'tabindex', '-1' );
    14521528
    1453                                 container.scrollTop( 0 );
     1529                                if ( args.completeCallback ) {
     1530                                        args.completeCallback();
     1531                                }
    14541532                        }
    14551533                },
    14561534