From 610b1f05dea3cf31e9e427379749426cc5bb7857 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Wed, 25 Oct 2017 16:48:19 +0000 Subject: [PATCH] Customize: Link `elements` prior to embedding to prevent possible errors when a control is associated with a non-existent section. Fixes issue specifically with attempting to access an orphaned control's `elements` immediately after it has been added. Normally this would not happen because a control would not be registered without a section, and also a control should only be interacted with once its `embedded` deferred has been resolved. Also harden logic for gathering list of deferred setting IDs. See #37964. Fixes #42330. git-svn-id: https://develop.svn.wordpress.org/trunk@42024 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/js/customize-controls.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js index e15f10cf58..deafe6c2ca 100644 --- a/src/wp-admin/js/customize-controls.js +++ b/src/wp-admin/js/customize-controls.js @@ -3474,12 +3474,18 @@ } _.extend( settings, control.params.settings ); - // Note: Settings can be an array or an object. - _.each( settings, function( setting, key ) { - if ( _.isObject( setting ) ) { // @todo Or check if instance of api.Setting? - control.settings[ key ] = setting; - } else { - deferredSettingIds.push( setting ); + // Note: Settings can be an array or an object, with values being either setting IDs or Setting (or Value) objects. + _.each( settings, function( value, key ) { + var setting; + if ( _.isObject( value ) && _.isFunction( value.extended ) && value.extended( api.Value ) ) { + control.settings[ key ] = value; + } else if ( _.isString( value ) ) { + setting = api( value ); + if ( setting ) { + control.settings[ key ] = setting; + } else { + deferredSettingIds.push( value ); + } } } ); @@ -3500,6 +3506,7 @@ // Identify the main setting. control.setting = control.settings['default'] || null; + control.linkElements(); // Link initial elements present in server-rendered content. control.embed(); }; @@ -3511,7 +3518,7 @@ // After the control is embedded on the page, invoke the "ready" method. control.deferred.embedded.done( function () { - control.linkElements(); + control.linkElements(); // Link any additional elements after template is rendered by renderContent(). control.setupNotifications(); control.ready(); });