From bef15d72a4d2fdd039cf16b740084cd6da515b89 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Mon, 2 May 2016 19:52:01 +0000 Subject: [PATCH] Customize: Allow Esc key to collapse the currently-expanded panel, section (or control). Pressing Esc collapses any expanded widget or nav menu item controls, or any control that implements the expanding interface. Also improves alignment between `WidgetControl` and `MenuItemControl`, adding the `expanded` state and associated `expand`/`collapse` methods to nav menu items. Props purcebr, celloexpressions, westonruter. Fixes #22237. git-svn-id: https://develop.svn.wordpress.org/trunk@37347 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/js/customize-controls.js | 38 +++++++++++++++++ src/wp-admin/js/customize-nav-menus.js | 56 +++++++++++++++++++++++++- 2 files changed, 92 insertions(+), 2 deletions(-) diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js index 1e134bd9ad..ef01674a7e 100644 --- a/src/wp-admin/js/customize-controls.js +++ b/src/wp-admin/js/customize-controls.js @@ -3647,6 +3647,44 @@ overlay.toggleClass( 'collapsed' ).toggleClass( 'expanded' ); }); + // Keyboard shortcuts - esc to exit section/panel. + $( 'body' ).on( 'keydown', function( event ) { + var collapsedObject, expandedControls = [], expandedSections = [], expandedPanels = []; + + if ( 27 !== event.which ) { // Esc. + return; + } + + // Check for expanded expandable controls (e.g. widgets and nav menus items), sections, and panels. + api.control.each( function( control ) { + if ( control.expanded && control.expanded() && _.isFunction( control.collapse ) ) { + expandedControls.push( control ); + } + }); + api.section.each( function( section ) { + if ( section.expanded() ) { + expandedSections.push( section ); + } + }); + api.panel.each( function( panel ) { + if ( panel.expanded() ) { + expandedPanels.push( panel ); + } + }); + + // Skip collapsing expanded controls if there are no expanded sections. + if ( expandedControls.length > 0 && 0 === expandedSections.length ) { + expandedControls.length = 0; + } + + // Collapse the most granular expanded object. + collapsedObject = expandedControls[0] || expandedSections[0] || expandedPanels[0]; + if ( collapsedObject ) { + collapsedObject.collapse(); + event.preventDefault(); + } + }); + $( '.customize-controls-preview-toggle' ).on( 'click', function() { overlay.toggleClass( 'preview-only' ); }); diff --git a/src/wp-admin/js/customize-nav-menus.js b/src/wp-admin/js/customize-nav-menus.js index 7f0925336b..d27f57c4cf 100644 --- a/src/wp-admin/js/customize-nav-menus.js +++ b/src/wp-admin/js/customize-nav-menus.js @@ -993,6 +993,13 @@ */ initialize: function( id, options ) { var control = this; + control.expanded = new api.Value( false ); + control.expandedArgumentsQueue = []; + control.expanded.bind( function( expanded ) { + var args = control.expandedArgumentsQueue.shift(); + args = $.extend( {}, control.defaultExpandedArguments, args ); + control.onChangeExpanded( expanded, args ); + }); api.Control.prototype.initialize.call( control, id, options ); control.active.validate = function() { var value, section = api.section( control.section() ); @@ -1369,6 +1376,23 @@ } }, + /** + * @since 4.6.0 + * + * @param {Boolean} expanded + * @param {Object} [params] + * @returns {Boolean} false if state already applied + */ + _toggleExpanded: api.Section.prototype._toggleExpanded, + + /** + * @since 4.6.0 + * + * @param {Object} [params] + * @returns {Boolean} false if already expanded + */ + expand: api.Section.prototype.expand, + /** * Expand the menu item form control. * @@ -1378,9 +1402,17 @@ * @param {Function} [params.completeCallback] - Function to call when the form toggle has finished animating. */ expandForm: function( params ) { - this.toggleForm( true, params ); + this.expand( params ); }, + /** + * @since 4.6.0 + * + * @param {Object} [params] + * @returns {Boolean} false if already collapsed + */ + collapse: api.Section.prototype.collapse, + /** * Collapse the menu item form control. * @@ -1390,12 +1422,13 @@ * @param {Function} [params.completeCallback] - Function to call when the form toggle has finished animating. */ collapseForm: function( params ) { - this.toggleForm( false, params ); + this.collapse( params ); }, /** * Expand or collapse the menu item control. * + * @deprecated this is poor naming, and it is better to directly set control.expanded( showOrHide ) * @since 4.5.0 Added params.completeCallback. * * @param {boolean} [showOrHide] - If not supplied, will be inverse of current visibility @@ -1403,6 +1436,25 @@ * @param {Function} [params.completeCallback] - Function to call when the form toggle has finished animating. */ toggleForm: function( showOrHide, params ) { + if ( typeof showOrHide === 'undefined' ) { + showOrHide = ! this.expanded(); + } + if ( showOrHide ) { + this.expand( params ); + } else { + this.collapse( params ); + } + }, + + /** + * Expand or collapse the menu item control. + * + * @since 4.6.0 + * @param {boolean} [showOrHide] - If not supplied, will be inverse of current visibility + * @param {Object} [params] - Optional params. + * @param {Function} [params.completeCallback] - Function to call when the form toggle has finished animating. + */ + onChangeExpanded: function( showOrHide, params ) { var self = this, $menuitem, $inside, complete; $menuitem = this.container;