Make WordPress Core

Changeset 20936


Ignore:
Timestamp:
05/26/2012 06:44:31 PM (13 years ago)
Author:
koopersmith
Message:

Theme Customizer: Ensure that JS color controls always use real color values, even if the server-side value is a hex value without a hash. fixes #20448, see #19910.

Adds WP_Customize_Setting->sanitize_js_callback and 'customize_sanitize_js_$settingID' filter, to filter values before they're passed to JS using WP_Customize_Setting->js_value().

Adds support for regular hex colors to the color picker.

Changes color methods:

  • sanitize_hex_color() accepts 3 and 6 digit hex colors (with hashes) and the empty string.
  • sanitize_hex_color_no_hash() accepts 3 and 6 digit hex colors (without hashes) and the empty string.
  • maybe_hash_hex_color() ensures that a hex color has a hash, and otherwise leaves the value untouched.
Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-content/themes/twentyeleven/inc/theme-options.php

    r20916 r20936  
    484484        'default'           => twentyeleven_get_default_link_color( $options['color_scheme'] ),
    485485        'type'              => 'option',
    486         'sanitize_callback' => 'twentyeleven_sanitize_hexcolor',
     486        'sanitize_callback' => 'sanitize_hex_color',
    487487        'capability'        => 'edit_theme_options',
    488488    ) );
     
    521521
    522522/**
    523  * Sanitize user input hex color value
    524  *
    525  * @uses sanitize_hexcolor()
    526  * @param $color string
    527  * @return string sanitized with prefixed # character
    528  */
    529 function twentyeleven_sanitize_hexcolor( $color ) {
    530     return '#' . sanitize_hexcolor( $color );
    531 }
    532 
    533 /**
    534523 * Bind JS handlers to make Theme Customizer preview reload changes asynchronously.
    535524 * Used with blogname and blogdescription.
  • trunk/wp-includes/class-wp-customize-control.php

    r20928 r20936  
    266266                    <div class="dropdown-arrow"></div>
    267267                </div>
    268                 <div class="color-picker-hex">
    269                     <span>#</span>
    270                     <input type="text" <?php $this->link(); ?> />
    271                 </div>
     268                <input class="color-picker-hex" type="text" maxlength="7" placeholder="<?php esc_attr_e('Hex Value'); ?>" />
    272269            </div>
    273270            <div class="farbtastic-placeholder"></div>
  • trunk/wp-includes/class-wp-customize-manager.php

    r20933 r20936  
    668668
    669669        $this->add_setting( 'header_textcolor', array(
    670             'sanitize_callback' => 'sanitize_header_textcolor',
    671670            'theme_supports' => array( 'custom-header', 'header-text' ),
    672671            'default'        => get_theme_support( 'custom-header', 'default-text-color' ),
     672
     673            'sanitize_callback'    => array( $this, '_sanitize_header_textcolor' ),
     674            'sanitize_js_callback' => 'maybe_hash_hex_color',
    673675        ) );
    674676
     
    690692        // With sanitize_callback
    691693        $this->add_setting( 'background_color', array(
    692             'default'           => get_theme_support( 'custom-background', 'default-color' ),
    693             'sanitize_callback' => 'sanitize_hexcolor',
    694             'theme_supports'    => 'custom-background',
     694            'default'        => get_theme_support( 'custom-background', 'default-color' ),
     695            'theme_supports' => 'custom-background',
     696
     697            'sanitize_callback'    => 'sanitize_hex_color_no_hash',
     698            'sanitize_js_callback' => 'maybe_hash_hex_color',
    695699        ) );
    696700
     
    877881        ) );
    878882    }
     883
     884    /**
     885     * Callback for validating the header_textcolor value.
     886     *
     887     * Accepts 'blank', and otherwise uses sanitize_hex_color_no_hash().
     888     *
     889     * @since 3.4.0
     890     */
     891    public function _sanitize_header_textcolor( $color ) {
     892        return ( 'blank' === $color ) ? 'blank' : sanitize_hex_color_no_hash( $color );
     893    }
    879894};
    880895
    881 // Callback function for sanitizing the header textcolor setting.
    882 function sanitize_header_textcolor( $color ) {
    883     if ( $color == 'blank' )
    884         return 'blank';
    885 
    886     return sanitize_hexcolor( $color );
    887 }
    888 
    889 // Callback function for sanitizing a hex color
    890 function sanitize_hexcolor( $color ) {
    891     $color = preg_replace( '/[^0-9a-fA-F]/', '', $color );
     896/**
     897 * Validates a hex color.
     898 *
     899 * Returns either '', a 3 or 6 digit hex color (with #), or null.
     900 * For validating values without a #, see sanitize_hex_color_no_hash().
     901 *
     902 * @since 3.4.0
     903 */
     904function sanitize_hex_color( $color ) {
     905    if ( '' === $color )
     906        return '';
    892907
    893908    // 3 or 6 hex digits, or the empty string.
    894     if ( preg_match('|^([A-Fa-f0-9]{3}){0,2}$|', $color ) )
     909    if ( preg_match('|^#([A-Fa-f0-9]{3}){1,2}$|', $color ) )
    895910        return $color;
    896911
    897912    return null;
    898913}
     914
     915/**
     916 * Sanitizes a hex color without a hash. Use sanitize_hex_color() when possible.
     917 *
     918 * Saving hex colors without a hash puts the burden of adding the hash on the
     919 * UI, which makes it difficult to use or upgrade to other color types such as
     920 * rgba, hsl, rgb, and html color names.
     921 *
     922 * Returns either '', a 3 or 6 digit hex color (without a #), or null.
     923 *
     924 * @since 3.4.0
     925 */
     926function sanitize_hex_color_no_hash( $color ) {
     927    $color = ltrim( $color, '#' );
     928
     929    if ( '' === $color )
     930        return '';
     931
     932    return sanitize_hex_color( '#' . $color ) ? $color : null;
     933}
     934
     935/**
     936 * Ensures that any hex color is properly hashed.
     937 * Otherwise, returns value untouched.
     938 *
     939 * This method should only be necessary if using sanitize_hex_color_no_hash().
     940 *
     941 * @since 3.4.0
     942 */
     943function maybe_hash_hex_color( $color ) {
     944    if ( $unhashed = sanitize_hex_color_no_hash( $color ) )
     945        return '#' . $unhashed;
     946
     947    return $color;
     948}
  • trunk/wp-includes/class-wp-customize-setting.php

    r20809 r20936  
    1212    public $id;
    1313
    14     public $type              = 'theme_mod';
    15     public $capability        = 'edit_theme_options';
    16     public $theme_supports    = '';
    17     public $default           = '';
    18     public $sanitize_callback = '';
    19     public $transport         = 'refresh';
     14    public $type            = 'theme_mod';
     15    public $capability      = 'edit_theme_options';
     16    public $theme_supports  = '';
     17    public $default         = '';
     18    public $transport       = 'refresh';
     19
     20    public $sanitize_callback    = '';
     21    public $sanitize_js_callback = '';
    2022
    2123    protected $id_data = array();
     
    5052            $this->id .= '[' . implode( '][', $this->id_data[ 'keys' ] ) . ']';
    5153
    52         if ( $this->sanitize_callback != '' )
    53             add_filter( "customize_sanitize_{$this->id}", $this->sanitize_callback );
     54        if ( $this->sanitize_callback )
     55            add_filter( "customize_sanitize_{$this->id}", $this->sanitize_callback, 10, 2 );
     56
     57        if ( $this->sanitize_js_callback )
     58            add_filter( "customize_sanitize_js_{$this->id}", $this->sanitize_js_callback, 10, 2 );
    5459
    5560        return $this;
     
    139144    public function sanitize( $value ) {
    140145        $value = stripslashes_deep( $value );
    141         return apply_filters( "customize_sanitize_{$this->id}", $value );
     146        return apply_filters( "customize_sanitize_{$this->id}", $value, $this );
    142147    }
    143148
     
    239244     */
    240245    public function js_value() {
    241         $value = $this->value();
     246        $value = apply_filters( "customize_sanitize_js_{$this->id}", $this->value(), $this );
    242247
    243248        if ( is_string( $value ) )
  • trunk/wp-includes/css/customize-controls.dev.css

    r20928 r20936  
    320320}
    321321
    322 .customize-section .color-picker-hex {
    323     float: left;
    324     width: 70px;
     322.customize-section input[type="text"].color-picker-hex {
     323    float: left;
     324    width: 85px;
    325325    font-family: monospace;
    326     background-color: #fff;
    327     color: #777;
    328     border: 1px solid #ccc;
    329     -webkit-border-radius: 3px;
    330     border-radius: 3px;
    331 }
    332 
    333 .customize-section .color-picker-hex span {
    334     float: left;
    335     display: block;
    336     margin: 1px -2px 0 0;
    337     line-height: 16px;
    338     padding: 3px 0 3px 8px;
    339     text-align: right;
    340     -webkit-border-radius: 3px 0 0 3px;
    341     border-radius: 3px 0 0 3px;
    342 }
    343 
    344 .customize-section .color-picker-hex input[type="text"] {
    345     width: 50px;
    346     height: 22px;
    347     line-height: 16px;
    348     color: #777;
    349     background: transparent;
    350     border: 0;
    351     -webkit-border-radius: 0 3px 3px 0;
    352     border-radius: 0 3px 3px 0;
     326    text-align: center;
     327}
     328
     329/* The centered cursor overlaps the placeholder in webkit. Hide it when selected. */
     330.customize-section input[type="text"].color-picker-hex:focus::-webkit-input-placeholder {
     331    color: transparent;
     332}
     333.customize-section input[type="text"].color-picker-hex:-moz-placeholder {
     334    color: #999;
    353335}
    354336
  • trunk/wp-includes/js/customize-controls.dev.js

    r20928 r20936  
    110110        ready: function() {
    111111            var control = this,
    112                 spot, text, update;
    113 
     112                rhex, spot, input, text, update;
     113
     114            rhex   = /^#([A-Fa-f0-9]{3}){0,2}$/;
    114115            spot   = this.container.find('.dropdown-content');
     116            input  = new api.Element( this.container.find('.color-picker-hex') );
    115117            update = function( color ) {
    116                 color = color ? '#' + color : '';
    117118                spot.css( 'background', color );
    118119                control.farbtastic.setColor( color );
    119120            };
    120121
    121             this.farbtastic = $.farbtastic( this.container.find('.farbtastic-placeholder'), function( color ) {
    122                 control.setting.set( color.replace( '#', '' ) );
    123             });
     122            this.farbtastic = $.farbtastic( this.container.find('.farbtastic-placeholder'), control.setting.set );
     123
     124            // Only pass through values that are valid hexes/empty.
     125            input.link( this.setting ).validate = function( to ) {
     126                return rhex.test( to ) ? to : null;
     127            };
    124128
    125129            this.setting.bind( update );
  • trunk/wp-includes/js/customize-preview.dev.js

    r20930 r20936  
    102102
    103103                if ( color() )
    104                     css += 'background-color: #' + color() + ';';
     104                    css += 'background-color: ' + color() + ';';
    105105
    106106                if ( image() ) {
Note: See TracChangeset for help on using the changeset viewer.