WordPress.org

Make WordPress Core

Ticket #30738: 30738.3.diff

File 30738.3.diff, 16.3 KB (added by westonruter, 2 years ago)

Use settingless-control for display_header_text to avoid element unsyncing https://github.com/xwp/wordpress-develop/pull/261/commits/09e8afd

  • src/wp-admin/js/customize-controls.js

    diff --git src/wp-admin/js/customize-controls.js src/wp-admin/js/customize-controls.js
    index b483aea335..ddacf31807 100644
     
    216216                        setting.id = id;
    217217                        setting.transport = setting.transport || 'refresh';
    218218                        setting._dirty = options.dirty || false;
     219                        setting['default'] = options['default'];
    219220                        setting.notifications = new api.Values({ defaultConstructor: api.Notification });
    220221
    221222                        // Whenever the setting's value changes, refresh the preview.
     
    20892090                defaultActiveArguments: { duration: 'fast', completeCallback: $.noop },
    20902091
    20912092                initialize: function( id, options ) {
    2092                         var control = this,
    2093                                 nodes, radios, settings;
     2093                        var control = this, settings, linkNodes;
    20942094
    20952095                        control.params = {};
    20962096                        $.extend( control, options || {} );
     
    21122112
    21132113                        control.elements = [];
    21142114
    2115                         nodes  = control.container.find('[data-customize-setting-link]');
    2116                         radios = {};
     2115                        linkNodes = function() {
     2116                                var nodes, radios;
     2117                                nodes  = control.container.find( '[data-customize-setting-link]' );
     2118                                radios = {};
    21172119
    2118                         nodes.each( function() {
    2119                                 var node = $( this ),
    2120                                         name;
     2120                                nodes.each( function() {
     2121                                        var node = $( this ),
     2122                                                name;
    21212123
    2122                                 if ( node.is( ':radio' ) ) {
    2123                                         name = node.prop( 'name' );
    2124                                         if ( radios[ name ] ) {
     2124                                        if ( node.data( 'customizeSettingLinkAdded' ) ) {
    21252125                                                return;
    21262126                                        }
    21272127
    2128                                         radios[ name ] = true;
    2129                                         node = nodes.filter( '[name="' + name + '"]' );
    2130                                 }
     2128                                        if ( node.is( ':radio' ) ) {
     2129                                                name = node.prop( 'name' );
     2130                                                if ( radios[ name ] ) {
     2131                                                        return;
     2132                                                }
    21312133
    2132                                 api( node.data( 'customizeSettingLink' ), function( setting ) {
    2133                                         var element = new api.Element( node );
    2134                                         control.elements.push( element );
    2135                                         element.sync( setting );
    2136                                         element.set( setting() );
     2134                                                radios[ name ] = true;
     2135                                                node = nodes.filter( '[name="' + name + '"]' );
     2136                                        }
     2137
     2138                                        node.data( 'customizeSettingLinkAdded', true );
     2139                                        api( node.data( 'customizeSettingLink' ), function( setting ) {
     2140                                                var element = new api.Element( node );
     2141                                                control.elements.push( element );
     2142                                                element.sync( setting );
     2143                                                element.set( setting() );
     2144                                        });
    21372145                                });
    2138                         });
     2146                        };
     2147                        linkNodes(); // Call early for back-compat in case no content template is being used.
    21392148
    21402149                        control.active.bind( function ( active ) {
    21412150                                var args = control.activeArgumentsQueue.shift();
     
    21982207
    21992208                        // After the control is embedded on the page, invoke the "ready" method.
    22002209                        control.deferred.embedded.done( function () {
     2210                                linkNodes(); // Link nodes that were added via content template.
     2211
    22012212                                control.setupNotifications();
    22022213                                control.ready();
    22032214                        });
     
    25152526                        var template,
    25162527                                control = this;
    25172528
     2529                        // If there's already content, bail.
     2530                        if ( control.container.is( ':empty' ) ) {
     2531                                return;
     2532                        }
    25182533                        // Replace the container element's content with the control.
    25192534                        if ( 0 !== $( '#tmpl-' + control.templateSelector ).length ) {
    25202535                                template = wp.template( control.templateSelector );
    2521                                 if ( template && control.container ) {
    2522                                         control.container.html( template( control.params ) );
    2523                                 }
     2536                        } else {
     2537                                template = wp.template( 'customize-control-default-content' );
     2538                        }
     2539
     2540                        if ( template && control.container ) {
     2541                                control.container.html( template( control.params ) );
    25242542                        }
    25252543                },
    25262544
     
    49094927                        var constructor = api.settingConstructor[ data.type ] || api.Setting,
    49104928                                setting;
    49114929
    4912                         setting = new constructor( id, data.value, {
    4913                                 transport: data.transport,
    4914                                 previewer: api.previewer,
    4915                                 dirty: !! data.dirty
    4916                         } );
     4930                        setting = new constructor( id, data.value, _.extend(
     4931                                {},
     4932                                data,
     4933                                { previewer: api.previewer }
     4934                        ) );
    49174935                        api.add( id, setting );
    49184936                });
    49194937
     
    56465664                        } );
    56475665                } );
    56485666
    5649                 // Juggle the two controls that use header_textcolor
    5650                 api.control( 'display_header_text', function( control ) {
    5651                         var last = '';
    5652 
    5653                         control.elements[0].unsync( api( 'header_textcolor' ) );
     5667                // Set up display_header_text control checkbox to toggle whether header_textcolor is blank or not.
     5668                api( 'header_textcolor', function( headerTextColorSetting ) {
     5669                        api.control( 'display_header_text', function( control ) {
     5670                                control.deferred.embedded.done( function() {
     5671                                        var last = '';
    56545672
    5655                         control.element = new api.Element( control.container.find('input') );
    5656                         control.element.set( 'blank' !== control.setting() );
     5673                                        control.element = new api.Element( control.container.find( 'input' ) );
     5674                                        control.element.set( 'blank' !== headerTextColorSetting() );
    56575675
    5658                         control.element.bind( function( to ) {
    5659                                 if ( ! to )
    5660                                         last = api( 'header_textcolor' ).get();
     5676                                        control.element.bind( function( to ) {
     5677                                                if ( ! to ) {
     5678                                                        last = headerTextColorSetting();
     5679                                                }
    56615680
    5662                                 control.setting.set( to ? last : 'blank' );
    5663                         });
     5681                                                headerTextColorSetting.set( to ? last : 'blank' );
     5682                                        });
    56645683
    5665                         control.setting.bind( function( to ) {
    5666                                 control.element.set( 'blank' !== to );
     5684                                        headerTextColorSetting.bind( function( to ) {
     5685                                                control.element.set( 'blank' !== to );
     5686                                        });
     5687                                });
    56675688                        });
    56685689                });
    56695690
  • 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 b9c83c7575..8f7b4ae505 100644
    class WP_Customize_Control { 
    316316                $this->json['label'] = $this->label;
    317317                $this->json['description'] = $this->description;
    318318                $this->json['instanceNumber'] = $this->instance_number;
     319                $this->json['value'] = $this->value();
     320                $this->json['link'] = $this->get_link();
     321                $this->json['choices'] = $this->choices;
     322                $this->json['inputAttrs'] = $this->get_input_attrs();
    319323
    320324                if ( 'dropdown-pages' === $this->type ) {
    321325                        $this->json['allow_addition'] = $this->allow_addition;
    class WP_Customize_Control { 
    459463         * @since 4.0.0
    460464         */
    461465        public function input_attrs() {
    462                 foreach ( $this->input_attrs as $attr => $value ) {
    463                         echo $attr . '="' . esc_attr( $value ) . '" ';
     466                echo $this->get_input_attrs();
     467        }
     468
     469        /**
     470         * Return html for the custom attributes for the control's input element.
     471         *
     472         * @since 4.3.0
     473         * @return string Input attributes html.
     474         */
     475        public function get_input_attrs() {
     476                $attrs = '';
     477                foreach( $this->input_attrs as $attr => $value ) {
     478                        $attrs .= $attr . '="' . esc_attr( $value ) . '" ';
    464479                }
     480                return $attrs;
    465481        }
    466482
    467483        /**
    class WP_Customize_Control { 
    475491         * Control content can alternately be rendered in JS. See WP_Customize_Control::print_template().
    476492         *
    477493         * @since 3.4.0
     494         * @since 4.3.0 Most core control types are rendered with a content template instead.
    478495         */
    479496        protected function render_content() {
    480497                switch( $this->type ) {
    481                         case 'checkbox':
    482                                 ?>
    483                                 <label>
    484                                         <input type="checkbox" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); checked( $this->value() ); ?> />
    485                                         <?php echo esc_html( $this->label ); ?>
    486                                         <?php if ( ! empty( $this->description ) ) : ?>
    487                                                 <span class="description customize-control-description"><?php echo $this->description; ?></span>
    488                                         <?php endif; ?>
    489                                 </label>
    490                                 <?php
    491                                 break;
    492                         case 'radio':
    493                                 if ( empty( $this->choices ) )
    494                                         return;
    495 
    496                                 $name = '_customize-radio-' . $this->id;
    497 
    498                                 if ( ! empty( $this->label ) ) : ?>
    499                                         <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
    500                                 <?php endif;
    501                                 if ( ! empty( $this->description ) ) : ?>
    502                                         <span class="description customize-control-description"><?php echo $this->description ; ?></span>
    503                                 <?php endif;
    504 
    505                                 foreach ( $this->choices as $value => $label ) :
    506                                         ?>
    507                                         <label>
    508                                                 <input type="radio" value="<?php echo esc_attr( $value ); ?>" name="<?php echo esc_attr( $name ); ?>" <?php $this->link(); checked( $this->value(), $value ); ?> />
    509                                                 <?php echo esc_html( $label ); ?><br/>
    510                                         </label>
    511                                         <?php
    512                                 endforeach;
    513                                 break;
    514                         case 'select':
    515                                 if ( empty( $this->choices ) )
    516                                         return;
    517 
    518                                 ?>
    519                                 <label>
    520                                         <?php if ( ! empty( $this->label ) ) : ?>
    521                                                 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
    522                                         <?php endif;
    523                                         if ( ! empty( $this->description ) ) : ?>
    524                                                 <span class="description customize-control-description"><?php echo $this->description; ?></span>
    525                                         <?php endif; ?>
    526 
    527                                         <select <?php $this->link(); ?>>
    528                                                 <?php
    529                                                 foreach ( $this->choices as $value => $label )
    530                                                         echo '<option value="' . esc_attr( $value ) . '"' . selected( $this->value(), $value, false ) . '>' . $label . '</option>';
    531                                                 ?>
    532                                         </select>
    533                                 </label>
    534                                 <?php
    535                                 break;
    536                         case 'textarea':
    537                                 ?>
    538                                 <label>
    539                                         <?php if ( ! empty( $this->label ) ) : ?>
    540                                                 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
    541                                         <?php endif;
    542                                         if ( ! empty( $this->description ) ) : ?>
    543                                                 <span class="description customize-control-description"><?php echo $this->description; ?></span>
    544                                         <?php endif; ?>
    545                                         <textarea rows="5" <?php $this->input_attrs(); ?> <?php $this->link(); ?>><?php echo esc_textarea( $this->value() ); ?></textarea>
    546                                 </label>
    547                                 <?php
    548                                 break;
    549498                        case 'dropdown-pages':
    550499                                ?>
    551500                                <label>
    class WP_Customize_Control { 
    609558                                        </div>
    610559                                <?php endif;
    611560                                break;
    612                         default:
    613                                 ?>
    614                                 <label>
    615                                         <?php if ( ! empty( $this->label ) ) : ?>
    616                                                 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
    617                                         <?php endif;
    618                                         if ( ! empty( $this->description ) ) : ?>
    619                                                 <span class="description customize-control-description"><?php echo $this->description; ?></span>
    620                                         <?php endif; ?>
    621                                         <input type="<?php echo esc_attr( $this->type ); ?>" <?php $this->input_attrs(); ?> value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); ?> />
    622                                 </label>
    623                                 <?php
    624                                 break;
    625561                }
    626562        }
    627563
    class WP_Customize_Control { 
    632568         * WP_Customize_Manager::register_control_type().
    633569         *
    634570         * In the future, this will also print the template for the control's container
    635          * element and be override-able.
     571         * element and be override-able. @link https://core.trac.wordpress.org/ticket/30741
    636572         *
    637573         * @since 4.1.0
    638574         */
    class WP_Customize_Control { 
    653589         * @see WP_Customize_Control::print_template()
    654590         *
    655591         * @since 4.1.0
     592         * @since 4.3.0 Core base control class uses JS templates by default.
    656593         */
    657         protected function content_template() {}
     594        protected function content_template() {
     595        ?>
     596                <# switch ( data.type ) {
     597                        case 'checkbox': #>
     598                                <label>
     599                                        <input type="checkbox" value="{{ data.value }}" {{{ data.link }}} <# if ( data.value ) { #> checked="checked" <# } #> />
     600                                        {{ data.label }}
     601                                        <# if ( data.description ) { #>
     602                                                <span class="description customize-control-description">{{ data.description }}</span>
     603                                        <# } #>
     604                                </label>
     605                                <#
     606                                break;
     607                        case 'radio':
     608                                if ( ! data.choices ) {
     609                                        return;
     610                                }
     611
     612                                var name = '_customize-radio-' + data.id;
    658613
     614                                if ( data.label ) { #>
     615                                        <span class="customize-control-title">{{ data.label }}</span>
     616                                <# } if ( data.description ) { #>
     617                                        <span class="description customize-control-description">{{{ data.description }}}</span>
     618                                <# }
     619
     620                                for ( key in data.choices ) { #>
     621                                        <label>
     622                                                <input type="radio" value="{{ key }}" name="{{ name }}" {{{ data.link }}} <# if ( data.choices[key] === data.value ) { #> checked="checked" <# } #> />
     623                                                {{ data.label }}<br/>
     624                                        </label>
     625                                <# }
     626                                break;
     627                        case 'select':
     628                                if ( ! data.choices ) {
     629                                        return;
     630                                }
     631                                #>
     632                                <label>
     633                                        <# if ( data.label ) { #>
     634                                                <span class="customize-control-title">{{ data.label }}</span>
     635                                        <# } if ( data.description ) { #>
     636                                                <span class="description customize-control-description">{{{ data.description }}}</span>
     637                                        <# } #>
     638
     639                                        <select {{{ data.link }}}>
     640                                                <# for ( key in data.choices ) { #>
     641                                                        <option value="{{ key }}" <# if ( data.choices[key] === data.value ) { #>selected="selected" <# } #>>{{ data.label }}</option>
     642                                                <# } #>
     643                                        </select>
     644                                </label>
     645                                <#
     646                                break;
     647                        case 'textarea':
     648                                #>
     649                                <label>
     650                                        <# if ( data.label ) { #>
     651                                                <span class="customize-control-title">{{ data.label }}</span>
     652                                        <# } if ( data.description ) { #>
     653                                                <span class="description customize-control-description">{{{ data.description }}}</span>
     654                                        <# } #>
     655
     656                                        <textarea rows="5" {{{ data.inputAttrs }}} {{{ data.link }}}>{{ data.value }}</textarea>
     657                                </label>
     658                                <#
     659                                break;
     660                        default:
     661                                #>
     662                                <label>
     663                                        <# if ( data.label ) { #>
     664                                                <span class="customize-control-title">{{ data.label }}</span>
     665                                        <# } if ( data.description ) { #>
     666                                                <span class="description customize-control-description">{{{ data.description }}}</span>
     667                                        <# } #>
     668
     669                                        <input type="{{ data.type }}" {{{ data.inputAttrs }}} value="{{ data.value }}" {{{ data.link }}} />
     670                                </label>
     671                <# } #>
     672        <?php
     673        }
    659674}
    660675
    661676/**
  • src/wp-includes/class-wp-customize-manager.php

    diff --git src/wp-includes/class-wp-customize-manager.php src/wp-includes/class-wp-customize-manager.php
    index 5e66a1aa75..76876163c7 100644
    final class WP_Customize_Manager { 
    32003200                        $control->print_template();
    32013201                }
    32023202
     3203                // Base control, for built-in & fallback types.
     3204                $control = new WP_Customize_Control( $this, 'temp', array( 'type' => 'default' ) );
     3205                $control->print_template();
     3206
     3207                $header_image_control = $this->get_control( 'header_image' );
     3208                if ( $header_image_control instanceof WP_Customize_Header_Image_Control ) {
     3209                        $header_image_control->print_header_image_template();
     3210                }
     3211
    32033212                ?>
    32043213                <script type="text/html" id="tmpl-customize-notification">
    32053214                        <li class="notice notice-{{ data.type || 'info' }} {{ data.alt ? 'notice-alt' : '' }} {{ data.dismissible ? 'is-dismissible' : '' }}" data-code="{{ data.code }}" data-type="{{ data.type }}">
    final class WP_Customize_Manager { 
    38843893                        'priority'       => 40,
    38853894                ) );
    38863895
    3887                 $this->add_setting( 'header_textcolor', array(
     3896                $header_text_color_setting = $this->add_setting( 'header_textcolor', array(
    38883897                        'theme_supports' => array( 'custom-header', 'header-text' ),
    38893898                        'default'        => get_theme_support( 'custom-header', 'default-text-color' ),
    38903899
    final class WP_Customize_Manager { 
    38953904                // Input type: checkbox
    38963905                // With custom value
    38973906                $this->add_control( 'display_header_text', array(
    3898                         'settings' => 'header_textcolor',
     3907                        'settings' => array(), // Settingless-control.
    38993908                        'label'    => __( 'Display Site Title and Tagline' ),
    39003909                        'section'  => 'title_tagline',
    39013910                        'type'     => 'checkbox',
    39023911                        'priority' => 40,
     3912                        'capability' => $header_text_color_setting->capability,
    39033913                ) );
    39043914
    39053915                $this->add_control( new WP_Customize_Color_Control( $this, 'header_textcolor', array(
  • src/wp-includes/class-wp-customize-setting.php

    diff --git src/wp-includes/class-wp-customize-setting.php src/wp-includes/class-wp-customize-setting.php
    index 601990f532..a5bddab000 100644
    class WP_Customize_Setting { 
    805805                        'transport' => $this->transport,
    806806                        'dirty'     => $this->dirty,
    807807                        'type'      => $this->type,
     808                        'default'   => $this->default,
    808809                );
    809810        }
    810811
  • src/wp-includes/customize/class-wp-customize-header-image-control.php

    diff --git src/wp-includes/customize/class-wp-customize-header-image-control.php src/wp-includes/customize/class-wp-customize-header-image-control.php
    index 8bf93e7df1..eab94c5d8d 100644
    class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control { 
    8484        }
    8585
    8686        /**
     87         * @todo This should go in the content_template() method.
    8788         */
    8889        public function print_header_image_template() {
    8990                ?>
    class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control { 
    157158        /**
    158159         */
    159160        public function render_content() {
    160                 $this->print_header_image_template();
    161161                $visibility = $this->get_current_image_src() ? '' : ' style="display:none" ';
    162162                $width = absint( get_theme_support( 'custom-header', 'width' ) );
    163163                $height = absint( get_theme_support( 'custom-header', 'height' ) );