diff --git a/src/wp-admin/css/common.css b/src/wp-admin/css/common.css
index c699ad8..3d9014a 100644
--- a/src/wp-admin/css/common.css
+++ b/src/wp-admin/css/common.css
@@ -3330,7 +3330,8 @@ img {
display: none;
}
-.control-section .accordion-section-title {
+.control-section .accordion-section-title,
+.customize-pane-child .accordion-section-title {
border-left: none;
border-right: none;
padding: 10px 10px 11px 14px;
@@ -3338,7 +3339,8 @@ img {
background: #fff;
}
-.control-section .accordion-section-title:after {
+.control-section .accordion-section-title:after,
+.customize-pane-child .accordion-section-title:after {
top: 11px;
}
diff --git a/src/wp-admin/css/customize-controls.css b/src/wp-admin/css/customize-controls.css
index a7648fd..d15b1e0 100644
--- a/src/wp-admin/css/customize-controls.css
+++ b/src/wp-admin/css/customize-controls.css
@@ -78,8 +78,8 @@ body {
line-height: 24px;
}
-#customize-controls .control-section .customize-section-title h3,
-#customize-controls .control-section h3.customize-section-title,
+#customize-controls .customize-pane-child .customize-section-title h3,
+#customize-controls .customize-pane-child h3.customize-section-title,
#customize-controls .customize-info .panel-title {
font-size: 20px;
font-weight: 200;
@@ -219,6 +219,94 @@ body {
box-sizing: border-box;
}
+.wp-full-overlay #customize-controls .wp-full-overlay-sidebar-content {
+ transform: translate3d(0, 0, 0); /* Promote to separate layer to avoid full-screen repaints */
+}
+
+#customize-info,
+#customize-theme-controls .customize-pane-parent,
+#customize-theme-controls .customize-pane-child {
+ overflow: visible;
+ width: 100%;
+ margin: 0;
+ padding: 0;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ transition: 0.36s transform cubic-bezier(0.645, 0.045, 0.355, 1); /* easeInOutCubic */
+}
+
+#customize-info,
+#customize-theme-controls .customize-pane-parent {
+ position: relative;
+ visibility: visible;
+ height: auto;
+ max-height: none;
+ overflow: auto;
+ transform: none;
+}
+
+#customize-theme-controls .customize-pane-child {
+ position: absolute;
+ top: 0;
+ left: 0;
+ transform: translateX(100%);
+ visibility: hidden;
+ height: 0;
+ max-height: none;
+ overflow: hidden;
+}
+
+#customize-theme-controls .customize-pane-child.open,
+#customize-theme-controls .customize-pane-child.current-panel,
+#customize-theme-controls .customize-themes-panel.customize-pane-child.current-panel {
+ transform: none;
+}
+
+#customize-theme-controls .customize-themes-panel.customize-pane-child,
+.section-open #customize-theme-controls .customize-pane-parent,
+.in-sub-panel #customize-theme-controls .customize-pane-parent,
+.section-open #customize-info,
+.in-sub-panel #customize-info,
+.in-sub-panel.section-open #customize-theme-controls .customize-pane-child.current-panel,
+.in-themes-panel #customize-theme-controls .customize-pane-parent,
+.in-themes-panel #customize-info {
+ visibility: hidden;
+ height: 0;
+ overflow: hidden;
+ transform: translateX(-100%);
+}
+
+.section-open #customize-theme-controls .customize-pane-parent.busy,
+.in-sub-panel #customize-theme-controls .customize-pane-parent.busy,
+.in-themes-panel #customize-theme-controls .customize-pane-parent.busy,
+.section-open #customize-info.busy,
+.in-sub-panel #customize-info.busy,
+.in-themes-panel #customize-info.busy,
+.busy.section-open.in-sub-panel #customize-theme-controls .customize-pane-child.current-panel,
+#customize-theme-controls .customize-pane-child.open,
+#customize-theme-controls .customize-pane-child.current-panel,
+#customize-theme-controls .customize-pane-child.busy {
+ visibility: visible;
+ height: auto;
+ overflow: auto;
+}
+
+.in-themes-panel #customize-theme-controls .customize-pane-parent,
+.in-themes-panel #customize-info {
+ transform: translateX(100%);
+}
+
+#customize-theme-controls .customize-pane-child.accordion-section-content,
+#customize-theme-controls .customize-pane-child.accordion-sub-container {
+ display: block;
+ overflow-x: hidden;
+}
+
+#customize-theme-controls .customize-pane-child.accordion-section-content {
+ padding: 12px;
+}
+
.customize-section-description-container {
margin-bottom: 15px;
}
@@ -258,39 +346,14 @@ h3.customize-section-title {
color: #555;
}
-#customize-theme-controls {
- position: relative;
- left: 0;
- -webkit-transition: .18s left ease-in-out;
- transition: .18s left ease-in-out;
-}
-
-.ios #customize-theme-controls {
- -webkit-transition: left 0s;
- transition: left 0s;
-}
-
-.section-open #customize-info,
-.section-open #customize-theme-controls {
- left: -100%;
-}
-
.accordion-sub-container.control-panel-content {
display: none;
position: absolute;
- left: 100%;
top: 0;
width: 100%;
- -webkit-transition: left ease-in-out .18s;
- transition: left ease-in-out .18s;
-}
-
-.ios .accordion-sub-container.control-panel-content {
- -webkit-transition: left 0s;
- transition: left 0s;
}
-.accordion-sub-container.control-panel-content.animating {
+.accordion-sub-container.control-panel-content.busy {
display: block;
}
@@ -333,20 +396,14 @@ h3.customize-section-title {
-webkit-box-shadow: none;
box-shadow: none;
cursor: pointer;
- -webkit-transition: left .18s ease-in-out, color .1s ease-in-out, background .1s ease-in-out;
- transition: left .18s ease-in-out, color .1s ease-in-out, background .1s ease-in-out;
+ -webkit-transition: color .1s ease-in-out, background .1s ease-in-out;
+ transition: color .1s ease-in-out, background .1s ease-in-out;
}
.customize-section-back {
height: 74px;
}
-.ios .customize-panel-back,
-.ios .customize-section-back {
- -webkit-transition: left 0s;
- transition: left 0s;
-}
-
.ios .customize-panel-back {
display: none;
}
@@ -412,63 +469,6 @@ h3.customize-section-title {
padding-left: 62px;
}
-#customize-info,
-#customize-theme-controls > ul > .accordion-section {
- position: relative;
- left: 0;
- -webkit-transition: left ease-in-out .18s;
- transition: left ease-in-out .18s;
-}
-
-.ios #customize-info,
-.ios #customize-theme-controls > ul > .accordion-section {
- -webkit-transition: left 0s;
- transition: left 0s;
-}
-
-.in-sub-panel #customize-info,
-.in-sub-panel #customize-theme-controls > ul > .accordion-section {
- left: -100%;
- width: 100%;
-}
-
-.in-sub-panel #customize-theme-controls .accordion-section.current-panel {
- width: 100%;
-}
-
-#customize-theme-controls .control-section.current-panel {
- padding: 0;
-}
-
-#customize-theme-controls .control-section > h3.accordion-section-title {
- position: relative;
- left: 0;
-}
-
-#customize-theme-controls .control-section.current-panel > h3.accordion-section-title {
- left: -354px;
- -webkit-transition: left ease-in-out .18s;
- transition: left ease-in-out .18s;
-}
-
-.ios #customize-theme-controls .control-section.current-panel > h3.accordion-section-title {
- -webkit-transition: left 0s;
- transition: left 0s;
-}
-
-.wp-full-overlay.section-open #customize-controls .wp-full-overlay-sidebar-content {
- visibility: hidden;
- overflow-y: hidden;
-}
-
-.wp-full-overlay.section-open .wp-full-overlay-sidebar-content .accordion-section.open {
- visibility: visible;
-}
-
-.wp-full-overlay.section-open .wp-full-overlay-sidebar-content .accordion-section.open .accordion-section-content {
- overflow-y: auto;
-}
-
p.customize-section-description {
font-style: normal;
margin-top: 22px;
@@ -976,7 +976,7 @@ p.customize-section-description {
animation: customize-reload .75s;
}
-.control-section-themes .accordion-section-title {
+#customize-controls .control-section-themes .accordion-section-title {
cursor: default;
}
@@ -986,27 +986,28 @@ p.customize-section-description {
background-color: #fff;
}
-.control-section-themes .accordion-section-title {
+#customize-controls .control-section-themes .accordion-section-title {
margin: 15px 0;
}
-.customize-themes-panel .accordion-section-title {
+#customize-controls .customize-themes-panel .accordion-section-title {
margin: 15px -8px;
}
-.control-section-themes .accordion-section-title {
+#customize-controls .control-section-themes .accordion-section-title,
+#customize-controls .customize-themes-panel .accordion-section-title {
padding-right: 100px; /* Space for the button */
}
-.control-section-themes .accordion-section-title span.customize-action,
+#customize-controls .control-section-themes .accordion-section-title span.customize-action,
#customize-controls .customize-section-title span.customize-action {
font-size: 13px;
display: block;
font-weight: 400;
}
-.control-section-themes .accordion-section-title .change-theme,
-.control-section-themes .accordion-section-title .customize-theme {
+#customize-controls .control-section-themes .accordion-section-title .change-theme,
+#customize-controls .customize-themes-panel .accordion-section-title .customize-theme {
position: absolute;
right: 10px;
top: 50%;
@@ -1014,12 +1015,11 @@ p.customize-section-description {
font-weight: 400;
}
-.control-section-themes .accordion-section-title:before {
+#customize-controls .control-section-themes .accordion-section-title:before {
display: none;
}
-.customize-themes-panel {
- display: none;
+#customize-controls .customize-themes-panel {
padding: 0 8px;
background: #f1f1f1;
-webkit-box-sizing: border-box;
@@ -1027,7 +1027,7 @@ p.customize-section-description {
box-sizing: border-box;
}
-.customize-themes-panel .accordion-section-title:first-child {
+#customize-controls .customize-themes-panel .accordion-section-title:first-child {
margin-top: 0;
}
@@ -1036,14 +1036,10 @@ p.customize-section-description {
font-weight: 600;
}
-.customize-themes-panel > h2 {
+#customize-controls .customize-themes-panel > h2 {
padding: 15px 8px 0 8px;
}
-.control-section.open .customize-themes-panel {
- display: block;
-}
-
#customize-theme-controls .customize-themes-panel .accordion-section-content {
background: transparent;
display: block;
@@ -1089,27 +1085,15 @@ p.customize-section-description {
width: 100%;
}
-#accordion-section-themes .accordion-section-title:after {
+.control-section-themes .accordion-section-title:after,
+.customize-themes-panel .accordion-section-title:after {
display: none;
}
-#customize-theme-controls .control-section-themes.current-panel > h3.accordion-section-title {
- left: 0;
-}
-
.customize-themes-panel.control-panel-content {
- position: absolute;
- left: -100%;
- top: 0;
- width: 100%;
border-top: 1px solid #ddd;
}
-.in-themes-panel #customize-info,
-.in-themes-panel #customize-theme-controls > ul > .accordion-section {
- left: 100%;
-}
-
/* Details View */
.wp-customizer .theme-overlay {
display: none;
@@ -1143,8 +1127,8 @@ p.customize-section-description {
text-align: right; /* Because there's only one action, match the pattern of media modals and right-align the action. */
}
-.modal-open .in-themes-panel #customize-controls .wp-full-overlay-sidebar-content {
- overflow: visible; /* Prevent the top-level Customizer controls from becoming visible when elements on the right of the details modal are focused. */
+.in-themes-panel #customize-controls .wp-full-overlay-sidebar-content {
+ transform: none; /* Prevent creating new stacking contexts and containing blocks for themes modal. */
}
.ie8 .wp-customizer .theme-overlay .theme-header,
diff --git a/src/wp-admin/css/customize-nav-menus.css b/src/wp-admin/css/customize-nav-menus.css
index 66d2b08..7250da7 100644
--- a/src/wp-admin/css/customize-nav-menus.css
+++ b/src/wp-admin/css/customize-nav-menus.css
@@ -377,15 +377,15 @@
.reordering .menu-item-depth-10 > .menu-item-bar { margin-right: 150px; }
.reordering .menu-item-depth-11 > .menu-item-bar { margin-right: 165px; }
-.control-section-nav_menu .menu .menu-item-edit-active {
+.accordion-section-content.menu .menu-item-edit-active {
margin-left: 0;
}
-.control-section-nav_menu .menu .menu-item-edit-active .menu-item-bar {
+.accordion-section-content.menu .menu-item-edit-active .menu-item-bar {
margin-right: 0;
}
-.control-section-nav_menu .menu .sortable-placeholder {
+.accordion-section-content.menu .sortable-placeholder {
margin-top: 0;
margin-bottom: 1px;
max-width: -webkit-calc(100% - 2px);
@@ -399,7 +399,7 @@
float: none;
}
-.control-section-nav_menu .menu ul.menu-item-transport .menu-item-bar {
+.accordion-section-content.menu ul.menu-item-transport .menu-item-bar {
margin-top: 0;
}
diff --git a/src/wp-admin/customize.php b/src/wp-admin/customize.php
index bd8e118..6c0b20d 100644
--- a/src/wp-admin/customize.php
+++ b/src/wp-admin/customize.php
@@ -142,7 +142,7 @@
diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js
index 7078cfd..712c045 100644
--- a/src/wp-admin/js/customize-controls.js
+++ b/src/wp-admin/js/customize-controls.js
@@ -1,6 +1,6 @@
/* global _wpCustomizeHeader, _wpCustomizeBackground, _wpMediaViewsL10n, MediaElementPlayer */
(function( exports, $ ){
- var Container, focus, api = wp.customize;
+ var Container, focus, normalizedTransitionendEventName, api = wp.customize;
/**
* A Customizer Setting.
@@ -96,26 +96,25 @@
* @param {Function} [params.completeCallback]
*/
focus = function ( params ) {
- var construct, completeCallback, focus, focusElement;
- construct = this;
+ var construct = this,
+ completeCallback, focus;
+
params = params || {};
focus = function () {
- var focusContainer;
- if ( construct.extended( api.Panel ) && construct.expanded && construct.expanded() ) {
- focusContainer = construct.container.find( 'ul.control-panel-content' );
- } else if ( construct.extended( api.Section ) && construct.expanded && construct.expanded() ) {
- focusContainer = construct.container.find( 'ul.accordion-section-content' );
- } else {
- focusContainer = construct.container;
- }
+ var focusContainer = construct.container,
+ focusElement;
- focusElement = focusContainer.find( '.control-focus:first' );
+ if ( ( construct.extended( api.Panel ) || construct.extended( api.Section ) ) && construct.expanded && construct.expanded() ) {
+ focusContainer = ( construct.content.is( 'ul' ) ) ? construct.content : construct.content.find( 'ul:first' );
+ }
+ focusElement = focusContainer.find( '.control-focus, input, select, textarea, button' ).filter( ':visible' ).first();
if ( 0 === focusElement.length ) {
// Note that we can't use :focusable due to a jQuery UI issue. See: https://github.com/jquery/jquery-ui/pull/1583
- focusElement = focusContainer.find( 'input, select, textarea, button, object, a[href], [tabindex]' ).filter( ':visible' ).first();
+ focusElement = focusContainer.find( 'object, a[href], [tabindex]' ).filter( ':visible' ).first();
}
focusElement.focus();
};
+
if ( params.completeCallback ) {
completeCallback = params.completeCallback;
params.completeCallback = function () {
@@ -188,6 +187,32 @@
};
/**
+ * Return browser supported `transitionend` event name
+ *
+ * @since
+ *
+ * @returns {String}
+ */
+ normalizedTransitionendEventName = (function () {
+ var el, transitions, prop;
+ el = document.createElement( 'div' );
+ transitions = {
+ 'transition' : 'transitionend',
+ 'OTransition' : 'oTransitionEnd',
+ 'MozTransition' : 'transitionend',
+ 'WebkitTransition': 'webkitTransitionEnd'
+ };
+ prop = _.find( _.keys( transitions ), function( prop ) {
+ return ! _.isUndefined( el.style[ prop ] );
+ } );
+ if ( prop ) {
+ return transitions[ prop ];
+ } else {
+ return null;
+ }
+ })();
+
+ /**
* Base class for Panel and Section.
*
* @since 4.1.0
@@ -238,6 +263,7 @@
if ( 0 === container.container.length ) {
container.container = $( container.getContainer() );
}
+ container.content = container.getContent();
container.deferred = {
embedded: new $.Deferred()
@@ -372,11 +398,6 @@
construct.container.stop( true, true ).slideUp( duration, args.completeCallback );
}
}
-
- // Recalculate the margin-top immediately, not waiting for debounced reflow, to prevent momentary (100ms) vertical jiggle.
- if ( expandedOtherPanel ) {
- expandedOtherPanel._recalculateTopMargin();
- }
},
/**
@@ -426,6 +447,12 @@
},
/**
+ * To override by subclass, handle CSS transitions/animations made on the container.
+ * @abstract
+ */
+ animateChangeExpanded: function() {},
+
+ /**
* Handle the toggle logic for expand/collapse.
*
* @param {Boolean} expanded - The new state to apply.
@@ -507,6 +534,44 @@
}
return '';
+ },
+
+ /**
+ * Detach and return the content html, extracted from the container html, if it exists.
+ *
+ * @since
+ */
+ getContent: function () {
+ var container = this,
+ list = container.container.find( '.accordion-section-content, .control-panel-content' ).first(),
+ contentId = 'sub-accordion-list-' + container.id;
+
+ container.setOwnership( contentId );
+
+ return list.detach().attr( {
+ 'id': contentId,
+ 'class': 'customize-pane-child ' + list.attr( 'class' )
+ } );
+ },
+
+ /**
+ * Add new element to `aria-owned` property of the container.
+ *
+ * @since
+ */
+ setOwnership: function ( elementId ) {
+ var container = this.container,
+ ownedElements = container.attr( 'aria-owns' );
+
+ if ( _.isUndefined( ownedElements ) ) {
+ container.attr( {
+ 'aria-owns': elementId
+ } );
+ } else {
+ container.attr( {
+ 'aria-owns': ownedElements + ' ' + elementId
+ } );
+ }
}
});
@@ -569,7 +634,9 @@
* @since 4.1.0
*/
embed: function () {
- var section = this, inject;
+ var inject,
+ section = this,
+ container = $( '#customize-theme-controls' );
// Watch for changes to the panel state
inject = function ( panelId ) {
@@ -579,31 +646,30 @@
api.panel( panelId, function ( panel ) {
// The panel has been registered, wait for it to become ready/initialized
panel.deferred.embedded.done( function () {
- parentContainer = panel.container.find( 'ul:first' );
+ parentContainer = panel.content;
if ( ! section.container.parent().is( parentContainer ) ) {
parentContainer.append( section.container );
}
+ if ( ! section.content.parent().is( section.container ) ) {
+ container.append( section.content );
+ }
section.deferred.embedded.resolve();
});
} );
} else {
// There is no panel, so embed the section in the root of the customizer
- parentContainer = $( '#customize-theme-controls' ).children( 'ul' ); // @todo This should be defined elsewhere, and to be configurable
+ parentContainer = $( '.customize-pane-parent' ); // @todo This should be defined elsewhere, and to be configurable
if ( ! section.container.parent().is( parentContainer ) ) {
parentContainer.append( section.container );
}
+ if ( ! section.content.parent().is( section.container ) ) {
+ container.append( section.content );
+ }
section.deferred.embedded.resolve();
}
};
section.panel.bind( inject );
inject( section.panel.get() ); // Since a section may never get a panel, assume that it won't ever get one
-
- section.deferred.embedded.done(function() {
- // Fix the top margin after reflow.
- api.bind( 'pane-contents-reflowed', _.debounce( function() {
- section._recalculateTopMargin();
- }, 100 ) );
- });
},
/**
@@ -612,10 +678,11 @@
* @since 4.1.0
*/
attachEvents: function () {
- var section = this;
+ var section = this,
+ toggleHandler;
// Expand/Collapse accordion sections on click.
- section.container.find( '.accordion-section-title, .customize-section-back' ).on( 'click keydown', function( event ) {
+ toggleHandler = function ( event ) {
if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
return;
}
@@ -626,7 +693,10 @@
} else {
section.expand();
}
- });
+ };
+
+ section.container.find( '.accordion-section-title' ).on( 'click keydown', toggleHandler );
+ section.content.find( '.customize-section-back' ).on( 'click keydown', toggleHandler );
},
/**
@@ -670,49 +740,43 @@
onChangeExpanded: function ( expanded, args ) {
var section = this,
container = section.container.closest( '.wp-full-overlay-sidebar-content' ),
- content = section.container.find( '.accordion-section-content' ),
+ content = section.content,
overlay = section.container.closest( '.wp-full-overlay' ),
- backBtn = section.container.find( '.customize-section-back' ),
+ backBtn = content.find( '.customize-section-back' ),
sectionTitle = section.container.find( '.accordion-section-title' ).first(),
- headerActionsHeight = $( '#customize-header-actions' ).height(),
- resizeContentHeight, expand, position, scroll;
+ currentScrollTop = container.scrollTop(),
+ previousScrollTop, expand, stateChangeCallback;
- if ( expanded && ! section.container.hasClass( 'open' ) ) {
+ if ( expanded && ! content.hasClass( 'open' ) ) {
if ( args.unchanged ) {
expand = args.completeCallback;
} else {
- container.scrollTop( 0 );
- resizeContentHeight = function() {
- var matchMedia, offset;
- matchMedia = window.matchMedia || window.msMatchMedia;
- offset = 90; // 45px for customize header actions + 45px for footer actions.
-
- // No footer on small screens.
- if ( matchMedia && matchMedia( '(max-width: 640px)' ).matches ) {
- offset = 45;
- }
- content.css( 'height', ( window.innerHeight - offset ) );
- };
- expand = function() {
- section.container.addClass( 'open' );
- overlay.addClass( 'section-open' );
- position = content.offset().top;
- scroll = container.scrollTop();
- content.css( 'margin-top', ( headerActionsHeight - position - scroll ) );
- resizeContentHeight();
- sectionTitle.attr( 'tabindex', '-1' );
- backBtn.attr( 'tabindex', '0' );
- backBtn.focus();
- if ( args.completeCallback ) {
- args.completeCallback();
- }
+ expand = $.proxy( function() {
+ stateChangeCallback = function() {
+ sectionTitle.attr( 'tabindex', '-1' );
+ backBtn.attr( 'tabindex', '0' );
- // Fix the height after browser resize.
- $( window ).on( 'resize.customizer-section', _.debounce( resizeContentHeight, 100 ) );
+ backBtn.focus();
+ content.css( 'top', '' );
+ container.scrollTop( 0 );
- setTimeout( _.bind( section._recalculateTopMargin, section ), 0 );
- };
+ if ( args.completeCallback ) {
+ args.completeCallback();
+ }
+ };
+
+ this.animateChangeExpanded( stateChangeCallback );
+
+ // Prevent ugly screen flicker for items that are 'below the fold'.
+ if ( 0 < currentScrollTop ) {
+ content.data( 'previous-scrollTop', currentScrollTop );
+ content.css( 'top', currentScrollTop + 'px' );
+ }
+
+ content.addClass( 'open' );
+ overlay.addClass( 'section-open' );
+ }, this );
}
if ( ! args.allowMultiple ) {
@@ -735,18 +799,33 @@
expand();
}
- } else if ( ! expanded && section.container.hasClass( 'open' ) ) {
- section.container.removeClass( 'open' );
+ } else if ( ! expanded && content.hasClass( 'open' ) ) {
+ stateChangeCallback = function() {
+ backBtn.attr( 'tabindex', '-1' );
+ sectionTitle.attr( 'tabindex', '0' );
+
+ sectionTitle.focus();
+ content.css( 'top', '' );
+
+ if ( args.completeCallback ) {
+ args.completeCallback();
+ }
+ };
+
+ this.animateChangeExpanded( stateChangeCallback );
+
+ content.removeClass( 'open' );
overlay.removeClass( 'section-open' );
- content.css( 'margin-top', '' );
- container.scrollTop( 0 );
- backBtn.attr( 'tabindex', '-1' );
- sectionTitle.attr( 'tabindex', '0' );
- sectionTitle.focus();
- if ( args.completeCallback ) {
- args.completeCallback();
- }
- $( window ).off( 'resize.customizer-section' );
+
+ // Prevent ugly screen flicker for items that are 'below the fold'.
+ _.defer( function() {
+ previousScrollTop = content.data( 'previous-scrollTop' ) || 0;
+ if ( 0 < currentScrollTop + previousScrollTop ) {
+ container.scrollTop( previousScrollTop );
+ content.css( 'top', previousScrollTop - currentScrollTop + 'px' );
+ }
+ } );
+
} else {
if ( args.completeCallback ) {
args.completeCallback();
@@ -755,22 +834,43 @@
},
/**
- * Recalculate the top margin.
+ * Animate pane state change if transitions are supported by the browser.
*
- * @since 4.4.0
- * @private
+ * @param {function} completeCallback Function to be called after transition is completed.
*/
- _recalculateTopMargin: function() {
- var section = this, content, offset, headerActionsHeight;
- content = section.container.find( '.accordion-section-content' );
- if ( 0 === content.length ) {
+ animateChangeExpanded: function( completeCallback ) {
+ var section = this,
+ content = section.content,
+ overlay = content.closest( '.wp-full-overlay' ),
+ affectedElements, transitionEndCallback;
+
+ if ( ! normalizedTransitionendEventName ) {
+ if ( completeCallback ) {
+ completeCallback();
+ }
return;
}
- headerActionsHeight = $( '#customize-header-actions' ).height();
- offset = ( content.offset().top - headerActionsHeight );
- if ( 0 < offset ) {
- content.css( 'margin-top', ( parseInt( content.css( 'margin-top' ), 10 ) - offset ) );
+
+ affectedElements = overlay.add( content );
+ if ( ! overlay.hasClass( 'in-sub-panel' ) ) {
+ affectedElements = affectedElements.add( '#customize-info, .customize-pane-parent' );
}
+
+ transitionEndCallback = function( e ) {
+ if ( 2 !== e.eventPhase || ! $( e.target ).is( content ) ) {
+ return;
+ }
+
+ content.off( normalizedTransitionendEventName, transitionEndCallback );
+ affectedElements.removeClass( 'busy' );
+
+ if ( completeCallback ) {
+ completeCallback();
+ }
+ };
+
+ content.on( normalizedTransitionendEventName, transitionEndCallback );
+ affectedElements.addClass( 'busy' );
}
});
@@ -804,7 +904,7 @@
*/
ready: function () {
var section = this;
- section.overlay = section.container.find( '.theme-overlay' );
+ section.overlay = section.content.find( '.theme-overlay' );
section.template = wp.template( 'customize-themes-details-view' );
// Bind global keyboard events.
@@ -851,10 +951,12 @@
* @since 4.2.0
*/
attachEvents: function () {
- var section = this;
+ var section = this,
+ content = section.content,
+ toggleHandler;
// Expand/Collapse section/panel.
- section.container.find( '.change-theme, .customize-theme' ).on( 'click keydown', function( event ) {
+ toggleHandler = function ( event ) {
if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
return;
}
@@ -865,10 +967,13 @@
} else {
section.expand();
}
- });
+ };
+
+ section.container.find( '.change-theme' ).on( 'click keydown', toggleHandler );
+ content.find( '.customize-theme' ).on( 'click keydown', toggleHandler );
// Theme navigation in details view.
- section.container.on( 'click keydown', '.left', function( event ) {
+ content.on( 'click keydown', '.left', function( event ) {
if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
return;
}
@@ -878,7 +983,7 @@
section.previousTheme();
});
- section.container.on( 'click keydown', '.right', function( event ) {
+ content.on( 'click keydown', '.right', function( event ) {
if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
return;
}
@@ -888,7 +993,7 @@
section.nextTheme();
});
- section.container.on( 'click keydown', '.theme-backdrop, .close', function( event ) {
+ content.on( 'click keydown', '.theme-backdrop, .close', function( event ) {
if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
return;
}
@@ -899,7 +1004,7 @@
});
var renderScreenshots = _.throttle( _.bind( section.renderScreenshots, this ), 100 );
- section.container.on( 'input', '#themes-filter', function( event ) {
+ content.on( 'input', '#themes-filter', function( event ) {
var count,
term = event.currentTarget.value.toLowerCase().trim().replace( '-', ' ' ),
controls = section.controls();
@@ -911,8 +1016,8 @@
renderScreenshots();
// Update theme count.
- count = section.container.find( 'li.customize-control:visible' ).length;
- section.container.find( '.theme-count' ).text( count );
+ count = content.find( 'li.customize-control:visible' ).length;
+ content.find( '.theme-count' ).text( count );
});
// Pre-load the first 3 theme screenshots.
@@ -948,18 +1053,16 @@
}
// Note: there is a second argument 'args' passed
- var position, scroll,
- panel = this,
- section = panel.container.closest( '.accordion-section' ),
+ var panel = this,
+ section = panel.content,
overlay = section.closest( '.wp-full-overlay' ),
container = section.closest( '.wp-full-overlay-sidebar-content' ),
- siblings = container.find( '.open' ),
customizeBtn = section.find( '.customize-theme' ),
- changeBtn = section.find( '.change-theme' ),
- content = section.find( '.control-panel-content' );
-
- if ( expanded ) {
+ changeBtn = panel.container.find( '.change-theme' ),
+ currentScrollTop = container.scrollTop(),
+ previousScrollTop, stateChangeCallback;
+ if ( expanded && ! section.hasClass( 'current-panel' ) ) {
// Collapse any sibling sections/panels
api.section.each( function ( otherSection ) {
if ( otherSection !== panel ) {
@@ -970,45 +1073,96 @@
otherPanel.collapse( { duration: 0 } );
});
- content.show( 0, function() {
- position = content.offset().top;
- scroll = container.scrollTop();
- content.css( 'margin-top', ( $( '#customize-header-actions' ).height() - position - scroll ) );
- section.addClass( 'current-panel' );
- overlay.addClass( 'in-themes-panel' );
+ stateChangeCallback = function() {
+ changeBtn.attr( 'tabindex', '-1' );
+ customizeBtn.attr( 'tabindex', '0' );
+
+ customizeBtn.focus();
+ section.css( 'top', '' );
container.scrollTop( 0 );
- _.delay( panel.renderScreenshots, 10 ); // Wait for the controls
- panel.$customizeSidebar.on( 'scroll.customize-themes-section', _.throttle( panel.renderScreenshots, 300 ) );
+
if ( args.completeCallback ) {
args.completeCallback();
}
- } );
- customizeBtn.focus();
- } else {
- siblings.removeClass( 'open' );
- section.removeClass( 'current-panel' );
- overlay.removeClass( 'in-themes-panel' );
- panel.$customizeSidebar.off( 'scroll.customize-themes-section' );
- content.delay( 180 ).hide( 0, function() {
- content.css( 'margin-top', 'inherit' ); // Reset
+ };
+
+ this.animateChangeExpanded( stateChangeCallback );
+
+ // Prevent ugly screen flicker for items that are 'below the fold'.
+ if ( 0 < currentScrollTop ) {
+ section.data( 'previous-scrollTop', currentScrollTop );
+ section.css( 'top', currentScrollTop + 'px' );
+ }
+
+ overlay.addClass( 'in-themes-panel' );
+ section.addClass( 'current-panel' );
+
+ } else if ( ! expanded && section.hasClass( 'current-panel' ) ) {
+
+ stateChangeCallback = function() {
+ changeBtn.attr( 'tabindex', '0' );
+ customizeBtn.attr( 'tabindex', '-1' );
+
+ changeBtn.focus();
+ section.css( 'top', '' );
+
if ( args.completeCallback ) {
args.completeCallback();
}
+ };
+
+ this.animateChangeExpanded( stateChangeCallback );
+
+ overlay.removeClass( 'in-themes-panel' );
+ section.removeClass( 'current-panel' );
+
+ // Prevent ugly screen flicker for items that are 'below the fold'.
+ _.defer( function() {
+ previousScrollTop = section.data( 'previous-scrollTop' ) || 0;
+ if ( 0 < currentScrollTop + previousScrollTop ) {
+ container.scrollTop( previousScrollTop );
+ section.css( 'top', previousScrollTop - currentScrollTop + 'px' );
+ }
} );
- customizeBtn.attr( 'tabindex', '0' );
- changeBtn.focus();
- container.scrollTop( 0 );
}
},
+
/**
- * Recalculate the top margin.
+ * Animate pane state change if transitions are supported by the browser.
*
- * @since 4.4.0
- * @private
+ * @param {function} completeCallback Function to be called after transition is completed.
*/
- _recalculateTopMargin: function() {
- api.Panel.prototype._recalculateTopMargin.call( this );
+ animateChangeExpanded: function( completeCallback ) {
+ var content = this.content,
+ overlay = content.closest( '.wp-full-overlay' ),
+ affectedElements, transitionEndCallback;
+
+ if ( ! normalizedTransitionendEventName ) {
+ if ( completeCallback ) {
+ completeCallback();
+ }
+ return;
+ }
+
+ affectedElements = overlay.add( content );
+ affectedElements = affectedElements.add( '#customize-info, .customize-pane-parent' );
+
+ transitionEndCallback = function( e ) {
+ if ( 2 !== e.eventPhase || ! $( e.target ).is( content ) ) {
+ return;
+ }
+
+ content.off( normalizedTransitionendEventName, transitionEndCallback );
+ affectedElements.removeClass( 'busy' );
+
+ if ( completeCallback ) {
+ completeCallback();
+ }
+ };
+
+ content.on( normalizedTransitionendEventName, transitionEndCallback );
+ affectedElements.addClass( 'busy' );
},
/**
@@ -1237,17 +1391,17 @@
*/
embed: function () {
var panel = this,
- parentContainer = $( '#customize-theme-controls > ul' ); // @todo This should be defined elsewhere, and to be configurable
+ container = $( '#customize-theme-controls' ),
+ parentContainer = $( '.customize-pane-parent' ); // @todo This should be defined elsewhere, and to be configurable
if ( ! panel.container.parent().is( parentContainer ) ) {
parentContainer.append( panel.container );
+ }
+ if ( ! panel.content.parent().is( panel.container ) ) {
+ container.append( panel.content );
panel.renderContent();
}
- api.bind( 'pane-contents-reflowed', _.debounce( function() {
- panel._recalculateTopMargin();
- }, 100 ) );
-
panel.deferred.embedded.resolve();
},
@@ -1270,7 +1424,7 @@
});
// Close panel.
- panel.container.find( '.customize-panel-back' ).on( 'click keydown', function( event ) {
+ panel.content.find( '.customize-panel-back' ).on( 'click keydown', function( event ) {
if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
return;
}
@@ -1281,7 +1435,7 @@
}
});
- meta = panel.container.find( '.panel-meta:first' );
+ meta = panel.content.find( '.panel-meta:first' );
meta.find( '> .accordion-section-title .customize-help-toggle' ).on( 'click keydown', function( event ) {
if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
@@ -1289,7 +1443,6 @@
}
event.preventDefault(); // Keep this AFTER the key filter above
- meta = panel.container.find( '.panel-meta' );
if ( meta.hasClass( 'cannot-expand' ) ) {
return;
}
@@ -1305,7 +1458,6 @@
$( this ).attr( 'aria-expanded', true );
}
});
-
},
/**
@@ -1359,20 +1511,16 @@
}
// Note: there is a second argument 'args' passed
- var position, scroll,
- panel = this,
- accordionSection = panel.container.closest( '.accordion-section' ),
+ var panel = this,
+ accordionSection = panel.content,
overlay = accordionSection.closest( '.wp-full-overlay' ),
container = accordionSection.closest( '.wp-full-overlay-sidebar-content' ),
- siblings = container.find( '.open' ),
- topPanel = overlay.find( '#customize-theme-controls > ul > .accordion-section > .accordion-section-title' ),
+ topPanel = panel.container.find( '.accordion-section-title' ),
backBtn = accordionSection.find( '.customize-panel-back' ),
- panelTitle = accordionSection.find( '.accordion-section-title' ).first(),
- content = accordionSection.find( '.control-panel-content' ),
- headerActionsHeight = $( '#customize-header-actions' ).height();
-
- if ( expanded ) {
+ currentScrollTop = container.scrollTop(),
+ previousScrollTop, stateChangeCallback;
+ if ( expanded && ! accordionSection.hasClass( 'current-panel' ) ) {
// Collapse any sibling sections/panels
api.section.each( function ( section ) {
if ( panel.id !== section.panel() ) {
@@ -1385,51 +1533,95 @@
}
});
- content.show( 0, function() {
- content.parent().show();
- position = content.offset().top;
- scroll = container.scrollTop();
- content.css( 'margin-top', ( headerActionsHeight - position - scroll ) );
- accordionSection.addClass( 'current-panel' );
- overlay.addClass( 'in-sub-panel' );
+ stateChangeCallback = function() {
+ topPanel.attr( 'tabindex', '-1' );
+ backBtn.attr( 'tabindex', '0' );
+
+ backBtn.focus();
+ accordionSection.css( 'top', '' );
container.scrollTop( 0 );
+
if ( args.completeCallback ) {
args.completeCallback();
}
- } );
- topPanel.attr( 'tabindex', '-1' );
- backBtn.attr( 'tabindex', '0' );
- backBtn.focus();
- panel._recalculateTopMargin();
- } else {
- siblings.removeClass( 'open' );
- accordionSection.removeClass( 'current-panel' );
- overlay.removeClass( 'in-sub-panel' );
- content.delay( 180 ).hide( 0, function() {
- content.css( 'margin-top', 'inherit' ); // Reset
+ };
+
+ this.animateChangeExpanded( stateChangeCallback );
+
+ // Prevent ugly screen flicker for items that are 'below the fold'.
+ if ( 0 < currentScrollTop ) {
+ accordionSection.data( 'previous-scrollTop', currentScrollTop );
+ accordionSection.css( 'top', currentScrollTop + 'px' );
+ }
+
+ overlay.addClass( 'in-sub-panel' );
+ accordionSection.addClass( 'current-panel' );
+
+ } else if ( ! expanded && accordionSection.hasClass( 'current-panel' ) ) {
+ stateChangeCallback = function() {
+ topPanel.attr( 'tabindex', '0' );
+ backBtn.attr( 'tabindex', '-1' );
+
+ topPanel.focus();
+ accordionSection.css( 'top', '' );
+
if ( args.completeCallback ) {
args.completeCallback();
}
+ };
+
+ this.animateChangeExpanded( stateChangeCallback );
+
+ // Prevent ugly screen flicker for items that are 'below the fold'.
+ _.defer( function() {
+ previousScrollTop = accordionSection.data( 'previous-scrollTop' ) || 0;
+ if ( 0 < currentScrollTop + previousScrollTop ) {
+ accordionSection.css( 'top', previousScrollTop - currentScrollTop + 'px' );
+ container.scrollTop( previousScrollTop );
+ }
} );
- topPanel.attr( 'tabindex', '0' );
- backBtn.attr( 'tabindex', '-1' );
- panelTitle.focus();
- container.scrollTop( 0 );
+
+ overlay.removeClass( 'in-sub-panel' );
+ accordionSection.removeClass( 'current-panel' );
}
},
/**
- * Recalculate the top margin.
+ * Animate pane state change if transitions are supported by the browser.
*
- * @since 4.4.0
- * @private
+ * @param {function} completeCallback Function to be called after transition is completed.
*/
- _recalculateTopMargin: function() {
- var panel = this, headerActionsHeight, content, accordionSection;
- headerActionsHeight = $( '#customize-header-actions' ).height();
- accordionSection = panel.container.closest( '.accordion-section' );
- content = accordionSection.find( '.control-panel-content' );
- content.css( 'margin-top', ( parseInt( content.css( 'margin-top' ), 10 ) - ( content.offset().top - headerActionsHeight ) ) );
+ animateChangeExpanded: function( completeCallback ) {
+ var panel = this,
+ content = panel.content,
+ overlay = content.closest( '.wp-full-overlay' ),
+ affectedElements, transitionEndCallback;
+
+ if ( ! normalizedTransitionendEventName ) {
+ if ( completeCallback ) {
+ completeCallback();
+ }
+ return;
+ }
+
+ affectedElements = overlay.add( content );
+ affectedElements = affectedElements.add( '#customize-info, .customize-pane-parent' );
+
+ transitionEndCallback = function( e ) {
+ if ( 2 !== e.eventPhase || ! $( e.target ).is( content ) ) {
+ return;
+ }
+
+ content.off( normalizedTransitionendEventName, transitionEndCallback );
+ affectedElements.removeClass( 'busy' );
+
+ if ( completeCallback ) {
+ completeCallback();
+ }
+ };
+
+ content.on( normalizedTransitionendEventName, transitionEndCallback );
+ affectedElements.addClass( 'busy' );
},
/**
@@ -1450,7 +1642,7 @@
template = wp.template( 'customize-panel-default-content' );
}
if ( template && panel.container ) {
- panel.container.find( '.accordion-sub-container' ).html( template( panel.params ) );
+ panel.content.html( template( panel.params ) );
}
}
});
@@ -1626,7 +1818,7 @@
api.section( sectionId, function ( section ) {
// Wait for the section to be ready/initialized
section.deferred.embedded.done( function () {
- parentContainer = section.container.find( 'ul:first' );
+ parentContainer = ( section.content.is( 'ul' ) ) ? section.content : section.content.find( 'ul:first' );
if ( ! control.container.parent().is( parentContainer ) ) {
parentContainer.append( control.container );
control.renderContent();
@@ -3896,6 +4088,77 @@
});
});
+ /**
+ * Sort panels, sections, controls by priorities. Hide empty sections and panels.
+ *
+ * @since 4.1.0
+ */
+ api.reflowPaneContents = _.bind( function () {
+
+ var appendContainer, activeElement, rootContainers, rootNodes = [], wasReflowed = false;
+
+ if ( document.activeElement ) {
+ activeElement = $( document.activeElement );
+ }
+
+ // Sort the sections within each panel
+ api.panel.each( function ( panel ) {
+ var sections = panel.sections(),
+ sectionContainers = _.pluck( sections, 'container' );
+ rootNodes.push( panel );
+ appendContainer = ( panel.content.is( 'ul' ) ) ? panel.content : panel.content.find( 'ul:first' );
+ if ( ! api.utils.areElementListsEqual( sectionContainers, appendContainer.children( '[id]' ) ) ) {
+ _( sections ).each( function ( section ) {
+ appendContainer.append( section.container );
+ } );
+ wasReflowed = true;
+ }
+ } );
+
+ // Sort the controls within each section
+ api.section.each( function ( section ) {
+ var controls = section.controls(),
+ controlContainers = _.pluck( controls, 'container' );
+ if ( ! section.panel() ) {
+ rootNodes.push( section );
+ }
+ appendContainer = ( section.content.is( 'ul' ) ) ? section.content : section.content.find( 'ul:first' );
+ if ( ! api.utils.areElementListsEqual( controlContainers, appendContainer.children( '[id]' ) ) ) {
+ _( controls ).each( function ( control ) {
+ appendContainer.append( control.container );
+ } );
+ wasReflowed = true;
+ }
+ } );
+
+ // Sort the root panels and sections
+ rootNodes.sort( api.utils.prioritySort );
+ rootContainers = _.pluck( rootNodes, 'container' );
+ appendContainer = $( '.customize-pane-parent' ); //$( '#customize-theme-controls' ).children( 'ul' ); // @todo This should be defined elsewhere, and to be configurable
+ if ( ! api.utils.areElementListsEqual( rootContainers, appendContainer.children() ) ) {
+ _( rootNodes ).each( function ( rootNode ) {
+ appendContainer.append( rootNode.container );
+ } );
+ wasReflowed = true;
+ }
+
+ // Now re-trigger the active Value callbacks to that the panels and sections can decide whether they can be rendered
+ api.panel.each( function ( panel ) {
+ var value = panel.active();
+ panel.active.callbacks.fireWith( panel.active, [ value, value ] );
+ } );
+ api.section.each( function ( section ) {
+ var value = section.active();
+ section.active.callbacks.fireWith( section.active, [ value, value ] );
+ } );
+
+ // Restore focus if there was a reflow and there was an active (focused) element
+ if ( wasReflowed && activeElement ) {
+ activeElement.focus();
+ }
+ api.trigger( 'pane-contents-reflowed' );
+ }, api );
+
api.bind( 'ready', api.reflowPaneContents );
$( [ api.panel, api.section, api.control ] ).each( function ( i, values ) {
var debouncedReflowPaneContents = _.debounce( api.reflowPaneContents, 100 );
diff --git a/src/wp-admin/js/customize-nav-menus.js b/src/wp-admin/js/customize-nav-menus.js
index e514a0a..fbfc63a 100644
--- a/src/wp-admin/js/customize-nav-menus.js
+++ b/src/wp-admin/js/customize-nav-menus.js
@@ -655,7 +655,7 @@
api.Panel.prototype.attachEvents.call( this );
var panel = this,
- panelMeta = panel.container.find( '.panel-meta' ),
+ panelMeta = panel.content.find( '.panel-meta' ),
help = panelMeta.find( '.customize-help-toggle' ),
content = panelMeta.find( '.customize-panel-description' ),
options = $( '#screen-options-wrap' ),
@@ -834,14 +834,14 @@
api.bind( 'pane-contents-reflowed', function() {
// Skip menus that have been removed.
- if ( ! section.container.parent().length ) {
+ if ( ! section.content.parent().length ) {
return;
}
- section.container.find( '.menu-item .menu-item-reorder-nav button' ).attr({ 'tabindex': '0', 'aria-hidden': 'false' });
- section.container.find( '.menu-item.move-up-disabled .menus-move-up' ).attr({ 'tabindex': '-1', 'aria-hidden': 'true' });
- section.container.find( '.menu-item.move-down-disabled .menus-move-down' ).attr({ 'tabindex': '-1', 'aria-hidden': 'true' });
- section.container.find( '.menu-item.move-left-disabled .menus-move-left' ).attr({ 'tabindex': '-1', 'aria-hidden': 'true' });
- section.container.find( '.menu-item.move-right-disabled .menus-move-right' ).attr({ 'tabindex': '-1', 'aria-hidden': 'true' });
+ section.content.find( '.menu-item .menu-item-reorder-nav button' ).attr({ 'tabindex': '0', 'aria-hidden': 'false' });
+ section.content.find( '.menu-item.move-up-disabled .menus-move-up' ).attr({ 'tabindex': '-1', 'aria-hidden': 'true' });
+ section.content.find( '.menu-item.move-down-disabled .menus-move-down' ).attr({ 'tabindex': '-1', 'aria-hidden': 'true' });
+ section.content.find( '.menu-item.move-left-disabled .menus-move-left' ).attr({ 'tabindex': '-1', 'aria-hidden': 'true' });
+ section.content.find( '.menu-item.move-right-disabled .menus-move-right' ).attr({ 'tabindex': '-1', 'aria-hidden': 'true' });
} );
},
@@ -952,7 +952,7 @@
var section = this;
if ( expanded ) {
- wpNavMenu.menuList = section.container.find( '.accordion-section-content:first' );
+ wpNavMenu.menuList = section.content;
wpNavMenu.targetList = wpNavMenu.menuList;
// Add attributes needed by wpNavMenu
@@ -1014,7 +1014,7 @@
onChangeExpanded: function( expanded ) {
var section = this,
button = section.container.find( '.add-menu-toggle' ),
- content = section.container.find( '.new-menu-section-content' ),
+ content = section.content,
customizer = section.container.closest( '.wp-full-overlay-sidebar-content' );
if ( expanded ) {
button.addClass( 'open' );
@@ -1028,6 +1028,15 @@
content.slideUp( 'fast' );
content.find( '.menu-name-field' ).removeClass( 'invalid' );
}
+ },
+
+ /**
+ * Detach and return the content html, extracted from the container html, if it exists.
+ *
+ * @since
+ */
+ getContent: function () {
+ return this.container.find( 'ul:first' );
}
});
@@ -1984,6 +1993,7 @@
*/
ready: function() {
var control = this,
+ section = api.section( control.section() ),
menuId = control.params.menu_id,
menu = control.setting(),
name,
@@ -2000,7 +2010,7 @@
* being deactivated.
*/
control.active.validate = function() {
- var value, section = api.section( control.section() );
+ var value;
if ( section ) {
value = section.active();
} else {
@@ -2009,7 +2019,7 @@
return value;
};
- control.$controlSection = control.container.closest( '.control-section' );
+ control.$controlSection = section.container;
control.$sectionContent = control.container.closest( '.accordion-section-content' );
this._setupModel();
@@ -2192,6 +2202,7 @@
section = api.section( control.section() );
removeSection = function() {
section.container.remove();
+ section.content.remove();
api.section.remove( section.id );
};
@@ -2283,11 +2294,11 @@
return;
}
- var section = control.container.closest( '.accordion-section' ),
+ var section = api.section( control.section() ),
menuId = control.params.menu_id,
- controlTitle = section.find( '.accordion-section-title' ),
- sectionTitle = section.find( '.customize-section-title h3' ),
- location = section.find( '.menu-in-location' ),
+ controlTitle = section.container.find( '.accordion-section-title' ),
+ sectionTitle = section.content.find( '.customize-section-title h3' ),
+ location = section.container.find( '.menu-in-location' ),
action = sectionTitle.find( '.customize-action' ),
name = displayNavMenuName( menu.name );
@@ -2311,7 +2322,7 @@
} );
// Update the nav menu name in all location checkboxes.
- section.find( '.customize-control-checkbox input' ).each( function() {
+ section.content.find( '.customize-control-checkbox input' ).each( function() {
if ( $( this ).prop( 'checked' ) ) {
$( '.current-menu-location-name-' + $( this ).data( 'location-id' ) ).text( name );
}
@@ -2625,9 +2636,6 @@
// Focus on the new menu section.
api.section( customizeId ).focus(); // @todo should we focus on the new menu's control and open the add-items panel? Thinking user flow...
-
- // Fix an issue with extra space at top immediately after creating new menu.
- $( '#menu-to-edit' ).css( 'margin-top', 0 );
}
});
diff --git a/src/wp-admin/js/customize-widgets.js b/src/wp-admin/js/customize-widgets.js
index 7598023..51b0672 100644
--- a/src/wp-admin/js/customize-widgets.js
+++ b/src/wp-admin/js/customize-widgets.js
@@ -1529,7 +1529,7 @@
panel.deferred.embedded.done(function() {
var panelMetaContainer, noRenderedAreasNotice, shouldShowNotice;
- panelMetaContainer = panel.container.find( '.panel-meta' );
+ panelMetaContainer = panel.content.find( '.panel-meta' );
noRenderedAreasNotice = $( '', {
'class': 'no-widget-areas-rendered-notice'
});
diff --git a/tests/qunit/wp-admin/js/customize-controls.js b/tests/qunit/wp-admin/js/customize-controls.js
index d806e46..10c7787 100644
--- a/tests/qunit/wp-admin/js/customize-controls.js
+++ b/tests/qunit/wp-admin/js/customize-controls.js
@@ -211,9 +211,11 @@ jQuery( window ).load( function (){
section = wp.customize.section( id );
ok( ! section.params.content );
ok( !! section.container );
+ ok( !! section.content );
ok( section.container.is( '.control-section.control-section-default' ) );
ok( 1 === section.container.find( '> .accordion-section-title' ).length );
- ok( 1 === section.container.find( '> .accordion-section-content' ).length );
+ ok( section.content.is( '.accordion-section-content' ) );
+ equal( section.container.attr( 'aria-owns' ), section.content.attr( 'id' ) );
} );
module( 'Customizer Custom Type (titleless) Section with Template in Fixture' );
@@ -225,9 +227,11 @@ jQuery( window ).load( function (){
section = wp.customize.section( id );
ok( ! section.params.content );
ok( !! section.container );
+ ok( !! section.content );
ok( section.container.is( '.control-section.control-section-titleless' ) );
ok( 0 === section.container.find( '> .accordion-section-title' ).length );
- ok( 1 === section.container.find( '> .accordion-section-content' ).length );
+ ok( section.content.is( '.accordion-section-content' ) );
+ equal( section.container.attr( 'aria-owns' ), section.content.attr( 'id' ) );
} );
module( 'Customizer Custom Type Section Lacking Specific Template' );
test( 'Fixture section has expected content', function () {
@@ -235,9 +239,11 @@ jQuery( window ).load( function (){
section = wp.customize.section( id );
ok( ! section.params.content );
ok( !! section.container );
+ ok( !! section.content );
ok( section.container.is( '.control-section.control-section-' + section.params.type ) );
ok( 1 === section.container.find( '> .accordion-section-title' ).length );
- ok( 1 === section.container.find( '> .accordion-section-content' ).length );
+ ok( section.content.is( '.accordion-section-content' ) );
+ equal( section.container.attr( 'aria-owns' ), section.content.attr( 'id' ) );
} );
module( 'Customizer Section lacking any params' );
test( 'Fixture section has default params supplied', function () {
@@ -270,6 +276,7 @@ jQuery( window ).load( function (){
var panel = wp.customize.panel( 'fixture-panel' );
ok( !! panel.params.content );
ok( !! panel.container );
+ ok( !! panel.content );
} );
test( 'Fixture panel has section among its sections()', function () {
var panel = wp.customize.panel( 'fixture-panel' );
@@ -304,9 +311,11 @@ jQuery( window ).load( function (){
panel = wp.customize.panel( id );
ok( ! panel.params.content );
ok( !! panel.container );
+ ok( !! panel.content );
ok( panel.container.is( '.control-panel.control-panel-default' ) );
ok( 1 === panel.container.find( '> .accordion-section-title' ).length );
- ok( 1 === panel.container.find( '> .control-panel-content' ).length );
+ ok( panel.content.is( '.control-panel-content' ) );
+ equal( panel.container.attr( 'aria-owns' ), panel.content.attr( 'id' ) );
} );
module( 'Customizer Custom Type Panel (titleless) with Template in Fixture' );
@@ -318,9 +327,11 @@ jQuery( window ).load( function (){
panel = wp.customize.panel( id );
ok( ! panel.params.content );
ok( !! panel.container );
+ ok( !! panel.content );
ok( panel.container.is( '.control-panel.control-panel-titleless' ) );
ok( 0 === panel.container.find( '> .accordion-section-title' ).length );
- ok( 1 === panel.container.find( '> .control-panel-content' ).length );
+ ok( panel.content.is( '.control-panel-content' ) );
+ equal( panel.container.attr( 'aria-owns' ), panel.content.attr( 'id' ) );
} );
module( 'Customizer Custom Type Panel Lacking Specific Template' );
@@ -329,9 +340,11 @@ jQuery( window ).load( function (){
panel = wp.customize.panel( id );
ok( ! panel.params.content );
ok( !! panel.container );
+ ok( !! panel.content );
ok( panel.container.is( '.control-panel.control-panel-' + panel.params.type ) );
ok( 1 === panel.container.find( '> .accordion-section-title' ).length );
- ok( 1 === panel.container.find( '> .control-panel-content' ).length );
+ ok( panel.content.is( '.control-panel-content' ) );
+ equal( panel.container.attr( 'aria-owns' ), panel.content.attr( 'id' ) );
} );
module( 'Customizer Panel lacking any params' );
test( 'Fixture panel has default params supplied', function () {
diff --git a/tests/qunit/wp-admin/js/customize-widgets.js b/tests/qunit/wp-admin/js/customize-widgets.js
index 225d155..bed93d1 100644
--- a/tests/qunit/wp-admin/js/customize-widgets.js
+++ b/tests/qunit/wp-admin/js/customize-widgets.js
@@ -58,12 +58,12 @@ jQuery( window ).load( function() {
ok( panel.extended( api.Widgets.WidgetsPanel ) );
panel.deferred.embedded.done( function() {
- ok( 1 === panel.container.find( '.no-widget-areas-rendered-notice' ).length );
- ok( panel.container.find( '.no-widget-areas-rendered-notice' ).is( ':visible' ) );
+ ok( 1 === panel.content.find( '.no-widget-areas-rendered-notice' ).length );
+ ok( panel.content.find( '.no-widget-areas-rendered-notice' ).is( ':visible' ) );
api.section( 'sidebar-widgets-sidebar-1' ).active( true );
api.control( 'sidebars_widgets[sidebar-1]' ).active( true );
api.trigger( 'pane-contents-reflowed' );
- ok( ! panel.container.find( '.no-widget-areas-rendered-notice' ).is( ':visible' ) );
+ ok( ! panel.content.find( '.no-widget-areas-rendered-notice' ).is( ':visible' ) );
} );
expect( 4 );