Make WordPress Core

Ticket #37964: 37964.1.diff

File 37964.1.diff, 8.8 KB (added by westonruter, 10 years ago)
  • src/wp-admin/js/customize-controls.js

    diff --git src/wp-admin/js/customize-controls.js src/wp-admin/js/customize-controls.js
    index 45fb65f..70b9fbe 100644
     
    23572357                defaultActiveArguments: { duration: 'fast', completeCallback: $.noop },
    23582358
    23592359                initialize: function( id, options ) {
    2360                         var control = this,
    2361                                 nodes, radios, settings;
     2360                        var control = this, deferredSettingIds = [];
    23622361
    23632362                        control.params = {};
    23642363                        $.extend( control, options || {} );
     
    23782377
    23792378                        control.elements = [];
    23802379
    2381                         nodes  = control.container.find('[data-customize-setting-link]');
    2382                         radios = {};
    2383 
    2384                         nodes.each( function() {
    2385                                 var node = $( this ),
    2386                                         name;
    2387 
    2388                                 if ( node.is( ':radio' ) ) {
    2389                                         name = node.prop( 'name' );
    2390                                         if ( radios[ name ] ) {
    2391                                                 return;
    2392                                         }
    2393 
    2394                                         radios[ name ] = true;
    2395                                         node = nodes.filter( '[name="' + name + '"]' );
    2396                                 }
    2397 
    2398                                 api( node.data( 'customizeSettingLink' ), function( setting ) {
    2399                                         var element = new api.Element( node );
    2400                                         control.elements.push( element );
    2401                                         element.sync( setting );
    2402                                         element.set( setting() );
    2403                                 });
    2404                         });
    2405 
    24062380                        control.active.bind( function ( active ) {
    24072381                                var args = control.activeArgumentsQueue.shift();
    24082382                                args = $.extend( {}, control.defaultActiveArguments, args );
     
    24152389
    24162390                        api.utils.bubbleChildValueChanges( control, [ 'section', 'priority', 'active' ] );
    24172391
     2392                        control.settings = {};
     2393
    24182394                        /*
    24192395                         * After all settings related to the control are available,
    24202396                         * make them available on the control and embed the control into the page.
    24212397                         */
    2422                         settings = $.map( control.params.settings, function( value ) {
    2423                                 return value;
    2424                         });
    2425 
    2426                         if ( 0 === settings.length ) {
    2427                                 control.setting = null;
    2428                                 control.settings = {};
    2429                                 control.embed();
    2430                         } else {
    2431                                 api.apply( api, settings.concat( function() {
    2432                                         var key;
    2433 
    2434                                         control.settings = {};
    2435                                         for ( key in control.params.settings ) {
    2436                                                 control.settings[ key ] = api( control.params.settings[ key ] );
    2437                                         }
    2438 
    2439                                         control.setting = control.settings['default'] || null;
     2398                        _.each( control.params.settings, function( setting, key ) {
     2399                                if ( _.isObject( setting ) ) {
     2400                                        control.settings[ key ] = setting;
     2401                                } else {
     2402                                        deferredSettingIds.push( setting );
     2403                                }
     2404                        } );
    24402405
    2441                                         // Add setting notifications to the control notification.
    2442                                         _.each( control.settings, function( setting ) {
    2443                                                 setting.notifications.bind( 'add', function( settingNotification ) {
    2444                                                         var controlNotification, code, params;
    2445                                                         code = setting.id + ':' + settingNotification.code;
    2446                                                         params = _.extend(
    2447                                                                 {},
    2448                                                                 settingNotification,
    2449                                                                 {
    2450                                                                         setting: setting.id
    2451                                                                 }
    2452                                                         );
    2453                                                         controlNotification = new api.Notification( code, params );
    2454                                                         control.notifications.add( controlNotification.code, controlNotification );
    2455                                                 } );
    2456                                                 setting.notifications.bind( 'remove', function( settingNotification ) {
    2457                                                         control.notifications.remove( setting.id + ':' + settingNotification.code );
    2458                                                 } );
     2406                        if ( deferredSettingIds.length > 0 ) {
     2407                                api.apply( api, deferredSettingIds.concat( function() {
     2408                                        _.each( control.params.settings, function( settingId, key ) {
     2409                                                if ( _.isString( settingId ) ) {
     2410                                                        control.settings[ key ] = api( settingId );
     2411                                                }
    24592412                                        } );
    24602413
     2414                                        control.setting = control.settings['default'] || null;
    24612415                                        control.embed();
    24622416                                }) );
     2417                        } else {
     2418                                control.setting = control.settings['default'] || null;
     2419                                control.embed();
    24632420                        }
    24642421
    24652422                        // After the control is embedded on the page, invoke the "ready" method.
    24662423                        control.deferred.embedded.done( function () {
    2467                                 /*
    2468                                  * Note that this debounced/deferred rendering is needed for two reasons:
    2469                                  * 1) The 'remove' event is triggered just _before_ the notification is actually removed.
    2470                                  * 2) Improve performance when adding/removing multiple notifications at a time.
    2471                                  */
    2472                                 var debouncedRenderNotifications = _.debounce( function renderNotifications() {
    2473                                         control.renderNotifications();
     2424                                control.linkElements();
     2425                                control.setupNotifications();
     2426                                control.ready();
     2427                        });
     2428                },
     2429
     2430                /**
     2431                 * Link elements between settings and inputs.
     2432                 *
     2433                 * @since 4.7.0
     2434                 * @access public
     2435                 *
     2436                 * @returns {void}
     2437                 */
     2438                linkElements: function() {
     2439                        var control = this, nodes, radios, element;
     2440
     2441                        nodes = control.container.find( '[data-customize-setting-link], [data-customize-value-link]' );
     2442                        radios = {};
     2443
     2444                        nodes.each( function() {
     2445                                var node = $( this ), name, setting;
     2446
     2447                                if ( node.data( 'customizeSettingLinked' ) ) {
     2448                                        return;
     2449                                }
     2450                                node.data( 'customizeSettingLinked', true ); // Prevent re-linking element.
     2451
     2452                                if ( node.is( ':radio' ) ) {
     2453                                        name = node.prop( 'name' );
     2454                                        if ( radios[ name ] ) {
     2455                                                return;
     2456                                        }
     2457
     2458                                        radios[ name ] = true;
     2459                                        node = nodes.filter( '[name="' + name + '"]' );
     2460                                }
     2461
     2462                                // Let link by default refer to setting ID. If it doesn't exist, fallback to looking up by setting key.
     2463                                if ( node.data( 'customizeSettingLink' ) ) {
     2464                                        setting = api( node.data( 'customizeSettingLink' ) );
     2465                                }
     2466                                if ( ! setting ) {
     2467                                        setting = control.settings[ node.data( 'customizeValueLink' ) ];
     2468                                }
     2469
     2470                                if ( setting ) {
     2471                                        element = new api.Element( node );
     2472                                        control.elements.push( element );
     2473                                        element.sync( setting );
     2474                                        element.set( setting() );
     2475                                }
     2476                        });
     2477                },
     2478
     2479                /**
     2480                 * Sync setting notifications to the control notifications and render when notifications are aded/removed.
     2481                 *
     2482                 * @since 4.7.0
     2483                 * @returns {void}
     2484                 */
     2485                setupNotifications: function() {
     2486                        var control = this, debouncedRenderNotifications;
     2487
     2488                        _.each( control.settings, function( setting, settingKey ) {
     2489                                setting.notifications.bind( 'add', function( settingNotification ) {
     2490                                        var controlNotification, code, params;
     2491                                        code = ( setting.id || settingKey ) + ':' + settingNotification.code;
     2492                                        params = _.extend(
     2493                                                {},
     2494                                                settingNotification,
     2495                                                {
     2496                                                        setting: setting.id || null // @todo Let this be the setting object itself?
     2497                                                }
     2498                                        );
     2499                                        controlNotification = new api.Notification( code, params );
     2500                                        control.notifications.add( controlNotification.code, controlNotification );
    24742501                                } );
    2475                                 control.notifications.bind( 'add', function( notification ) {
    2476                                         wp.a11y.speak( notification.message, 'assertive' );
    2477                                         debouncedRenderNotifications();
     2502                                setting.notifications.bind( 'remove', function( settingNotification ) {
     2503                                        control.notifications.remove( ( setting.id || settingKey ) + ':' + settingNotification.code );
    24782504                                } );
    2479                                 control.notifications.bind( 'remove', debouncedRenderNotifications );
    2480                                 control.renderNotifications();
     2505                        } );
    24812506
    2482                                 control.ready();
    2483                         });
     2507                        /*
     2508                         * Note that this debounced/deferred rendering is needed for two reasons:
     2509                         * 1) The 'remove' event is triggered just _before_ the notification is actually removed.
     2510                         * 2) Improve performance when adding/removing multiple notifications at a time.
     2511                         */
     2512                        debouncedRenderNotifications = _.debounce( function renderNotifications() {
     2513                                control.renderNotifications();
     2514                        } );
     2515                        control.notifications.bind( 'add', function( notification ) {
     2516                                wp.a11y.speak( notification.message, 'assertive' );
     2517                                debouncedRenderNotifications();
     2518                        } );
     2519                        control.notifications.bind( 'remove', debouncedRenderNotifications );
     2520                        control.renderNotifications();
    24842521                },
    24852522
    24862523                /**
  • src/wp-includes/class-wp-customize-control.php

    diff --git src/wp-includes/class-wp-customize-control.php src/wp-includes/class-wp-customize-control.php
    index 7bed232..7f44b9f 100644
    class WP_Customize_Control { 
    419419         * Get the data link attribute for a setting.
    420420         *
    421421         * @since 3.4.0
     422         * @since 4.7.0 Returning a `data-customize-value-link` attribute if a setting is not registered for the key.
    422423         *
    423424         * @param string $setting_key
    424          * @return string Data link parameter, if $setting_key is a valid setting, empty string otherwise.
     425         * @return string Data link parameter, a `data-customize-setting-link` attribute if the `$setting_key` refers to a pre-registered setting,
     426         *                and a `data-customize-value-link` attribute if the setting is not registered.
    425427         */
    426428        public function get_link( $setting_key = 'default' ) {
    427                 if ( ! isset( $this->settings[ $setting_key ] ) )
    428                         return '';
    429 
    430                 return 'data-customize-setting-link="' . esc_attr( $this->settings[ $setting_key ]->id ) . '"';
     429                if ( isset( $this->settings[ $setting_key ] ) && $this->settings[ $setting_key ] instanceof WP_Customize_Setting ) {
     430                        return 'data-customize-setting-link="' . esc_attr( $this->settings[ $setting_key ]->id ) . '"';
     431                } else {
     432                        return 'data-customize-value-link="' . esc_attr( $setting_key ) . '"';
     433                }
    431434        }
    432435
    433436        /**