Customizer: Add shift-click on nav menu items in preview to focus on corresponding nav menu item controls in pane.

Add missing `params.completeCallback` to `MenuItemControl.focus()` for parity with `Control.focus()`. Also adds `params` to `MenuItemControl.expandForm`, `MenuItemControl.collapseForm()`, and `MenuItemControl.toggleForm()`.

Props MattGeri, westonruter.
Fixes #32681.


git-svn-id: https://develop.svn.wordpress.org/trunk@36383 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Weston Ruter
2016-01-22 21:20:26 +00:00
parent 535d080317
commit 0e46055d5b
4 changed files with 95 additions and 14 deletions

View File

@@ -74,7 +74,7 @@
* @since 4.1.0
*
* @param {Object} [params]
* @param {Callback} [params.completeCallback]
* @param {Function} [params.completeCallback]
*/
focus = function ( params ) {
var construct, completeCallback, focus;

View File

@@ -1363,24 +1363,38 @@
/**
* Expand the menu item form control.
*
* @since 4.5.0 Added params.completeCallback.
*
* @param {Object} [params] - Optional params.
* @param {Function} [params.completeCallback] - Function to call when the form toggle has finished animating.
*/
expandForm: function() {
this.toggleForm( true );
expandForm: function( params ) {
this.toggleForm( true, params );
},
/**
* Collapse the menu item form control.
*
* @since 4.5.0 Added params.completeCallback.
*
* @param {Object} [params] - Optional params.
* @param {Function} [params.completeCallback] - Function to call when the form toggle has finished animating.
*/
collapseForm: function() {
this.toggleForm( false );
collapseForm: function( params ) {
this.toggleForm( false, params );
},
/**
* Expand or collapse the menu item control.
*
* @param {boolean|undefined} [showOrHide] If not supplied, will be inverse of current visibility
* @since 4.5.0 Added params.completeCallback.
*
* @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.
*/
toggleForm: function( showOrHide ) {
toggleForm: function( showOrHide, params ) {
var self = this, $menuitem, $inside, complete;
$menuitem = this.container;
@@ -1391,6 +1405,9 @@
// Already expanded or collapsed.
if ( $inside.is( ':visible' ) === showOrHide ) {
if ( params && params.completeCallback ) {
params.completeCallback();
}
return;
}
@@ -1407,6 +1424,10 @@
.removeClass( 'menu-item-edit-inactive' )
.addClass( 'menu-item-edit-active' );
self.container.trigger( 'expanded' );
if ( params && params.completeCallback ) {
params.completeCallback();
}
};
$menuitem.find( '.item-edit' ).attr( 'aria-expanded', 'true' );
@@ -1419,6 +1440,10 @@
.addClass( 'menu-item-edit-inactive' )
.removeClass( 'menu-item-edit-active' );
self.container.trigger( 'collapsed' );
if ( params && params.completeCallback ) {
params.completeCallback();
}
};
self.container.trigger( 'collapse' );
@@ -1431,14 +1456,31 @@
/**
* Expand the containing menu section, expand the form, and focus on
* the first input in the control.
*
* @since 4.5.0 Added params.completeCallback.
*
* @param {Object} [params] - Params object.
* @param {Function} [params.completeCallback] - Optional callback function when focus has completed.
*/
focus: function() {
var control = this, focusable;
focus: function( params ) {
params = params || {};
var control = this, originalCompleteCallback = params.completeCallback;
control.expandControlSection();
control.expandForm();
// Note that we can't use :focusable due to a jQuery UI issue. See: https://github.com/jquery/jquery-ui/pull/1583
focusable = control.container.find( '.menu-item-settings' ).find( 'input, select, textarea, button, object, a[href], [tabindex]' ).filter( ':visible' );
focusable.first().focus();
params.completeCallback = function() {
var focusable;
// Note that we can't use :focusable due to a jQuery UI issue. See: https://github.com/jquery/jquery-ui/pull/1583
focusable = control.container.find( '.menu-item-settings' ).find( 'input, select, textarea, button, object, a[href], [tabindex]' ).filter( ':visible' );
focusable.first().focus();
if ( originalCompleteCallback ) {
originalCompleteCallback();
}
};
control.expandForm( params );
},
/**
@@ -2445,6 +2487,9 @@
api.previewer.bind( 'refresh', function() {
api.previewer.refresh();
});
// Open and focus menu control.
api.previewer.bind( 'focus-nav-menu-item-control', api.Menus.focusMenuItemControl );
} );
/**

View File

@@ -946,6 +946,9 @@ final class WP_Customize_Nav_Menus {
),
'previewCustomizeNonce' => wp_create_nonce( 'preview-customize_' . $this->manager->get_stylesheet() ),
'navMenuInstanceArgs' => $this->preview_nav_menu_instance_args,
'l10n' => array(
'editNavMenuItemTooltip' => __( 'Shift-click to edit this menu item.' ),
),
);
printf( '<script>var _wpCustomizePreviewNavMenusExports = %s;</script>', wp_json_encode( $exports ) );

View File

@@ -19,7 +19,8 @@
active: false,
stylesheet: ''
},
navMenuInstanceArgs: {}
navMenuInstanceArgs: {},
l10n: {}
};
api.MenusCustomizerPreview = {
@@ -63,6 +64,8 @@
}
}
} );
self.highlightControls();
},
/**
@@ -272,6 +275,36 @@
}, this ),
refreshDebounceDelay
);
},
/**
* Connect nav menu items with their corresponding controls in the pane.
*/
highlightControls: function() {
var selector = '.menu-item[id^=menu-item-]',
addTooltips;
// Open expand the menu item control when shift+clicking the menu item
$( document ).on( 'click', selector, function( e ) {
var navMenuItemParts;
if ( ! e.shiftKey ) {
return;
}
navMenuItemParts = $( this ).attr( 'id' ).match( /^menu-item-(\d+)$/ );
if ( navMenuItemParts ) {
e.preventDefault();
e.stopPropagation(); // Make sure a sub-nav menu item will get focused instead of parent items.
api.preview.send( 'focus-nav-menu-item-control', parseInt( navMenuItemParts[1], 10 ) );
}
});
addTooltips = function( e, params ) {
params.newContainer.find( selector ).attr( 'title', settings.l10n.editNavMenuItemTooltip );
};
addTooltips( null, { newContainer: $( document.body ) } );
$( document ).on( 'customize-preview-menu-refreshed', addTooltips );
}
};