Make WordPress Core

Changeset 38648


Ignore:
Timestamp:
09/23/2016 10:22:09 PM (10 years ago)
Author:
westonruter
Message:

Customize: Re-architect and harden panel/section UI logic.

Removes contents for sections and panels from being logically nested (in the DOM) in order to eliminate many issues related to using margin-top hacks. The element containing the link to expand the content element for panels and sections is now a sibling element to its content element: the content is removed from being nested at initialization. The content element is now available in a contentContainer property whereas the head element (containing the link to open the construct) is in a headContainer property. The existing container property is now a jQuery collection that contains both of these elements. Since the head element is no longer in an ancestor element to the content element, the aria-owns property is now used to maintain the relationship between the headContainer and the contentContainer. These changes are also accompanied by an improvement to the animation performance for the sliding panes.

Props delawski, celloexpressions.
Fixes #34391.
Fixes #34344.
Fixes #35947.

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/css/common.css

    r38640 r38648  
    33683368}
    33693369
    3370 .control-section .accordion-section-title {
     3370.control-section .accordion-section-title,
     3371.customize-pane-child .accordion-section-title {
    33713372        border-left: none;
    33723373        border-right: none;
     
    33763377}
    33773378
    3378 .control-section .accordion-section-title:after {
     3379.control-section .accordion-section-title:after,
     3380.customize-pane-child .accordion-section-title:after {
    33793381        top: 11px;
    33803382}
  • trunk/src/wp-admin/css/customize-controls.css

    r38602 r38648  
    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;
     
    230230}
    231231
     232#customize-info,
     233#customize-theme-controls .customize-pane-parent,
     234#customize-theme-controls .customize-pane-child {
     235        overflow: visible;
     236        width: 100%;
     237        margin: 0;
     238        padding: 0;
     239        -webkit-box-sizing: border-box;
     240        -moz-box-sizing: border-box;
     241        box-sizing: border-box;
     242        -webkit-transition: 0.18s -webkit-transform cubic-bezier(0.645, 0.045, 0.355, 1);
     243        transition: 0.18s -webkit-transform cubic-bezier(0.645, 0.045, 0.355, 1);
     244        transition: 0.18s transform cubic-bezier(0.645, 0.045, 0.355, 1);
     245        transition: 0.18s transform cubic-bezier(0.645, 0.045, 0.355, 1), 0.18s -webkit-transform cubic-bezier(0.645, 0.045, 0.355, 1); /* easeInOutCubic */
     246}
     247
     248#customize-info,
     249#customize-theme-controls .customize-pane-parent {
     250        position: relative;
     251        visibility: visible;
     252        height: auto;
     253        max-height: none;
     254        overflow: auto;
     255        -webkit-transform: none;
     256        -ms-transform: none;
     257        transform: none;
     258}
     259
     260#customize-theme-controls .customize-pane-child {
     261        position: absolute;
     262        top: 0;
     263        left: 0;
     264        visibility: hidden;
     265        height: 0;
     266        max-height: none;
     267        overflow: hidden;
     268        -webkit-transform: translateX(100%);
     269        -ms-transform: translateX(100%);
     270        transform: translateX(100%);
     271}
     272
     273#customize-theme-controls .customize-pane-child.open,
     274#customize-theme-controls .customize-pane-child.current-panel,
     275#customize-theme-controls .customize-themes-panel.customize-pane-child.current-panel {
     276        -webkit-transform: none;
     277        -ms-transform: none;
     278        transform: none;
     279}
     280
     281#customize-theme-controls .customize-themes-panel.customize-pane-child,
     282.section-open #customize-theme-controls .customize-pane-parent,
     283.in-sub-panel #customize-theme-controls .customize-pane-parent,
     284.section-open #customize-info,
     285.in-sub-panel #customize-info,
     286.in-sub-panel.section-open #customize-theme-controls .customize-pane-child.current-panel,
     287.in-themes-panel #customize-theme-controls .customize-pane-parent,
     288.in-themes-panel #customize-info {
     289        visibility: hidden;
     290        height: 0;
     291        overflow: hidden;
     292        -webkit-transform: translateX(-100%);
     293        -ms-transform: translateX(-100%);
     294        transform: translateX(-100%);
     295}
     296
     297.section-open #customize-theme-controls .customize-pane-parent.busy,
     298.in-sub-panel #customize-theme-controls .customize-pane-parent.busy,
     299.in-themes-panel #customize-theme-controls .customize-pane-parent.busy,
     300.section-open #customize-info.busy,
     301.in-sub-panel #customize-info.busy,
     302.in-themes-panel #customize-info.busy,
     303.busy.section-open.in-sub-panel #customize-theme-controls .customize-pane-child.current-panel,
     304#customize-theme-controls .customize-pane-child.open,
     305#customize-theme-controls .customize-pane-child.current-panel,
     306#customize-theme-controls .customize-pane-child.busy {
     307        visibility: visible;
     308        height: auto;
     309        overflow: auto;
     310}
     311
     312.in-themes-panel #customize-theme-controls .customize-pane-parent,
     313.in-themes-panel #customize-info {
     314        -webkit-transform: translateX(100%);
     315        -ms-transform: translateX(100%);
     316        transform: translateX(100%);
     317}
     318
     319#customize-theme-controls .customize-pane-child.accordion-section-content,
     320#customize-theme-controls .customize-pane-child.accordion-sub-container {
     321        display: block;
     322        overflow-x: hidden;
     323}
     324
     325#customize-theme-controls .customize-pane-child.accordion-section-content {
     326        padding: 12px;
     327}
     328
    232329.customize-section-description-container {
    233330        margin-bottom: 15px;
     
    269366}
    270367
    271 #customize-theme-controls {
    272         position: relative;
    273         left: 0;
    274         -webkit-transition: .18s left ease-in-out;
    275         transition: .18s left ease-in-out;
    276 }
    277 
    278 .ios #customize-theme-controls {
    279         -webkit-transition: left 0s;
    280         transition: left 0s;
    281 }
    282 
    283 .section-open #customize-info,
    284 .section-open #customize-theme-controls {
    285         left: -100%;
    286 }
    287 
    288368.accordion-sub-container.control-panel-content {
    289369        display: none;
    290370        position: absolute;
    291         left: 100%;
    292371        top: 0;
    293372        width: 100%;
    294         -webkit-transition: left ease-in-out .18s;
    295         transition: left ease-in-out .18s;
    296 }
    297 
    298 .ios .accordion-sub-container.control-panel-content {
    299         -webkit-transition: left 0s;
    300         transition: left 0s;
    301 }
    302 
    303 .accordion-sub-container.control-panel-content.animating {
     373}
     374
     375.accordion-sub-container.control-panel-content.busy {
    304376        display: block;
    305377}
     
    344416        box-shadow: none;
    345417        cursor: pointer;
    346         -webkit-transition: left .18s ease-in-out, color .1s ease-in-out, background .1s ease-in-out;
    347         transition: left .18s ease-in-out, color .1s ease-in-out, background .1s ease-in-out;
     418        -webkit-transition: color .1s ease-in-out, background .1s ease-in-out;
     419        transition: color .1s ease-in-out, background .1s ease-in-out;
    348420}
    349421
    350422.customize-section-back {
    351423        height: 74px;
    352 }
    353 
    354 .ios .customize-panel-back,
    355 .ios .customize-section-back {
    356         -webkit-transition: left 0s;
    357         transition: left 0s;
    358424}
    359425
     
    422488.in-sub-panel .wp-full-overlay-sidebar .wp-full-overlay-header {
    423489        padding-left: 62px;
    424 }
    425 
    426 #customize-info,
    427 #customize-theme-controls > ul > .accordion-section {
    428         position: relative;
    429         left: 0;
    430         -webkit-transition: left ease-in-out .18s;
    431         transition: left ease-in-out .18s;
    432 }
    433 
    434 .ios #customize-info,
    435 .ios #customize-theme-controls > ul > .accordion-section {
    436         -webkit-transition: left 0s;
    437         transition: left 0s;
    438 }
    439 
    440 .in-sub-panel #customize-info,
    441 .in-sub-panel #customize-theme-controls > ul > .accordion-section {
    442         left: -100%;
    443         width: 100%;
    444 }
    445 
    446 .in-sub-panel #customize-theme-controls .accordion-section.current-panel {
    447         width: 100%;
    448 }
    449 
    450 #customize-theme-controls .control-section.current-panel {
    451         padding: 0;
    452 }
    453 
    454 #customize-theme-controls .control-section > h3.accordion-section-title {
    455         position: relative;
    456         left: 0;
    457 }
    458 
    459 #customize-theme-controls .control-section.current-panel > h3.accordion-section-title {
    460         left: -354px;
    461         -webkit-transition: left ease-in-out .18s;
    462         transition: left ease-in-out .18s;
    463 }
    464 
    465 .ios #customize-theme-controls .control-section.current-panel > h3.accordion-section-title {
    466         -webkit-transition: left 0s;
    467         transition: left 0s;
    468 }
    469 
    470 .wp-full-overlay.section-open #customize-controls .wp-full-overlay-sidebar-content {
    471         visibility: hidden;
    472         overflow-y: hidden;
    473 }
    474 
    475 .wp-full-overlay.section-open .wp-full-overlay-sidebar-content .accordion-section.open {
    476         visibility: visible;
    477 }
    478 
    479 .wp-full-overlay.section-open .wp-full-overlay-sidebar-content .accordion-section.open .accordion-section-content {
    480         overflow-y: auto;
    481490}
    482491
     
    10061015#customize-theme-controls .control-section-themes > .accordion-section-title:hover, /* Not a focusable element. */
    10071016#customize-theme-controls .control-section-themes > .accordion-section-title {
    1008         margin: 15px 0;
    1009 }
    1010 
    1011 .customize-themes-panel .accordion-section-title {
     1017        margin: 0 0 15px;
     1018}
     1019
     1020#customize-controls .customize-themes-panel .accordion-section-title {
    10121021        margin: 15px -8px;
    10131022}
    10141023
    1015 .control-section-themes .accordion-section-title {
     1024#customize-controls .control-section-themes .accordion-section-title,
     1025#customize-controls .customize-themes-panel .accordion-section-title {
    10161026        padding-right: 100px; /* Space for the button */
    10171027}
    10181028
    1019 .control-section-themes .accordion-section-title span.customize-action,
     1029#customize-controls .control-section-themes .accordion-section-title span.customize-action,
    10201030#customize-controls .customize-section-title span.customize-action {
    10211031        font-size: 13px;
     
    10241034}
    10251035
    1026 .control-section-themes .accordion-section-title .change-theme,
    1027 .control-section-themes .accordion-section-title .customize-theme {
     1036#customize-controls .control-section-themes .accordion-section-title .change-theme,
     1037#customize-controls .customize-themes-panel .accordion-section-title .customize-theme {
    10281038        position: absolute;
    10291039        right: 10px;
     
    10331043}
    10341044
    1035 .control-section-themes .accordion-section-title:before {
     1045#customize-controls .control-section-themes .accordion-section-title:before {
    10361046        display: none;
    10371047}
    10381048
    1039 .customize-themes-panel {
    1040         display: none;
     1049#customize-controls .customize-themes-panel {
    10411050        padding: 0 8px;
    10421051        background: #f1f1f1;
     
    10461055}
    10471056
    1048 .customize-themes-panel .accordion-section-title:first-child {
     1057#customize-controls .customize-themes-panel .accordion-section-title:first-child {
    10491058        margin-top: 0;
    10501059}
     
    10551064}
    10561065
    1057 .customize-themes-panel > h2 {
     1066#customize-controls .customize-themes-panel > h2 {
    10581067        padding: 15px 8px 0 8px;
    1059 }
    1060 
    1061 .control-section.open .customize-themes-panel {
    1062         display: block;
    10631068}
    10641069
     
    11081113}
    11091114
    1110 #accordion-section-themes .accordion-section-title:after {
     1115.control-section-themes .accordion-section-title:after,
     1116.customize-themes-panel .accordion-section-title:after {
    11111117        display: none;
    11121118}
    11131119
    1114 #customize-theme-controls .control-section-themes.current-panel > h3.accordion-section-title {
    1115         left: 0;
    1116 }
    1117 
    11181120.customize-themes-panel.control-panel-content {
    1119         position: absolute;
    1120         left: -100%;
    1121         top: 0;
    1122         width: 100%;
    11231121        border-top: 1px solid #ddd;
    1124 }
    1125 
    1126 .in-themes-panel #customize-info,
    1127 .in-themes-panel #customize-theme-controls > ul > .accordion-section {
    1128         left: 100%;
    11291122}
    11301123
     
    11601153.wp-customizer .theme-overlay .theme-actions {
    11611154        text-align: right; /* Because there's only one action, match the pattern of media modals and right-align the action. */
    1162 }
    1163 
    1164 .modal-open .in-themes-panel #customize-controls .wp-full-overlay-sidebar-content {
    1165         overflow: visible; /* Prevent the top-level Customizer controls from becoming visible when elements on the right of the details modal are focused. */
    11661155}
    11671156
  • trunk/src/wp-admin/css/customize-nav-menus.css

    r38642 r38648  
    382382.reordering .menu-item-depth-11 > .menu-item-bar { margin-right: 165px; }
    383383
    384 .control-section-nav_menu .menu .menu-item-edit-active {
     384.control-section-nav_menu.menu .menu-item-edit-active {
    385385        margin-left: 0;
    386386}
    387387
    388 .control-section-nav_menu .menu .menu-item-edit-active .menu-item-bar {
     388.control-section-nav_menu.menu .menu-item-edit-active .menu-item-bar {
    389389        margin-right: 0;
    390390}
    391391
    392 .control-section-nav_menu .menu .sortable-placeholder {
     392.control-section-nav_menu.menu .sortable-placeholder {
    393393        margin-top: 0;
    394394        margin-bottom: 1px;
     
    404404}
    405405
    406 .control-section-nav_menu .menu ul.menu-item-transport .menu-item-bar {
     406.control-section-nav_menu.menu ul.menu-item-transport .menu-item-bar {
    407407        margin-top: 0;
    408408}
  • trunk/src/wp-admin/customize.php

    r37914 r38648  
    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>
  • trunk/src/wp-admin/js/customize-controls.js

    r38520 r38648  
    11/* global _wpCustomizeHeader, _wpCustomizeBackground, _wpMediaViewsL10n, MediaElementPlayer */
    22(function( exports, $ ){
    3         var Container, focus, api = wp.customize;
     3        var Container, focus, normalizedTransitionendEventName, api = wp.customize;
    44
    55        /**
     
    102102                focus = function () {
    103103                        var focusContainer;
    104                         if ( construct.extended( api.Panel ) && construct.expanded && construct.expanded() ) {
    105                                 focusContainer = construct.container.find( 'ul.control-panel-content' );
    106                         } else if ( construct.extended( api.Section ) && construct.expanded && construct.expanded() ) {
    107                                 focusContainer = construct.container.find( 'ul.accordion-section-content' );
     104                        if ( ( construct.extended( api.Panel ) || construct.extended( api.Section ) ) && construct.expanded && construct.expanded() ) {
     105                                focusContainer = construct.contentContainer;
    108106                        } else {
    109107                                focusContainer = construct.container;
     
    187185                return equal;
    188186        };
     187
     188        /**
     189         * Return browser supported `transitionend` event name.
     190         *
     191         * @since 4.7.0
     192         *
     193         * @returns {string|null} Normalized `transitionend` event name or null if CSS transitions are not supported.
     194         */
     195        normalizedTransitionendEventName = (function () {
     196                var el, transitions, prop;
     197                el = document.createElement( 'div' );
     198                transitions = {
     199                        'transition'      : 'transitionend',
     200                        'OTransition'     : 'oTransitionEnd',
     201                        'MozTransition'   : 'transitionend',
     202                        'WebkitTransition': 'webkitTransitionEnd'
     203                };
     204                prop = _.find( _.keys( transitions ), function( prop ) {
     205                        return ! _.isUndefined( el.style[ prop ] );
     206                } );
     207                if ( prop ) {
     208                        return transitions[ prop ];
     209                } else {
     210                        return null;
     211                }
     212        })();
    189213
    190214        /**
     
    239263                                container.container = $( container.getContainer() );
    240264                        }
     265                        container.headContainer = container.container;
     266                        container.contentContainer = container.getContent();
     267                        container.container = container.container.add( container.contentContainer );
    241268
    242269                        container.deferred = {
     
    326353                 */
    327354                onChangeActive: function( active, args ) {
    328                         var duration, construct = this, expandedOtherPanel;
     355                        var construct = this,
     356                                headContainer = construct.headContainer,
     357                                duration, expandedOtherPanel;
     358
    329359                        if ( args.unchanged ) {
    330360                                if ( args.completeCallback ) {
     
    353383                        }
    354384
    355                         if ( ! $.contains( document, construct.container[0] ) ) {
     385                        if ( ! $.contains( document, headContainer ) ) {
    356386                                // jQuery.fn.slideUp is not hiding an element if it is not in the DOM
    357                                 construct.container.toggle( active );
     387                                headContainer.toggle( active );
    358388                                if ( args.completeCallback ) {
    359389                                        args.completeCallback();
    360390                                }
    361391                        } else if ( active ) {
    362                                 construct.container.stop( true, true ).slideDown( duration, args.completeCallback );
     392                                headContainer.stop( true, true ).slideDown( duration, args.completeCallback );
    363393                        } else {
    364394                                if ( construct.expanded() ) {
     
    366396                                                duration: duration,
    367397                                                completeCallback: function() {
    368                                                         construct.container.stop( true, true ).slideUp( duration, args.completeCallback );
     398                                                        headContainer.stop( true, true ).slideUp( duration, args.completeCallback );
    369399                                                }
    370400                                        });
    371401                                } else {
    372                                         construct.container.stop( true, true ).slideUp( duration, args.completeCallback );
    373                                 }
    374                         }
    375 
    376                         // Recalculate the margin-top immediately, not waiting for debounced reflow, to prevent momentary (100ms) vertical jiggle.
    377                         if ( expandedOtherPanel ) {
    378                                 expandedOtherPanel._recalculateTopMargin();
     402                                        headContainer.stop( true, true ).slideUp( duration, args.completeCallback );
     403                                }
    379404                        }
    380405                },
     
    484509
    485510                /**
     511                 * Animate container state change if transitions are supported by the browser.
     512                 *
     513                 * @since 4.7.0
     514                 *
     515                 * @param {function} completeCallback Function to be called after transition is completed.
     516                 * @returns {void}
     517                 * @private
     518                 */
     519                _animateChangeExpanded: function( completeCallback ) {
     520                        // Return if CSS transitions are not supported.
     521                        if ( ! normalizedTransitionendEventName ) {
     522                                if ( completeCallback ) {
     523                                        completeCallback();
     524                                }
     525                                return;
     526                        }
     527
     528                        var construct = this,
     529                                content = construct.contentContainer,
     530                                overlay = content.closest( '.wp-full-overlay' ),
     531                                elements, transitionEndCallback;
     532
     533                        // Determine set of elements that are affected by the animation.
     534                        elements = overlay.add( content );
     535                        if ( _.isUndefined( construct.panel ) || '' === construct.panel() ) {
     536                                elements = elements.add( '#customize-info, .customize-pane-parent' );
     537                        }
     538
     539                        // Handle `transitionEnd` event.
     540                        transitionEndCallback = function( e ) {
     541                                if ( 2 !== e.eventPhase || ! $( e.target ).is( content ) ) {
     542                                        return;
     543                                }
     544                                content.off( normalizedTransitionendEventName, transitionEndCallback );
     545                                elements.removeClass( 'busy' );
     546                                if ( completeCallback ) {
     547                                        completeCallback();
     548                                }
     549                        };
     550                        content.on( normalizedTransitionendEventName, transitionEndCallback );
     551                        elements.addClass( 'busy' );
     552
     553                        // Prevent screen flicker when pane has been scrolled before expanding.
     554                        _.defer( function() {
     555                                var container = content.closest( '.wp-full-overlay-sidebar-content' ),
     556                                        currentScrollTop = container.scrollTop(),
     557                                        previousScrollTop = content.data( 'previous-scrollTop' ) || 0,
     558                                        expanded = construct.expanded();
     559
     560                                if ( expanded && 0 < currentScrollTop ) {
     561                                        content.css( 'top', currentScrollTop + 'px' );
     562                                        content.data( 'previous-scrollTop', currentScrollTop );
     563                                } else if ( ! expanded && 0 < currentScrollTop + previousScrollTop ) {
     564                                        content.css( 'top', previousScrollTop - currentScrollTop + 'px' );
     565                                        container.scrollTop( previousScrollTop );
     566                                }
     567                        } );
     568                },
     569
     570                /**
    486571                 * Bring the container into view and then expand this and bring it into view
    487572                 * @param {Object} [params]
     
    508593
    509594                        return '<li></li>';
     595                },
     596
     597                /**
     598                 * Find content element which is displayed when the section is expanded.
     599                 *
     600                 * After a construct is initialized, the return value will be available via the `contentContainer` property.
     601                 * By default the element will be related it to the parent container with `aria-owns` and detached.
     602                 * Custom panels and sections (such as the `NewMenuSection`) that do not have a sliding pane should
     603                 * just return the content element without needing to add the `aria-owns` element or detach it from
     604                 * the container. Such non-sliding pane custom sections also need to override the `onChangeExpanded`
     605                 * method to handle animating the panel/section into and out of view.
     606                 *
     607                 * @since 4.7.0
     608                 *
     609                 * @returns {jQuery} Detached content element.
     610                 */
     611                getContent: function() {
     612                        var construct = this,
     613                                container = construct.container,
     614                                content = container.find( '.accordion-section-content, .control-panel-content' ).first(),
     615                                contentId = 'sub-' + container.attr( 'id' ),
     616                                ownedElements = contentId,
     617                                alreadyOwnedElements = container.attr( 'aria-owns' );
     618
     619                        if ( alreadyOwnedElements ) {
     620                                ownedElements = ownedElements + ' ' + alreadyOwnedElements;
     621                        }
     622                        container.attr( 'aria-owns', ownedElements );
     623
     624                        return content.detach().attr( {
     625                                'id': contentId,
     626                                'class': 'customize-pane-child ' + content.attr( 'class' ) + ' ' + container.attr( 'class' )
     627                        } );
    510628                }
    511629        });
     
    553671                        section.panel = new api.Value();
    554672                        section.panel.bind( function ( id ) {
    555                                 $( section.container ).toggleClass( 'control-subsection', !! id );
     673                                $( section.headContainer ).toggleClass( 'control-subsection', !! id );
    556674                        });
    557675                        section.panel.set( section.params.panel || '' );
     
    570688                 */
    571689                embed: function () {
    572                         var section = this, inject;
     690                        var inject,
     691                                section = this,
     692                                container = $( '#customize-theme-controls' );
    573693
    574694                        // Watch for changes to the panel state
     
    580700                                                // The panel has been registered, wait for it to become ready/initialized
    581701                                                panel.deferred.embedded.done( function () {
    582                                                         parentContainer = panel.container.find( 'ul:first' );
    583                                                         if ( ! section.container.parent().is( parentContainer ) ) {
    584                                                                 parentContainer.append( section.container );
     702                                                        parentContainer = panel.contentContainer;
     703                                                        if ( ! section.headContainer.parent().is( parentContainer ) ) {
     704                                                                parentContainer.append( section.headContainer );
     705                                                        }
     706                                                        if ( ! section.contentContainer.parent().is( section.headContainer ) ) {
     707                                                                container.append( section.contentContainer );
    585708                                                        }
    586709                                                        section.deferred.embedded.resolve();
     
    589712                                } else {
    590713                                        // There is no panel, so embed the section in the root of the customizer
    591                                         parentContainer = $( '#customize-theme-controls' ).children( 'ul' ); // @todo This should be defined elsewhere, and to be configurable
    592                                         if ( ! section.container.parent().is( parentContainer ) ) {
    593                                                 parentContainer.append( section.container );
     714                                        parentContainer = $( '.customize-pane-parent' ); // @todo This should be defined elsewhere, and to be configurable
     715                                        if ( ! section.headContainer.parent().is( parentContainer ) ) {
     716                                                parentContainer.append( section.headContainer );
     717                                        }
     718                                        if ( ! section.contentContainer.parent().is( section.headContainer ) ) {
     719                                                container.append( section.contentContainer );
    594720                                        }
    595721                                        section.deferred.embedded.resolve();
     
    598724                        section.panel.bind( inject );
    599725                        inject( section.panel.get() ); // Since a section may never get a panel, assume that it won't ever get one
    600 
    601                         section.deferred.embedded.done(function() {
    602                                 // Fix the top margin after reflow.
    603                                 api.bind( 'pane-contents-reflowed', _.debounce( function() {
    604                                         section._recalculateTopMargin();
    605                                 }, 100 ) );
    606                         });
    607726                },
    608727
     
    670789                onChangeExpanded: function ( expanded, args ) {
    671790                        var section = this,
    672                                 container = section.container.closest( '.wp-full-overlay-sidebar-content' ),
    673                                 content = section.container.find( '.accordion-section-content' ),
    674                                 overlay = section.container.closest( '.wp-full-overlay' ),
    675                                 backBtn = section.container.find( '.customize-section-back' ),
    676                                 sectionTitle = section.container.find( '.accordion-section-title' ).first(),
    677                                 headerActionsHeight = $( '#customize-header-actions' ).height(),
    678                                 resizeContentHeight, expand, position, scroll;
    679 
    680                         if ( expanded && ! section.container.hasClass( 'open' ) ) {
     791                                container = section.headContainer.closest( '.wp-full-overlay-sidebar-content' ),
     792                                content = section.contentContainer,
     793                                overlay = section.headContainer.closest( '.wp-full-overlay' ),
     794                                backBtn = content.find( '.customize-section-back' ),
     795                                sectionTitle = section.headContainer.find( '.accordion-section-title' ).first(),
     796                                expand;
     797
     798                        if ( expanded && ! content.hasClass( 'open' ) ) {
    681799
    682800                                if ( args.unchanged ) {
    683801                                        expand = args.completeCallback;
    684802                                } else {
    685                                         container.scrollTop( 0 );
    686                                         resizeContentHeight = function() {
    687                                                 var matchMedia, offset;
    688                                                 matchMedia = window.matchMedia || window.msMatchMedia;
    689                                                 offset = 90; // 45px for customize header actions + 45px for footer actions.
    690 
    691                                                 // No footer on small screens.
    692                                                 if ( matchMedia && matchMedia( '(max-width: 640px)' ).matches ) {
    693                                                         offset = 45;
    694                                                 }
    695                                                 content.css( 'height', ( window.innerHeight - offset ) );
    696                                         };
    697                                         expand = function() {
    698                                                 section.container.addClass( 'open' );
     803                                        expand = $.proxy( function() {
     804                                                section._animateChangeExpanded( function() {
     805                                                        sectionTitle.attr( 'tabindex', '-1' );
     806                                                        backBtn.attr( 'tabindex', '0' );
     807
     808                                                        backBtn.focus();
     809                                                        content.css( 'top', '' );
     810                                                        container.scrollTop( 0 );
     811
     812                                                        if ( args.completeCallback ) {
     813                                                                args.completeCallback();
     814                                                        }
     815                                                } );
     816
     817                                                content.addClass( 'open' );
    699818                                                overlay.addClass( 'section-open' );
    700                                                 position = content.offset().top;
    701                                                 scroll = container.scrollTop();
    702                                                 content.css( 'margin-top', ( headerActionsHeight - position - scroll ) );
    703                                                 resizeContentHeight();
    704                                                 sectionTitle.attr( 'tabindex', '-1' );
    705                                                 backBtn.attr( 'tabindex', '0' );
    706                                                 backBtn.focus();
    707                                                 if ( args.completeCallback ) {
    708                                                         args.completeCallback();
    709                                                 }
    710 
    711                                                 // Fix the height after browser resize.
    712                                                 $( window ).on( 'resize.customizer-section', _.debounce( resizeContentHeight, 100 ) );
    713 
    714                                                 setTimeout( _.bind( section._recalculateTopMargin, section ), 0 );
    715                                         };
     819                                        }, this );
    716820                                }
    717821
     
    736840                                }
    737841
    738                         } else if ( ! expanded && section.container.hasClass( 'open' ) ) {
    739                                 section.container.removeClass( 'open' );
     842                        } else if ( ! expanded && content.hasClass( 'open' ) ) {
     843                                section._animateChangeExpanded( function() {
     844                                        backBtn.attr( 'tabindex', '-1' );
     845                                        sectionTitle.attr( 'tabindex', '0' );
     846
     847                                        sectionTitle.focus();
     848                                        content.css( 'top', '' );
     849
     850                                        if ( args.completeCallback ) {
     851                                                args.completeCallback();
     852                                        }
     853                                } );
     854
     855                                content.removeClass( 'open' );
    740856                                overlay.removeClass( 'section-open' );
    741                                 content.css( 'margin-top', '' );
    742                                 container.scrollTop( 0 );
    743                                 backBtn.attr( 'tabindex', '-1' );
    744                                 sectionTitle.attr( 'tabindex', '0' );
    745                                 sectionTitle.focus();
    746                                 if ( args.completeCallback ) {
    747                                         args.completeCallback();
    748                                 }
    749                                 $( window ).off( 'resize.customizer-section' );
     857
    750858                        } else {
    751859                                if ( args.completeCallback ) {
    752860                                        args.completeCallback();
    753861                                }
    754                         }
    755                 },
    756 
    757                 /**
    758                  * Recalculate the top margin.
    759                  *
    760                  * @since 4.4.0
    761                  * @private
    762                  */
    763                 _recalculateTopMargin: function() {
    764                         var section = this, content, offset, headerActionsHeight;
    765                         content = section.container.find( '.accordion-section-content' );
    766                         if ( 0 === content.length ) {
    767                                 return;
    768                         }
    769                         headerActionsHeight = $( '#customize-header-actions' ).height();
    770                         offset = ( content.offset().top - headerActionsHeight );
    771                         if ( 0 < offset ) {
    772                                 content.css( 'margin-top', ( parseInt( content.css( 'margin-top' ), 10 ) - offset ) );
    773862                        }
    774863                }
     
    9491038
    9501039                        // Note: there is a second argument 'args' passed
    951                         var position, scroll,
    952                                 panel = this,
    953                                 section = panel.container.closest( '.accordion-section' ),
     1040                        var panel = this,
     1041                                section = panel.contentContainer,
    9541042                                overlay = section.closest( '.wp-full-overlay' ),
    9551043                                container = section.closest( '.wp-full-overlay-sidebar-content' ),
    956                                 siblings = container.find( '.open' ),
    9571044                                customizeBtn = section.find( '.customize-theme' ),
    958                                 changeBtn = section.find( '.change-theme' ),
    959                                 content = section.find( '.control-panel-content' );
    960 
    961                         if ( expanded ) {
    962 
     1045                                changeBtn = panel.headContainer.find( '.change-theme' );
     1046
     1047                        if ( expanded && ! section.hasClass( 'current-panel' ) ) {
    9631048                                // Collapse any sibling sections/panels
    9641049                                api.section.each( function ( otherSection ) {
     
    9711056                                });
    9721057
    973                                 content.show( 0, function() {
    974                                         position = content.offset().top;
    975                                         scroll = container.scrollTop();
    976                                         content.css( 'margin-top', ( $( '#customize-header-actions' ).height() - position - scroll ) );
    977                                         section.addClass( 'current-panel' );
    978                                         overlay.addClass( 'in-themes-panel' );
     1058                                panel._animateChangeExpanded( function() {
     1059                                        changeBtn.attr( 'tabindex', '-1' );
     1060                                        customizeBtn.attr( 'tabindex', '0' );
     1061
     1062                                        customizeBtn.focus();
     1063                                        section.css( 'top', '' );
    9791064                                        container.scrollTop( 0 );
    980                                         _.delay( panel.renderScreenshots, 10 ); // Wait for the controls
    981                                         panel.$customizeSidebar.on( 'scroll.customize-themes-section', _.throttle( panel.renderScreenshots, 300 ) );
     1065
    9821066                                        if ( args.completeCallback ) {
    9831067                                                args.completeCallback();
    9841068                                        }
    9851069                                } );
    986                                 customizeBtn.focus();
    987                         } else {
    988                                 siblings.removeClass( 'open' );
    989                                 section.removeClass( 'current-panel' );
    990                                 overlay.removeClass( 'in-themes-panel' );
    991                                 panel.$customizeSidebar.off( 'scroll.customize-themes-section' );
    992                                 content.delay( 180 ).hide( 0, function() {
    993                                         content.css( 'margin-top', 'inherit' ); // Reset
     1070
     1071                                overlay.addClass( 'in-themes-panel' );
     1072                                section.addClass( 'current-panel' );
     1073
     1074                        } else if ( ! expanded && section.hasClass( 'current-panel' ) ) {
     1075                                panel._animateChangeExpanded( function() {
     1076                                        changeBtn.attr( 'tabindex', '0' );
     1077                                        customizeBtn.attr( 'tabindex', '-1' );
     1078
     1079                                        changeBtn.focus();
     1080                                        section.css( 'top', '' );
     1081
    9941082                                        if ( args.completeCallback ) {
    9951083                                                args.completeCallback();
    9961084                                        }
    9971085                                } );
    998                                 customizeBtn.attr( 'tabindex', '0' );
    999                                 changeBtn.focus();
    1000                                 container.scrollTop( 0 );
    1001                         }
    1002                 },
    1003 
    1004                 /**
    1005                  * Recalculate the top margin.
    1006                  *
    1007                  * @since 4.4.0
    1008                  * @private
    1009                  */
    1010                 _recalculateTopMargin: function() {
    1011                         api.Panel.prototype._recalculateTopMargin.call( this );
     1086
     1087                                overlay.removeClass( 'in-themes-panel' );
     1088                                section.removeClass( 'current-panel' );
     1089                        }
    10121090                },
    10131091
     
    12381316                embed: function () {
    12391317                        var panel = this,
    1240                                 parentContainer = $( '#customize-theme-controls > ul' ); // @todo This should be defined elsewhere, and to be configurable
    1241 
    1242                         if ( ! panel.container.parent().is( parentContainer ) ) {
    1243                                 parentContainer.append( panel.container );
     1318                                container = $( '#customize-theme-controls' ),
     1319                                parentContainer = $( '.customize-pane-parent' ); // @todo This should be defined elsewhere, and to be configurable
     1320
     1321                        if ( ! panel.headContainer.parent().is( parentContainer ) ) {
     1322                                parentContainer.append( panel.headContainer );
     1323                        }
     1324                        if ( ! panel.contentContainer.parent().is( panel.headContainer ) ) {
     1325                                container.append( panel.contentContainer );
    12441326                                panel.renderContent();
    12451327                        }
    1246 
    1247                         api.bind( 'pane-contents-reflowed', _.debounce( function() {
    1248                                 panel._recalculateTopMargin();
    1249                         }, 100 ) );
    12501328
    12511329                        panel.deferred.embedded.resolve();
     
    12591337
    12601338                        // Expand/Collapse accordion sections on click.
    1261                         panel.container.find( '.accordion-section-title' ).on( 'click keydown', function( event ) {
     1339                        panel.headContainer.find( '.accordion-section-title' ).on( 'click keydown', function( event ) {
    12621340                                if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
    12631341                                        return;
     
    12901368                                event.preventDefault(); // Keep this AFTER the key filter above
    12911369
    1292                                 meta = panel.container.find( '.panel-meta' );
    12931370                                if ( meta.hasClass( 'cannot-expand' ) ) {
    12941371                                        return;
     
    13601437
    13611438                        // Note: there is a second argument 'args' passed
    1362                         var position, scroll,
    1363                                 panel = this,
    1364                                 accordionSection = panel.container.closest( '.accordion-section' ),
     1439                        var panel = this,
     1440                                accordionSection = panel.contentContainer,
    13651441                                overlay = accordionSection.closest( '.wp-full-overlay' ),
    13661442                                container = accordionSection.closest( '.wp-full-overlay-sidebar-content' ),
    1367                                 siblings = container.find( '.open' ),
    1368                                 topPanel = overlay.find( '#customize-theme-controls > ul > .accordion-section > .accordion-section-title' ),
    1369                                 backBtn = accordionSection.find( '.customize-panel-back' ),
    1370                                 panelTitle = accordionSection.find( '.accordion-section-title' ).first(),
    1371                                 content = accordionSection.find( '.control-panel-content' ),
    1372                                 headerActionsHeight = $( '#customize-header-actions' ).height();
    1373 
    1374                         if ( expanded ) {
    1375 
     1443                                topPanel = panel.headContainer.find( '.accordion-section-title' ),
     1444                                backBtn = accordionSection.find( '.customize-panel-back' );
     1445
     1446                        if ( expanded && ! accordionSection.hasClass( 'current-panel' ) ) {
    13761447                                // Collapse any sibling sections/panels
    13771448                                api.section.each( function ( section ) {
     
    13861457                                });
    13871458
    1388                                 content.show( 0, function() {
    1389                                         content.parent().show();
    1390                                         position = content.offset().top;
    1391                                         scroll = container.scrollTop();
    1392                                         content.css( 'margin-top', ( headerActionsHeight - position - scroll ) );
    1393                                         accordionSection.addClass( 'current-panel' );
    1394                                         overlay.addClass( 'in-sub-panel' );
     1459                                panel._animateChangeExpanded( function() {
     1460                                        topPanel.attr( 'tabindex', '-1' );
     1461                                        backBtn.attr( 'tabindex', '0' );
     1462
     1463                                        backBtn.focus();
     1464                                        accordionSection.css( 'top', '' );
    13951465                                        container.scrollTop( 0 );
     1466
    13961467                                        if ( args.completeCallback ) {
    13971468                                                args.completeCallback();
    13981469                                        }
    13991470                                } );
    1400                                 topPanel.attr( 'tabindex', '-1' );
    1401                                 backBtn.attr( 'tabindex', '0' );
    1402                                 backBtn.focus();
    1403                                 panel._recalculateTopMargin();
    1404                         } else {
    1405                                 siblings.removeClass( 'open' );
    1406                                 accordionSection.removeClass( 'current-panel' );
    1407                                 overlay.removeClass( 'in-sub-panel' );
    1408                                 content.delay( 180 ).hide( 0, function() {
    1409                                         content.css( 'margin-top', 'inherit' ); // Reset
     1471
     1472                                overlay.addClass( 'in-sub-panel' );
     1473                                accordionSection.addClass( 'current-panel' );
     1474
     1475                        } else if ( ! expanded && accordionSection.hasClass( 'current-panel' ) ) {
     1476                                panel._animateChangeExpanded( function() {
     1477                                        topPanel.attr( 'tabindex', '0' );
     1478                                        backBtn.attr( 'tabindex', '-1' );
     1479
     1480                                        topPanel.focus();
     1481                                        accordionSection.css( 'top', '' );
     1482
    14101483                                        if ( args.completeCallback ) {
    14111484                                                args.completeCallback();
    14121485                                        }
    14131486                                } );
    1414                                 topPanel.attr( 'tabindex', '0' );
    1415                                 backBtn.attr( 'tabindex', '-1' );
    1416                                 panelTitle.focus();
    1417                                 container.scrollTop( 0 );
    1418                         }
    1419                 },
    1420 
    1421                 /**
    1422                  * Recalculate the top margin.
    1423                  *
    1424                  * @since 4.4.0
    1425                  * @private
    1426                  */
    1427                 _recalculateTopMargin: function() {
    1428                         var panel = this, headerActionsHeight, content, accordionSection;
    1429                         headerActionsHeight = $( '#customize-header-actions' ).height();
    1430                         accordionSection = panel.container.closest( '.accordion-section' );
    1431                         content = accordionSection.find( '.control-panel-content' );
    1432                         content.css( 'margin-top', ( parseInt( content.css( 'margin-top' ), 10 ) - ( content.offset().top - headerActionsHeight ) ) );
     1487
     1488                                overlay.removeClass( 'in-sub-panel' );
     1489                                accordionSection.removeClass( 'current-panel' );
     1490                        }
    14331491                },
    14341492
     
    14501508                                template = wp.template( 'customize-panel-default-content' );
    14511509                        }
    1452                         if ( template && panel.container ) {
    1453                                 panel.container.find( '.accordion-sub-container' ).html( template( panel.params ) );
     1510                        if ( template && panel.headContainer ) {
     1511                                panel.contentContainer.html( template( panel.params ) );
    14541512                        }
    14551513                }
     
    16271685                                        // Wait for the section to be ready/initialized
    16281686                                        section.deferred.embedded.done( function () {
    1629                                                 parentContainer = section.container.find( 'ul:first' );
     1687                                                parentContainer = ( section.contentContainer.is( 'ul' ) ) ? section.contentContainer : section.contentContainer.find( 'ul:first' );
    16301688                                                if ( ! control.container.parent().is( parentContainer ) ) {
    16311689                                                        parentContainer.append( control.container );
     
    35433601        api.reflowPaneContents = _.bind( function () {
    35443602
    3545                 var appendContainer, activeElement, rootContainers, rootNodes = [], wasReflowed = false;
     3603                var appendContainer, activeElement, rootHeadContainers, rootNodes = [], wasReflowed = false;
    35463604
    35473605                if ( document.activeElement ) {
     
    35523610                api.panel.each( function ( panel ) {
    35533611                        var sections = panel.sections(),
    3554                                 sectionContainers = _.pluck( sections, 'container' );
     3612                                sectionHeadContainers = _.pluck( sections, 'headContainer' );
    35553613                        rootNodes.push( panel );
    3556                         appendContainer = panel.container.find( 'ul:first' );
    3557                         if ( ! api.utils.areElementListsEqual( sectionContainers, appendContainer.children( '[id]' ) ) ) {
     3614                        appendContainer = ( panel.contentContainer.is( 'ul' ) ) ? panel.contentContainer : panel.contentContainer.find( 'ul:first' );
     3615                        if ( ! api.utils.areElementListsEqual( sectionHeadContainers, appendContainer.children( '[id]' ) ) ) {
    35583616                                _( sections ).each( function ( section ) {
    3559                                         appendContainer.append( section.container );
     3617                                        appendContainer.append( section.headContainer );
    35603618                                } );
    35613619                                wasReflowed = true;
     
    35703628                                rootNodes.push( section );
    35713629                        }
    3572                         appendContainer = section.container.find( 'ul:first' );
     3630                        appendContainer = ( section.contentContainer.is( 'ul' ) ) ? section.contentContainer : section.contentContainer.find( 'ul:first' );
    35733631                        if ( ! api.utils.areElementListsEqual( controlContainers, appendContainer.children( '[id]' ) ) ) {
    35743632                                _( controls ).each( function ( control ) {
     
    35813639                // Sort the root panels and sections
    35823640                rootNodes.sort( api.utils.prioritySort );
    3583                 rootContainers = _.pluck( rootNodes, 'container' );
    3584                 appendContainer = $( '#customize-theme-controls' ).children( 'ul' ); // @todo This should be defined elsewhere, and to be configurable
    3585                 if ( ! api.utils.areElementListsEqual( rootContainers, appendContainer.children() ) ) {
     3641                rootHeadContainers = _.pluck( rootNodes, 'headContainer' );
     3642                appendContainer = $( '#customize-theme-controls .customize-pane-parent' ); // @todo This should be defined elsewhere, and to be configurable
     3643                if ( ! api.utils.areElementListsEqual( rootHeadContainers, appendContainer.children() ) ) {
    35863644                        _( rootNodes ).each( function ( rootNode ) {
    3587                                 appendContainer.append( rootNode.container );
     3645                                appendContainer.append( rootNode.headContainer );
    35883646                        } );
    35893647                        wasReflowed = true;
  • trunk/src/wp-admin/js/customize-nav-menus.js

    r38624 r38648  
    852852                        api.bind( 'pane-contents-reflowed', function() {
    853853                                // Skip menus that have been removed.
    854                                 if ( ! section.container.parent().length ) {
     854                                if ( ! section.contentContainer.parent().length ) {
    855855                                        return;
    856856                                }
     
    970970
    971971                        if ( expanded ) {
    972                                 wpNavMenu.menuList = section.container.find( '.accordion-section-content:first' );
     972                                wpNavMenu.menuList = section.contentContainer;
    973973                                wpNavMenu.targetList = wpNavMenu.menuList;
    974974
     
    10321032                        var section = this,
    10331033                                button = section.container.find( '.add-menu-toggle' ),
    1034                                 content = section.container.find( '.new-menu-section-content' ),
    1035                                 customizer = section.container.closest( '.wp-full-overlay-sidebar-content' );
     1034                                content = section.contentContainer,
     1035                                customizer = section.headContainer.closest( '.wp-full-overlay-sidebar-content' );
    10361036                        if ( expanded ) {
    10371037                                button.addClass( 'open' );
     
    10461046                                content.find( '.menu-name-field' ).removeClass( 'invalid' );
    10471047                        }
     1048                },
     1049
     1050                /**
     1051                 * Find the content element.
     1052                 *
     1053                 * @since 4.7.0
     1054                 *
     1055                 * @returns {jQuery} Content UL element.
     1056                 */
     1057                getContent: function() {
     1058                        return this.container.find( 'ul:first' );
    10481059                }
    10491060        });
     
    20022013                ready: function() {
    20032014                        var control = this,
     2015                                section = api.section( control.section() ),
    20042016                                menuId = control.params.menu_id,
    20052017                                menu = control.setting(),
     
    20182030                         */
    20192031                        control.active.validate = function() {
    2020                                 var value, section = api.section( control.section() );
     2032                                var value;
    20212033                                if ( section ) {
    20222034                                        value = section.active();
     
    20272039                        };
    20282040
    2029                         control.$controlSection = control.container.closest( '.control-section' );
     2041                        control.$controlSection = section.headContainer;
    20302042                        control.$sectionContent = control.container.closest( '.accordion-section-content' );
    20312043
     
    23012313                                }
    23022314
    2303                                 var section = control.container.closest( '.accordion-section' ),
     2315                                var section = api.section( control.section() ),
    23042316                                        menuId = control.params.menu_id,
    2305                                         controlTitle = section.find( '.accordion-section-title' ),
    2306                                         sectionTitle = section.find( '.customize-section-title h3' ),
    2307                                         location = section.find( '.menu-in-location' ),
     2317                                        controlTitle = section.headContainer.find( '.accordion-section-title' ),
     2318                                        sectionTitle = section.contentContainer.find( '.customize-section-title h3' ),
     2319                                        location = section.headContainer.find( '.menu-in-location' ),
    23082320                                        action = sectionTitle.find( '.customize-action' ),
    23092321                                        name = displayNavMenuName( menu.name );
     
    23292341
    23302342                                // Update the nav menu name in all location checkboxes.
    2331                                 section.find( '.customize-control-checkbox input' ).each( function() {
     2343                                section.contentContainer.find( '.customize-control-checkbox input' ).each( function() {
    23322344                                        if ( $( this ).prop( 'checked' ) ) {
    23332345                                                $( '.current-menu-location-name-' + $( this ).data( 'location-id' ) ).text( name );
     
    26432655                        // Focus on the new menu section.
    26442656                        api.section( customizeId ).focus(); // @todo should we focus on the new menu's control and open the add-items panel? Thinking user flow...
    2645 
    2646                         // Fix an issue with extra space at top immediately after creating new menu.
    2647                         $( '#menu-to-edit' ).css( 'margin-top', 0 );
    26482657                }
    26492658        });
  • trunk/tests/qunit/wp-admin/js/customize-controls.js

    r37700 r38648  
    212212                ok( ! section.params.content );
    213213                ok( !! section.container );
    214                 ok( section.container.is( '.control-section.control-section-default' ) );
    215                 ok( 1 === section.container.find( '> .accordion-section-title' ).length );
    216                 ok( 1 === section.container.find( '> .accordion-section-content' ).length );
     214                ok( !! section.headContainer );
     215                ok( !! section.contentContainer );
     216                ok( section.container.has( section.headContainer ) );
     217                ok( section.container.has( section.contentContainer ) );
     218                ok( section.headContainer.is( '.control-section.control-section-default' ) );
     219                ok( 1 === section.headContainer.find( '> .accordion-section-title' ).length );
     220                ok( section.contentContainer.is( '.accordion-section-content' ) );
     221                equal( section.headContainer.attr( 'aria-owns' ), section.contentContainer.attr( 'id' ) );
    217222        } );
    218223
     
    226231                ok( ! section.params.content );
    227232                ok( !! section.container );
     233                ok( !! section.headContainer );
     234                ok( !! section.contentContainer );
     235                ok( section.container.has( section.headContainer ) );
     236                ok( section.container.has( section.contentContainer ) );
    228237                ok( section.container.is( '.control-section.control-section-titleless' ) );
    229                 ok( 0 === section.container.find( '> .accordion-section-title' ).length );
    230                 ok( 1 === section.container.find( '> .accordion-section-content' ).length );
     238                ok( 0 === section.headContainer.find( '> .accordion-section-title' ).length );
     239                ok( section.contentContainer.is( '.accordion-section-content' ) );
     240                equal( section.headContainer.attr( 'aria-owns' ), section.contentContainer.attr( 'id' ) );
    231241        } );
    232242        module( 'Customizer Custom Type Section Lacking Specific Template' );
     
    236246                ok( ! section.params.content );
    237247                ok( !! section.container );
    238                 ok( section.container.is( '.control-section.control-section-' + section.params.type ) );
    239                 ok( 1 === section.container.find( '> .accordion-section-title' ).length );
    240                 ok( 1 === section.container.find( '> .accordion-section-content' ).length );
     248                ok( !! section.headContainer );
     249                ok( !! section.contentContainer );
     250                ok( section.container.has( section.headContainer ) );
     251                ok( section.container.has( section.contentContainer ) );
     252                ok( section.headContainer.is( '.control-section.control-section-' + section.params.type ) );
     253                ok( 1 === section.headContainer.find( '> .accordion-section-title' ).length );
     254                ok( section.contentContainer.is( '.accordion-section-content' ) );
     255                equal( section.headContainer.attr( 'aria-owns' ), section.contentContainer.attr( 'id' ) );
    241256        } );
    242257        module( 'Customizer Section lacking any params' );
     
    271286                ok( !! panel.params.content );
    272287                ok( !! panel.container );
     288                ok( !! panel.headContainer );
     289                ok( !! panel.contentContainer );
     290                ok( panel.container.has( panel.headContainer ) );
     291                ok( panel.container.has( panel.contentContainer ) );
    273292        } );
    274293        test( 'Fixture panel has section among its sections()', function () {
     
    305324                ok( ! panel.params.content );
    306325                ok( !! panel.container );
    307                 ok( panel.container.is( '.control-panel.control-panel-default' ) );
    308                 ok( 1 === panel.container.find( '> .accordion-section-title' ).length );
    309                 ok( 1 === panel.container.find( '> .control-panel-content' ).length );
     326                ok( !! panel.headContainer );
     327                ok( !! panel.contentContainer );
     328                ok( panel.container.has( panel.headContainer ) );
     329                ok( panel.container.has( panel.contentContainer ) );
     330                ok( panel.headContainer.is( '.control-panel.control-panel-default' ) );
     331                ok( 1 === panel.headContainer.find( '> .accordion-section-title' ).length );
     332                ok( panel.contentContainer.is( '.control-panel-content' ) );
     333                equal( panel.headContainer.attr( 'aria-owns' ), panel.contentContainer.attr( 'id' ) );
    310334        } );
    311335
     
    319343                ok( ! panel.params.content );
    320344                ok( !! panel.container );
    321                 ok( panel.container.is( '.control-panel.control-panel-titleless' ) );
    322                 ok( 0 === panel.container.find( '> .accordion-section-title' ).length );
    323                 ok( 1 === panel.container.find( '> .control-panel-content' ).length );
     345                ok( !! panel.headContainer );
     346                ok( !! panel.contentContainer );
     347                ok( panel.container.has( panel.headContainer ) );
     348                ok( panel.container.has( panel.contentContainer ) );
     349                ok( panel.headContainer.is( '.control-panel.control-panel-titleless' ) );
     350                ok( 0 === panel.headContainer.find( '> .accordion-section-title' ).length );
     351                ok( panel.contentContainer.is( '.control-panel-content' ) );
     352                equal( panel.headContainer.attr( 'aria-owns' ), panel.contentContainer.attr( 'id' ) );
    324353        } );
    325354
     
    330359                ok( ! panel.params.content );
    331360                ok( !! panel.container );
    332                 ok( panel.container.is( '.control-panel.control-panel-' + panel.params.type ) );
    333                 ok( 1 === panel.container.find( '> .accordion-section-title' ).length );
    334                 ok( 1 === panel.container.find( '> .control-panel-content' ).length );
     361                ok( !! panel.headContainer );
     362                ok( !! panel.contentContainer );
     363                ok( panel.container.has( panel.headContainer ) );
     364                ok( panel.container.has( panel.contentContainer ) );
     365                ok( panel.headContainer.is( '.control-panel.control-panel-' + panel.params.type ) );
     366                ok( 1 === panel.headContainer.find( '> .accordion-section-title' ).length );
     367                ok( panel.contentContainer.is( '.control-panel-content' ) );
     368                equal( panel.headContainer.attr( 'aria-owns' ), panel.contentContainer.attr( 'id' ) );
    335369        } );
    336370        module( 'Customizer Panel lacking any params' );
  • trunk/tests/qunit/wp-admin/js/customize-widgets.js

    r35231 r38648  
    5959
    6060                panel.deferred.embedded.done( function() {
    61                         ok( 1 === panel.container.find( '.no-widget-areas-rendered-notice' ).length );
    62                         ok( panel.container.find( '.no-widget-areas-rendered-notice' ).is( ':visible' ) );
     61                        ok( 1 === panel.contentContainer.find( '.no-widget-areas-rendered-notice' ).length );
     62                        ok( panel.contentContainer.find( '.no-widget-areas-rendered-notice' ).is( ':visible' ) );
    6363                        api.section( 'sidebar-widgets-sidebar-1' ).active( true );
    6464                        api.control( 'sidebars_widgets[sidebar-1]' ).active( true );
    6565                        api.trigger( 'pane-contents-reflowed' );
    66                         ok( ! panel.container.find( '.no-widget-areas-rendered-notice' ).is( ':visible' ) );
     66                        ok( ! panel.contentContainer.find( '.no-widget-areas-rendered-notice' ).is( ':visible' ) );
    6767                } );
    6868
Note: See TracChangeset for help on using the changeset viewer.