From 462a7c2c70c52f3a5c961f5e406cec18244ed43b Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 1 Mar 2016 22:03:27 +0000 Subject: [PATCH] Customize: Ensure autofocus deep-linking applies for dynamically-created panels, sections, and controls. Removes overly-zealous filtering of autofocus panels, sections, and controls which are unrecognized or for which the user doesn't have the capability to focus (in which case it would no-op anyway). Also defers autofocus logic until instances are created, even after initial `ready` event. This ensures that autofocus can apply for any panels, sections, or controls that get created via the loaded preview. See #28650. Fixes #36018. git-svn-id: https://develop.svn.wordpress.org/trunk@36796 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/js/customize-controls.js | 25 ++++++++++++------- .../class-wp-customize-manager.php | 16 +----------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js index 67c78ed03c..e66dab5fe6 100644 --- a/src/wp-admin/js/customize-controls.js +++ b/src/wp-admin/js/customize-controls.js @@ -3468,18 +3468,25 @@ }); // Focus the autofocused element - _.each( [ 'panel', 'section', 'control' ], function ( type ) { - var instance, id = api.settings.autofocus[ type ]; - if ( id && api[ type ]( id ) ) { - instance = api[ type ]( id ); - // Wait until the element is embedded in the DOM - instance.deferred.embedded.done( function () { - // Wait until the preview has activated and so active panels, sections, controls have been set - api.previewer.deferred.active.done( function () { + _.each( [ 'panel', 'section', 'control' ], function( type ) { + var id = api.settings.autofocus[ type ]; + if ( ! id ) { + return; + } + + /* + * Defer focus until: + * 1. The panel, section, or control exists (especially for dynamically-created ones). + * 2. The instance is embedded in the document (and so is focusable). + * 3. The preview has finished loading so that the active states have been set. + */ + api[ type ]( id, function( instance ) { + instance.deferred.embedded.done( function() { + api.previewer.deferred.active.done( function() { instance.focus(); }); }); - } + }); }); /** diff --git a/src/wp-includes/class-wp-customize-manager.php b/src/wp-includes/class-wp-customize-manager.php index 10d7f3a74a..a75eabd807 100644 --- a/src/wp-includes/class-wp-customize-manager.php +++ b/src/wp-includes/class-wp-customize-manager.php @@ -1728,7 +1728,7 @@ final class WP_Customize_Manager { 'panels' => array(), 'sections' => array(), 'nonce' => $this->get_nonces(), - 'autofocus' => array(), + 'autofocus' => $this->get_autofocus(), 'documentTitleTmpl' => $this->get_document_title_template(), 'previewableDevices' => $this->get_previewable_devices(), 'selectiveRefreshEnabled' => isset( $this->selective_refresh ), @@ -1753,20 +1753,6 @@ final class WP_Customize_Manager { } } - // Pass to front end the Customizer construct being deeplinked. - foreach ( $this->get_autofocus() as $type => $id ) { - $can_autofocus = ( - ( 'control' === $type && $this->get_control( $id ) && $this->get_control( $id )->check_capabilities() ) - || - ( 'section' === $type && isset( $settings['sections'][ $id ] ) ) - || - ( 'panel' === $type && isset( $settings['panels'][ $id ] ) ) - ); - if ( $can_autofocus ) { - $settings['autofocus'][ $type ] = $id; - } - } - ?>