<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[20295] trunk/wp-includes: Create WP_Customize_Control to separate the process of rendering a control from fetching, previewing, and saving its values.</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg > ul, #logmsg > ol { margin-left: 0; margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://core.trac.wordpress.org/changeset/20295">20295</a></dd>
<dt>Author</dt> <dd>koopersmith</dd>
<dt>Date</dt> <dd>2012-03-28 04:14:09 +0000 (Wed, 28 Mar 2012)</dd>
</dl>
<h3>Log Message</h3>
<pre>Create WP_Customize_Control to separate the process of rendering a control from fetching, previewing, and saving its values. see <a href="http://core.trac.wordpress.org/ticket/19910">#19910</a>.
Many-to-many mapping between settings and controls.
* Settings and controls have been separated in both the PHP (WP_Customize_Setting, WP_Customize_Control) and the JS (wp.customize.Setting, wp.customize.Control).
* While most settings are tied to a single control, some require multiple controls. The 'header_textcolor' control is a good example: to hide the header text, header_textcolor is set to 'blank'.
Add 'Display Header Text' control.
A handful of miscellaneous bugfixes along the way.
Notes:
* Controls should be separated out a bit more; juggling type-specific arguments in the switch statement is rather inelegant.
* Page dropdowns are currently inactive and need to be re-linked.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkwpincludesclasswpcustomizesectionphp">trunk/wp-includes/class-wp-customize-section.php</a></li>
<li><a href="#trunkwpincludesclasswpcustomizesettingphp">trunk/wp-includes/class-wp-customize-setting.php</a></li>
<li><a href="#trunkwpincludesclasswpcustomizephp">trunk/wp-includes/class-wp-customize.php</a></li>
<li><a href="#trunkwpincludescustomizecontrolsphp">trunk/wp-includes/customize-controls.php</a></li>
<li><a href="#trunkwpincludesjscustomizebasedevjs">trunk/wp-includes/js/customize-base.dev.js</a></li>
<li><a href="#trunkwpincludesjscustomizecontrolsdevjs">trunk/wp-includes/js/customize-controls.dev.js</a></li>
<li><a href="#trunkwpincludesjspluploadwppluploaddevjs">trunk/wp-includes/js/plupload/wp-plupload.dev.js</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkwpincludesclasswpcustomizecontrolphp">trunk/wp-includes/class-wp-customize-control.php</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkwpincludesclasswpcustomizecontrolphp"></a>
<div class="addfile"><h4>Added: trunk/wp-includes/class-wp-customize-control.php (0 => 20295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/class-wp-customize-control.php         (rev 0)
+++ trunk/wp-includes/class-wp-customize-control.php        2012-03-28 04:14:09 UTC (rev 20295)
</span><span class="lines">@@ -0,0 +1,329 @@
</span><ins>+<?php
+/**
+ * Customize Control Class
+ *
+ * @package WordPress
+ * @subpackage Customize
+ * @since 3.4.0
+ */
+
+class WP_Customize_Control {
+        public $manager;
+        public $id;
+
+        public $settings;
+        public $setting;
+
+        public $priority = 10;
+        public $section = '';
+        public $label = '';
+        // @todo: remove control_params
+        public $control_params = array();
+        // @todo: remove choices
+        public $choices = array();
+
+        public $visibility;
+
+        public $type = 'text';
+
+
+        /**
+         * Constructor.
+         *
+         * If $args['settings'] is not defined, use the $id as the setting ID.
+         *
+         * @since 3.4.0
+         */
+        function __construct( $manager, $id, $args = array() ) {
+                $keys = array_keys( get_class_vars( __CLASS__ ) );
+                foreach ( $keys as $key ) {
+                        if ( isset( $args[ $key ] ) )
+                                $this->$key = $args[ $key ];
+                }
+
+                $this->manager = $manager;
+                $this->id = $id;
+
+
+                // Process settings.
+                if ( empty( $this->settings ) )
+                        $this->settings = $id;
+
+                $settings = array();
+                if ( is_array( $this->settings ) ) {
+                        foreach ( $this->settings as $key => $setting ) {
+                                $settings[ $key ] = $this->manager->get_setting( $setting );
+                        }
+                } else {
+                        $this->setting = $this->manager->get_setting( $this->settings );
+                        $settings['default'] = $this->setting;
+                }
+                $this->settings = $settings;
+        }
+
+        /**
+         * Enqueue control related scripts/styles.
+         *
+         * @since 3.4.0
+         */
+        public function enqueue() {
+                switch( $this->type ) {
+                        case 'color':
+                                wp_enqueue_script( 'farbtastic' );
+                                wp_enqueue_style( 'farbtastic' );
+                                break;
+                        case 'upload':
+                                wp_enqueue_script( 'wp-plupload' );
+                                break;
+                }
+        }
+
+
+        /**
+         * Fetch a setting's value.
+         * Grabs the main setting by default.
+         *
+         * @since 3.4.0
+         */
+        public final function value( $setting_key = 'default' ) {
+                if ( isset( $this->settings[ $setting_key ] ) )
+                        return $this->settings[ $setting_key ]->value();
+        }
+
+        public function json( $args = array() ) {
+                $settings = array();
+                foreach ( $this->settings as $key => $setting ) {
+                        $settings[ $key ] = $setting->id;
+                }
+
+                return array(
+                        'type' => $this->type,
+                        'params' => wp_parse_args( wp_parse_args( $args, array(
+                                'settings' => $settings,
+                        ) ), $this->control_params ),
+                );
+        }
+
+        /**
+         * Check if the theme supports the control and check user capabilities.
+         *
+         * @since 3.4.0
+         *
+         * @return bool False if theme doesn't support the control or user doesn't have the required permissions, otherwise true.
+         */
+        public final function check_capabilities() {
+                foreach ( $this->settings as $setting ) {
+                        if ( ! $setting->check_capabilities() )
+                                return false;
+                }
+
+                $section = $this->manager->get_section( $this->section );
+                if ( isset( $section ) && ! $section->check_capabilities() )
+                        return false;
+
+                return true;
+        }
+
+        /**
+         * Check capabiliites and render the control.
+         *
+         * @since 3.4.0
+         */
+        public final function maybe_render() {
+                if ( ! $this->check_capabilities() )
+                        return;
+
+                do_action( 'customize_render_control', $this );
+                do_action( 'customize_render_control_' . $this->id, $this );
+
+                $this->render();
+        }
+
+        /**
+         * Render the control. Renders the control wrapper, then calls $this->render_content().
+         *
+         * @since 3.4.0
+         */
+        protected function render() {
+                $id = 'customize-control-' . $this->id;
+                $class = 'customize-control customize-control-' . $this->type;
+
+                $style = '';
+                if ( $this->visibility ) {
+                        if ( is_string( $this->visibility ) ) {
+                                $visibility_id = $this->visibility;
+                                $visibility_value = true;
+                        } else {
+                                $visibility_id = $this->visibility[0];
+                                $visibility_value = $this->visibility[1];
+                        }
+                        $visibility_setting = $this->manager->get_setting( $visibility_id );
+
+                        if ( $visibility_setting && $visibility_value != $visibility_setting->value() )
+                                $style = 'style="display:none;"';
+                }
+
+                ?><li id="<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $class ); ?>" <?php echo $style; ?>>
+                        <?php $this->render_content(); ?>
+                </li><?php
+        }
+
+        public function link( $setting_key = 'default' ) {
+                if ( ! isset( $this->settings[ $setting_key ] ) )
+                        return;
+
+                echo 'data-customize-setting-link="' . esc_attr( $this->settings[ $setting_key ]->id ) . '"';
+        }
+
+        /**
+         * Render the control's content.
+         *
+         * Allows the content to be overriden without having to rewrite the wrapper.
+         *
+         * @since 3.4.0
+         */
+        protected function render_content() {
+                switch( $this->type ) {
+                        case 'text':
+                                ?>
+                                <label>
+                                        <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
+                                        <input type="text" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); ?> />
+                                </label>
+                                <?php
+                                break;
+                        case 'color':
+                                ?>
+                                <label>
+                                        <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
+                                        <div class="color-picker">
+                                                <input type="hidden" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); ?> />
+                                                <a href="#"></a>
+                                                <div class="color-picker-controls">
+                                                        <div class="farbtastic-placeholder"></div>
+                                                        <div class="color-picker-details">
+                                                                <div class="color-picker-hex">
+                                                                        <span>#</span>
+                                                                        <input type="text" <?php $this->link(); ?> />
+                                                                </div>
+                                                        </div>
+                                                </div>
+                                        </div>
+                                </label>
+                                <?php
+                                break;
+                        case 'checkbox':
+                                ?>
+                                <label>
+                                        <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
+                                        <input type="checkbox" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); checked( $this->value() ); ?> class="customize-control-content" />
+                                </label>
+                                <?php
+                                break;
+                        case 'radio':
+                                if ( empty( $this->choices ) )
+                                        return;
+
+                                $name = '_customize-radio-' . $this->id;
+
+                                ?>
+                                <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
+                                <?php
+                                foreach ( $this->choices as $value => $label ) :
+                                        ?>
+                                        <label>
+                                                <input type="radio" value="<?php echo esc_attr( $value ); ?>" name="<?php echo esc_attr( $name ); ?>" <?php $this->link(); checked( $this->value(), $value ); ?> />
+                                                <?php echo esc_html( $label ); ?><br/>
+                                        </label>
+                                        <?php
+                                endforeach;
+                                break;
+                        case 'select':
+                                if ( empty( $this->choices ) )
+                                        return;
+
+                                ?>
+                                <label>
+                                        <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
+                                        <select <?php $this->link(); ?> class="customize-control-content">
+                                                <?php
+                                                foreach ( $this->choices as $value => $label )
+                                                        echo '<option value="' . esc_attr( $value ) . '"' . selected( $this->value(), $value, false ) . '>' . $label . '</option>';
+                                                ?>
+                                        </select>
+                                </label>
+                                <?php
+                                break;
+                        case 'upload':
+                                ?>
+                                <label>
+                                        <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
+                                        <div>
+                                                <input type="hidden" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); ?> />
+                                                <a href="#" class="button-secondary upload"><?php _e( 'Upload' ); ?></a>
+                                                <a href="#" class="remove"><?php _e( 'Remove' ); ?></a>
+                                        </div>
+                                </label>
+                                <?php
+                                break;
+                        case 'image':
+                                $value = $this->value();
+
+                                $image = $value;
+                                if ( isset( $this->control_params['get_url'] ) )
+                                        $image = call_user_func( $this->control_params['get_url'], $image );
+
+                                ?>
+                                <label>
+                                        <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
+                                        <input type="hidden" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); ?> />
+                                        <div class="customize-image-picker">
+                                                <div class="thumbnail">
+                                                        <?php if ( empty( $image ) ): ?>
+                                                                <img style="display:none;" />
+                                                        <?php else: ?>
+                                                                <img src="<?php echo esc_url( $image ); ?>" />
+                                                        <?php endif; ?>
+                                                </div>
+                                                <div class="actions">
+                                                        <a href="#" class="upload"><?php _e( 'Upload New' ); ?></a>
+                                                        <a href="#" class="change"><?php _e( 'Change Image' ); ?></a>
+                                                        <a href="#" class="remove"><?php _e( 'Remove Image' ); ?></a>
+                                                </div>
+                                                <div class="library">
+                                                        <ul>
+                                                                <?php foreach ( $this->control_params['tabs'] as $tab ): ?>
+                                                                        <li data-customize-tab='<?php echo esc_attr( $tab[0] ); ?>'>
+                                                                                <?php echo esc_html( $tab[1] ); ?>
+                                                                        </li>
+                                                                <?php endforeach; ?>
+                                                        </ul>
+                                                        <?php foreach ( $this->control_params['tabs'] as $tab ): ?>
+                                                                <div class="library-content" data-customize-tab='<?php echo esc_attr( $tab[0] ); ?>'>
+                                                                        <?php call_user_func( $tab[2] ); ?>
+                                                                </div>
+                                                        <?php endforeach; ?>
+                                                </div>
+                                        </div>
+                                </label>
+                                <?php
+                                break;
+                        case 'dropdown-pages':
+                                printf(
+                                        '<label class="customize-control-select"><span class="customize-control-title">%s</span> %s</label>',
+                                        $this->label,
+                                        wp_dropdown_pages(
+                                                array(
+                                                        // @todo: this is going to need fixing.
+                                                        // 'name' => $this->get_name(),
+                                                        'echo' => 0,
+                                                        'show_option_none' => __( '&mdash; Select &mdash;' ),
+                                                        'option_none_value' => '0',
+                                                        'selected' => $this->value(),
+                                                )
+                                        )
+                                );
+                                break;
+                }
+        }
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkwpincludesclasswpcustomizesectionphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/class-wp-customize-section.php (20294 => 20295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/class-wp-customize-section.php        2012-03-28 02:58:21 UTC (rev 20294)
+++ trunk/wp-includes/class-wp-customize-section.php        2012-03-28 04:14:09 UTC (rev 20295)
</span><span class="lines">@@ -15,7 +15,7 @@
</span><span class="cx">         public $theme_supports = '';
</span><span class="cx">         public $title = '';
</span><span class="cx">         public $description = '';
</span><del>-        public $settings;
</del><ins>+        public $controls;
</ins><span class="cx">
</span><span class="cx">         /**
</span><span class="cx">          * Constructor.
</span><span class="lines">@@ -35,7 +35,7 @@
</span><span class="cx">                 $this->manager = $manager;
</span><span class="cx">                 $this->id = $id;
</span><span class="cx">
</span><del>-                $this->settings = array(); // Users cannot customize the $settings array.
</del><ins>+                $this->controls = array(); // Users cannot customize the $controls array.
</ins><span class="cx">
</span><span class="cx">                 return $this;
</span><span class="cx">         }
</span><span class="lines">@@ -84,8 +84,8 @@
</span><span class="cx">                         <h3 class="customize-section-title" title="<?php echo esc_attr( $this->description ); ?>"><?php echo esc_html( $this->title ); ?></h3>
</span><span class="cx">                         <ul class="customize-section-content">
</span><span class="cx">                                 <?php
</span><del>-                                foreach ( $this->settings as $setting )
-                                        $setting->maybe_render();
</del><ins>+                                foreach ( $this->controls as $control )
+                                        $control->maybe_render();
</ins><span class="cx">                                 ?>
</span><span class="cx">                         </ul>
</span><span class="cx">                 </li>
</span></span></pre></div>
<a id="trunkwpincludesclasswpcustomizesettingphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/class-wp-customize-setting.php (20294 => 20295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/class-wp-customize-setting.php        2012-03-28 02:58:21 UTC (rev 20294)
+++ trunk/wp-includes/class-wp-customize-setting.php        2012-03-28 04:14:09 UTC (rev 20295)
</span><span class="lines">@@ -10,18 +10,12 @@
</span><span class="cx"> class WP_Customize_Setting {
</span><span class="cx">         public $manager;
</span><span class="cx">         public $id;
</span><del>-        public $priority = 10;
-        public $section = '';
-        public $label = '';
-        public $control = 'text';
-        public $control_params = array();
</del><ins>+
</ins><span class="cx">         public $type = 'theme_mod';
</span><del>-        public $choices = array();
</del><span class="cx">         public $capability = 'edit_theme_options';
</span><span class="cx">         public $theme_supports = '';
</span><span class="cx">         public $default = '';
</span><span class="cx">         public $sanitize_callback = '';
</span><del>-        public $visibility;
</del><span class="cx">
</span><span class="cx">         protected $id_data = array();
</span><span class="cx">         private $_post_value; // Cached, sanitized $_POST value.
</span><span class="lines">@@ -64,23 +58,6 @@
</span><span class="cx">         }
</span><span class="cx">
</span><span class="cx">         /**
</span><del>-         * Enqueue setting related scripts/styles.
-         *
-         * @since 3.4.0
-         */
-        public function enqueue() {
-                switch( $this->control ) {
-                        case 'color':
-                                wp_enqueue_script( 'farbtastic' );
-                                wp_enqueue_style( 'farbtastic' );
-                                break;
-                        case 'upload':
-                                wp_enqueue_script( 'wp-plupload' );
-                                break;
-                }
-        }
-
-        /**
</del><span class="cx">          * Handle previewing the setting.
</span><span class="cx">          *
</span><span class="cx">          * @since 3.4.0
</span><span class="lines">@@ -275,230 +252,10 @@
</span><span class="cx">                 if ( $this->theme_supports && ! call_user_func_array( 'current_theme_supports', (array) $this->theme_supports ) )
</span><span class="cx">                         return false;
</span><span class="cx">
</span><del>-                $section = $this->manager->get_section( $this->section );
-                if ( isset( $section ) && ! $section->check_capabilities() )
-                        return false;
-
</del><span class="cx">                 return true;
</span><span class="cx">         }
</span><span class="cx">
</span><span class="cx">         /**
</span><del>-         * Check capabiliites and render the control.
-         *
-         * @since 3.4.0
-         */
-        public final function maybe_render() {
-                if ( ! $this->check_capabilities() )
-                        return;
-
-                do_action( 'customize_render_setting', $this );
-                do_action( 'customize_render_setting_' . $this->id, $this );
-
-                $this->render();
-        }
-
-        /**
-         * Render the control. Renders the control wrapper, then calls $this->render_content().
-         *
-         * @since 3.4.0
-         */
-        protected function render() {
-
-                $id = 'customize-control-' . $this->id;
-                $class = 'customize-control customize-control-' . $this->control;
-
-                $style = '';
-                if ( $this->visibility ) {
-                        if ( is_string( $this->visibility ) ) {
-                                $visibility_id = $this->visibility;
-                                $visibility_value = true;
-                        } else {
-                                $visibility_id = $this->visibility[0];
-                                $visibility_value = $this->visibility[1];
-                        }
-                        $visibility_setting = $this->manager->get_setting( $visibility_id );
-
-                        if ( $visibility_setting && $visibility_value != $visibility_setting->value() )
-                                $style = 'style="display:none;"';
-                }
-
-                ?><li id="<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $class ); ?>" <?php echo $style; ?>>
-                        <?php $this->render_content(); ?>
-                </li><?php
-        }
-
-        /**
-         * Render the control's content.
-         *
-         * Allows the content to be overriden without having to rewrite the wrapper.
-         *
-         * @since 3.4.0
-         */
-        protected function render_content() {
-                switch( $this->control ) {
-                        case 'text':
-                                ?>
-                                <label>
-                                        <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
-                                        <input type="text" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->name(); ?> />
-                                </label>
-                                <?php
-                                break;
-                        case 'color':
-                                ?>
-                                <label>
-                                        <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
-                                        <div class="color-picker">
-                                                <input type="hidden" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->name(); ?> />
-                                                <a href="#"></a>
-                                                <div class="color-picker-controls">
-                                                        <div class="farbtastic-placeholder"></div>
-                                                        <div class="color-picker-details">
-                                                                <div class="color-picker-hex">
-                                                                        <span>#</span>
-                                                                        <input type="text" />
-                                                                </div>
-                                                        </div>
-                                                </div>
-                                        </div>
-                                </label>
-                                <?php
-                                break;
-                        case 'checkbox':
-                                ?>
-                                <label>
-                                        <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
-                                        <input type="checkbox" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->name(); checked( $this->value() ); ?> class="customize-control-content" />
-                                </label>
-                                <?php
-                                break;
-                        case 'radio':
-                                if ( empty( $this->choices ) )
-                                        return;
-
-                                ?>
-                                <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
-                                <?php
-                                foreach ( $this->choices as $value => $label ) :
-                                        ?>
-                                        <label>
-                                                <input type="radio" value="<?php echo esc_attr( $value ); ?>" <?php $this->name(); checked( $this->value(), $value ); ?> />
-                                                <?php echo esc_html( $label ); ?><br/>
-                                        </label>
-                                        <?php
-                                endforeach;
-                                break;
-                        case 'select':
-                                if ( empty( $this->choices ) )
-                                        return;
-
-                                ?>
-                                <label>
-                                        <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
-                                        <select <?php $this->name(); ?> class="customize-control-content">
-                                                <?php
-                                                foreach ( $this->choices as $value => $label )
-                                                        echo '<option value="' . esc_attr( $value ) . '"' . selected( $this->value(), $value, false ) . '>' . $label . '</option>';
-                                                ?>
-                                        </select>
-                                </label>
-                                <?php
-                                break;
-                        case 'upload':
-                                ?>
-                                <label>
-                                        <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
-                                        <div>
-                                                <input type="hidden" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->name(); ?> />
-                                                <a href="#" class="button-secondary upload"><?php _e( 'Upload' ); ?></a>
-                                                <a href="#" class="remove"><?php _e( 'Remove' ); ?></a>
-                                        </div>
-                                </label>
-                                <?php
-                                break;
-                        case 'image':
-                                $value = $this->value();
-
-                                $image = $value;
-                                if ( isset( $this->control_params['get_url'] ) )
-                                        $image = call_user_func( $this->control_params['get_url'], $image );
-
-                                ?>
-                                <label>
-                                        <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
-                                        <input type="hidden" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->name(); ?> />
-                                        <div class="customize-image-picker">
-                                                <div class="thumbnail">
-                                                        <?php if ( empty( $image ) ): ?>
-                                                                <img style="display:none;" />
-                                                        <?php else: ?>
-                                                                <img src="<?php echo esc_url( $image ); ?>" />
-                                                        <?php endif; ?>
-                                                </div>
-                                                <div class="actions">
-                                                        <a href="#" class="upload"><?php _e( 'Upload New' ); ?></a>
-                                                        <a href="#" class="change"><?php _e( 'Change Image' ); ?></a>
-                                                        <a href="#" class="remove"><?php _e( 'Remove Image' ); ?></a>
-                                                </div>
-                                                <div class="library">
-                                                        <ul>
-                                                                <?php foreach ( $this->control_params['tabs'] as $tab ): ?>
-                                                                        <li data-customize-tab='<?php echo esc_attr( $tab[0] ); ?>'>
-                                                                                <?php echo esc_html( $tab[1] ); ?>
-                                                                        </li>
-                                                                <?php endforeach; ?>
-                                                        </ul>
-                                                        <?php foreach ( $this->control_params['tabs'] as $tab ): ?>
-                                                                <div class="library-content" data-customize-tab='<?php echo esc_attr( $tab[0] ); ?>'>
-                                                                        <?php call_user_func( $tab[2] ); ?>
-                                                                </div>
-                                                        <?php endforeach; ?>
-                                                </div>
-                                        </div>
-                                </label>
-                                <?php
-                                break;
-                        case 'dropdown-pages':
-                                printf(
-                                        '<label class="customize-control-select"><span class="customize-control-title">%s</span> %s</label>',
-                                        $this->label,
-                                        wp_dropdown_pages(
-                                                array(
-                                                        'name' => $this->get_name(),
-                                                        'echo' => 0,
-                                                        'show_option_none' => __( '&mdash; Select &mdash;' ),
-                                                        'option_none_value' => '0',
-                                                        'selected' => get_option( $this->id )
-                                                )
-                                        )
-                                );
-                                break;
-                }
-        }
-
-        /**
-         * Retrieve the name attribute for an input.
-         *
-         * @since 3.4.0
-         *
-         * @return string The name.
-         */
-        public final function get_name() {
-                return self::name_prefix . esc_attr( $this->id );
-        }
-
-        /**
-         * Echo the HTML name attribute for an input.
-         *
-         * @since 3.4.0
-         *
-         * @return string The HTML name attribute.
-         */
-        public final function name() {
-                echo 'name="' . $this->get_name() . '"';
-        }
-
-        /**
</del><span class="cx">          * Multidimensional helper function.
</span><span class="cx">          *
</span><span class="cx">          * @since 3.4.0
</span></span></pre></div>
<a id="trunkwpincludesclasswpcustomizephp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/class-wp-customize.php (20294 => 20295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/class-wp-customize.php        2012-03-28 02:58:21 UTC (rev 20294)
+++ trunk/wp-includes/class-wp-customize.php        2012-03-28 04:14:09 UTC (rev 20295)
</span><span class="lines">@@ -14,6 +14,7 @@
</span><span class="cx">
</span><span class="cx">         protected $settings = array();
</span><span class="cx">         protected $sections = array();
</span><ins>+        protected $controls = array();
</ins><span class="cx">
</span><span class="cx">         /**
</span><span class="cx">          * Constructor.
</span><span class="lines">@@ -23,6 +24,7 @@
</span><span class="cx">         public function __construct() {
</span><span class="cx">                 require( ABSPATH . WPINC . '/class-wp-customize-setting.php' );
</span><span class="cx">                 require( ABSPATH . WPINC . '/class-wp-customize-section.php' );
</span><ins>+                require( ABSPATH . WPINC . '/class-wp-customize-control.php' );
</ins><span class="cx">
</span><span class="cx">                 add_action( 'setup_theme', array( $this, 'setup_theme' ) );
</span><span class="cx">                 add_action( 'admin_init', array( $this, 'admin_init' ) );
</span><span class="lines">@@ -357,12 +359,15 @@
</span><span class="cx">          *
</span><span class="cx">          * @since 3.4.0
</span><span class="cx">          *
</span><del>-         * @param string $id An specific ID of the setting. Can be a
</del><ins>+         * @param string $id A specific ID of the setting. Can be a
</ins><span class="cx">          * theme mod or option name.
</span><span class="cx">          * @param array $args Setting arguments.
</span><span class="cx">          */
</span><span class="cx">         public function add_setting( $id, $args = array() ) {
</span><del>-                $setting = new WP_Customize_Setting( $this, $id, $args );
</del><ins>+                if ( is_a( $id, 'WP_Customize_Setting' ) )
+                        $setting = $id;
+                else
+                        $setting = new WP_Customize_Setting( $this, $id, $args );
</ins><span class="cx">
</span><span class="cx">                 $this->settings[ $setting->id ] = $setting;
</span><span class="cx">         }
</span><span class="lines">@@ -372,7 +377,7 @@
</span><span class="cx">          *
</span><span class="cx">          * @since 3.4.0
</span><span class="cx">          *
</span><del>-         * @param string $id An specific ID of the setting.
</del><ins>+         * @param string $id A specific ID of the setting.
</ins><span class="cx">          * @return object The settings object.
</span><span class="cx">          */
</span><span class="cx">         public function get_setting( $id ) {
</span><span class="lines">@@ -385,7 +390,7 @@
</span><span class="cx">          *
</span><span class="cx">          * @since 3.4.0
</span><span class="cx">          *
</span><del>-         * @param string $id An specific ID of the setting.
</del><ins>+         * @param string $id A specific ID of the setting.
</ins><span class="cx">          */
</span><span class="cx">         public function remove_setting( $id ) {
</span><span class="cx">                 unset( $this->settings[ $id ] );
</span><span class="lines">@@ -396,11 +401,14 @@
</span><span class="cx">          *
</span><span class="cx">          * @since 3.4.0
</span><span class="cx">          *
</span><del>-         * @param string $id An specific ID of the section.
</del><ins>+         * @param string $id A specific ID of the section.
</ins><span class="cx">          * @param array $args Section arguments.
</span><span class="cx">          */
</span><span class="cx">         public function add_section( $id, $args = array() ) {
</span><del>-                $section = new WP_Customize_Section( $this, $id, $args );
</del><ins>+                if ( is_a( $id, 'WP_Customize_Section' ) )
+                        $section = $id;
+                else
+                        $section = new WP_Customize_Section( $this, $id, $args );
</ins><span class="cx">
</span><span class="cx">                 $this->sections[ $section->id ] = $section;
</span><span class="cx">         }
</span><span class="lines">@@ -410,7 +418,7 @@
</span><span class="cx">          *
</span><span class="cx">          * @since 3.4.0
</span><span class="cx">          *
</span><del>-         * @param string $id An specific ID of the section.
</del><ins>+         * @param string $id A specific ID of the section.
</ins><span class="cx">          * @return object The section object.
</span><span class="cx">          */
</span><span class="cx">         public function get_section( $id ) {
</span><span class="lines">@@ -423,13 +431,54 @@
</span><span class="cx">          *
</span><span class="cx">          * @since 3.4.0
</span><span class="cx">          *
</span><del>-         * @param string $id An specific ID of the section.
</del><ins>+         * @param string $id A specific ID of the section.
</ins><span class="cx">          */
</span><span class="cx">         public function remove_section( $id ) {
</span><span class="cx">                 unset( $this->sections[ $id ] );
</span><span class="cx">         }
</span><span class="cx">
</span><span class="cx">         /**
</span><ins>+         * Add a customize control.
+         *
+         * @since 3.4.0
+         *
+         * @param string $id A specific ID of the control.
+         * @param array $args Setting arguments.
+         */
+        public function add_control( $id, $args = array() ) {
+                if ( is_a( $id, 'WP_Customize_Control' ) )
+                        $control = $id;
+                else
+                        $control = new WP_Customize_Control( $this, $id, $args );
+
+                $this->controls[ $control->id ] = $control;
+        }
+
+        /**
+         * Retrieve a customize control.
+         *
+         * @since 3.4.0
+         *
+         * @param string $id A specific ID of the control.
+         * @return object The settings object.
+         */
+        public function get_control( $id ) {
+                if ( isset( $this->controls[ $id ] ) )
+                        return $this->controls[ $id ];
+        }
+
+        /**
+         * Remove a customize setting.
+         *
+         * @since 3.4.0
+         *
+         * @param string $id A specific ID of the control.
+         */
+        public function remove_control( $id ) {
+                unset( $this->controls[ $id ] );
+        }
+
+        /**
</ins><span class="cx">          * Helper function to compare two objects by priority.
</span><span class="cx">          *
</span><span class="cx">          * @since 3.4.0
</span><span class="lines">@@ -452,20 +501,20 @@
</span><span class="cx">          * @since 3.4.0
</span><span class="cx">          */
</span><span class="cx">         public function prepare_controls() {
</span><del>-                // Prepare settings
</del><ins>+                // Prepare controls
</ins><span class="cx">                 // Reversing makes uasort sort by time added when conflicts occur.
</span><span class="cx">
</span><del>-                $this->settings = array_reverse( $this->settings );
-                $settings = array();
</del><ins>+                $this->controls = array_reverse( $this->controls );
+                $controls = array();
</ins><span class="cx">
</span><del>-                foreach ( $this->settings as $id => $setting ) {
-                        if ( ! isset( $this->sections[ $setting->section ] ) || ! $setting->check_capabilities() )
</del><ins>+                foreach ( $this->controls as $id => $control ) {
+                        if ( ! isset( $this->sections[ $control->section ] ) || ! $control->check_capabilities() )
</ins><span class="cx">                                 continue;
</span><span class="cx">
</span><del>-                        $this->sections[ $setting->section ]->settings[] = $setting;
-                        $settings[ $id ] = $setting;
</del><ins>+                        $this->sections[ $control->section ]->controls[] = $control;
+                        $controls[ $id ] = $control;
</ins><span class="cx">                 }
</span><del>-                $this->settings = $settings;
</del><ins>+                $this->controls = $controls;
</ins><span class="cx">
</span><span class="cx">                 // Prepare sections
</span><span class="cx">                 $this->sections = array_reverse( $this->sections );
</span><span class="lines">@@ -473,10 +522,10 @@
</span><span class="cx">                 $sections = array();
</span><span class="cx">
</span><span class="cx">                 foreach ( $this->sections as $section ) {
</span><del>-                        if ( ! $section->check_capabilities() || ! $section->settings )
</del><ins>+                        if ( ! $section->check_capabilities() || ! $section->controls )
</ins><span class="cx">                                 continue;
</span><span class="cx">
</span><del>-                        usort( $section->settings, array( $this, '_cmp_priority' ) );
</del><ins>+                        usort( $section->controls, array( $this, '_cmp_priority' ) );
</ins><span class="cx">                         $sections[] = $section;
</span><span class="cx">                 }
</span><span class="cx">                 $this->sections = $sections;
</span><span class="lines">@@ -488,8 +537,8 @@
</span><span class="cx">          * @since 3.4.0
</span><span class="cx">          */
</span><span class="cx">         public function enqueue_control_scripts() {
</span><del>-                foreach ( $this->settings as $setting ) {
-                        $setting->enqueue();
</del><ins>+                foreach ( $this->controls as $control ) {
+                        $control->enqueue();
</ins><span class="cx">                 }
</span><span class="cx">         }
</span><span class="cx">
</span><span class="lines">@@ -508,36 +557,37 @@
</span><span class="cx">                 ) );
</span><span class="cx">
</span><span class="cx">                 $this->add_setting( 'header_textcolor', array(
</span><del>-                        'label' => 'Text Color',
-                        'section' => 'header',
-                        'sanitize_callback' => 'sanitize_hexcolor',
-                        'control' => 'color',
-                        'theme_supports' => array( 'custom-header', 'header-text' ),
-                        'default' => get_theme_support( 'custom-header', 'default-text-color' ),
</del><ins>+                        // @todo: replace with a new accept() setting method
+                        // 'sanitize_callback' => 'sanitize_hexcolor',
+                        'control' => 'color',
+                        'theme_supports' => array( 'custom-header', 'header-text' ),
+                        'default' => get_theme_support( 'custom-header', 'default-text-color' ),
</ins><span class="cx">                 ) );
</span><span class="cx">
</span><del>-                /*
-                $this->add_setting( 'display_header', array(
-                        'label' => 'Display Text',
</del><ins>+                $this->add_control( 'display_header_text', array(
+                        'settings' => 'header_textcolor',
+                        'label' => __( 'Display Header Text' ),
+                        'section' => 'header',
+                        'type' => 'checkbox',
+                ) );
+
+                $this->add_control( 'header_textcolor', array(
+                        'label' => __( 'Text Color' ),
</ins><span class="cx">                         'section' => 'header',
</span><del>-                        'type' => 'radio',
-                        'choices' => array(
-                                'show' => 'Yes',
-                                'hide' => 'No'
-                        ),
-                        // Showing header text is actually done by setting header_textcolor to 'blank'.
-                        // @todo: Do some JS magic to make this work (since we'll be hiding the textcolor input).
-                        'theme_mod' => false,
</del><ins>+                        'type' => 'color',
</ins><span class="cx">                 ) );
</span><del>-                */
</del><span class="cx">
</span><span class="cx">                 // Input type: checkbox
</span><span class="cx">                 // With custom value
</span><span class="cx">                 $this->add_setting( 'header_image', array(
</span><ins>+                        'default' => get_theme_support( 'custom-header', 'default-image' ),
+                        'theme_supports' => 'custom-header',
+                ) );
+
+                $this->add_control( 'header_image', array(
</ins><span class="cx">                         'label' => 'Header Image',
</span><span class="cx">                         'section' => 'header',
</span><del>-                        'control' => 'image',
-                        'default' => get_theme_support( 'custom-header', 'default-image' ),
</del><ins>+                        'type' => 'image',
</ins><span class="cx">                         'control_params' => array(
</span><span class="cx">                                 'context' => 'custom-header',
</span><span class="cx">                                 'removed' => 'remove-header',
</span><span class="lines">@@ -559,60 +609,80 @@
</span><span class="cx">                 // Input type: Color
</span><span class="cx">                 // With sanitize_callback
</span><span class="cx">                 $this->add_setting( 'background_color', array(
</span><del>-                        'label' => 'Background Color',
-                        'section' => 'background',
-                        'control' => 'color',
</del><span class="cx">                         'default' => get_theme_support( 'custom-background', 'default-color' ),
</span><span class="cx">                         'sanitize_callback' => 'sanitize_hexcolor',
</span><ins>+                        'theme_supports' => 'custom-background',
</ins><span class="cx">                 ) );
</span><span class="cx">
</span><ins>+                $this->add_control( 'background_color', array(
+                        'label' => __( 'Background Color' ),
+                        'section' => 'background',
+                        'type' => 'color',
+                ) );
+
</ins><span class="cx">                 $this->add_setting( 'background_image', array(
</span><del>-                        'label' => 'Background Image',
</del><ins>+                        'default' => get_theme_support( 'custom-background', 'default-image' ),
+                        'theme_supports' => 'custom-background',
+                ) );
+
+                $this->add_control( 'background_image', array(
+                        'label' => __( 'Background Image' ),
</ins><span class="cx">                         'section' => 'background',
</span><del>-                        'control' => 'upload',
-                        'default' => get_theme_support( 'custom-background', 'default-image' ),
</del><ins>+                        'type' => 'upload',
</ins><span class="cx">                         'control_params' => array(
</span><span class="cx">                                 'context' => 'custom-background',
</span><span class="cx">                         ),
</span><span class="cx">                 ) );
</span><span class="cx">
</span><span class="cx">                 $this->add_setting( 'background_repeat', array(
</span><del>-                        'label' => 'Background Repeat',
</del><ins>+                        'default' => 'repeat',
+                        'theme_supports' => 'custom-background',
+                ) );
+
+                $this->add_control( 'background_repeat', array(
+                        'label' => __( 'Background Repeat' ),
</ins><span class="cx">                         'section' => 'background',
</span><span class="cx">                         'visibility' => 'background_image',
</span><del>-                        'control' => 'radio',
</del><ins>+                        'type' => 'radio',
</ins><span class="cx">                         'choices' => array(
</span><span class="cx">                                 'no-repeat' => __('No Repeat'),
</span><span class="cx">                                 'repeat' => __('Tile'),
</span><span class="cx">                                 'repeat-x' => __('Tile Horizontally'),
</span><span class="cx">                                 'repeat-y' => __('Tile Vertically'),
</span><span class="cx">                         ),
</span><del>-                        'default' => 'repeat',
</del><span class="cx">                 ) );
</span><span class="cx">
</span><span class="cx">                 $this->add_setting( 'background_position_x', array(
</span><del>-                        'label' => 'Background Position',
</del><ins>+                        'default' => 'left',
+                        'theme_supports' => 'custom-background',
+                ) );
+
+                $this->add_control( 'background_position_x', array(
+                        'label' => __( 'Background Position' ),
</ins><span class="cx">                         'section' => 'background',
</span><span class="cx">                         'visibility' => 'background_image',
</span><del>-                        'control' => 'radio',
</del><ins>+                        'type' => 'radio',
</ins><span class="cx">                         'choices' => array(
</span><span class="cx">                                 'left' => __('Left'),
</span><span class="cx">                                 'center' => __('Center'),
</span><span class="cx">                                 'right' => __('Right'),
</span><span class="cx">                         ),
</span><del>-                        'default' => 'left',
</del><span class="cx">                 ) );
</span><span class="cx">
</span><span class="cx">                 $this->add_setting( 'background_attachment', array(
</span><del>-                        'label' => 'Background Attachment',
</del><ins>+                        'default' => 'fixed',
+                        'theme_supports' => 'custom-background',
+                ) );
+
+                $this->add_control( 'background_attachment', array(
+                        'label' => __( 'Background Attachment' ),
</ins><span class="cx">                         'section' => 'background',
</span><span class="cx">                         'visibility' => 'background_image',
</span><del>-                        'control' => 'radio',
</del><ins>+                        'type' => 'radio',
</ins><span class="cx">                         'choices' => array(
</span><span class="cx">                                 'fixed' => __('Fixed'),
</span><span class="cx">                                 'scroll' => __('Scroll'),
</span><span class="cx">                         ),
</span><del>-                        'default' => 'fixed',
</del><span class="cx">                 ) );
</span><span class="cx">
</span><span class="cx">                 /* Nav Menus */
</span><span class="lines">@@ -636,14 +706,19 @@
</span><span class="cx">                                 $choices[ $menu->term_id ] = $truncated_name;
</span><span class="cx">                         }
</span><span class="cx">
</span><del>-                        $this->add_setting( "nav_menu_locations[{$location}]", array(
-                                'label' => $description,
-                                'theme_supports' => 'menus', // Todo: Needs also widgets -- array( 'menus', 'widgets' )
-                                'section' => 'nav',
-                                'control' => 'select',
-                                'choices' => $choices,
</del><ins>+                        $menu_setting_id = "nav_menu_locations[{$location}]";
+
+                        $this->add_setting( $menu_setting_id, array(
</ins><span class="cx">                                 'sanitize_callback' => 'absint',
</span><ins>+                                'theme_supports' => 'menus',
</ins><span class="cx">                         ) );
</span><ins>+
+                        $this->add_control( $menu_setting_id, array(
+                                'label' => $description,
+                                'section' => 'nav',
+                                'type' => 'select',
+                                'choices' => $choices,
+                        ) );
</ins><span class="cx">                 }
</span><span class="cx">
</span><span class="cx">                 /* Static Front Page */
</span><span class="lines">@@ -660,36 +735,45 @@
</span><span class="cx">                 $choices['page'] = __( 'A static page (select below)' );
</span><span class="cx">
</span><span class="cx">                 $this->add_setting( 'show_on_front', array(
</span><del>-                        'label' => __( 'Front page displays' ),
-                //        'theme_supports' => 'static-front-page',
-                        'section' => 'static_front_page',
-                        'control' => 'radio',
-                        'choices' => $choices,
</del><span class="cx">                         'default' => get_option( 'show_on_front' ),
</span><ins>+                        'capability' => 'manage_options',
</ins><span class="cx">                         'type' => 'option',
</span><del>-                        'capability' => 'manage_options',
</del><ins>+                //        'theme_supports' => 'static-front-page',
</ins><span class="cx">                 ) );
</span><span class="cx">
</span><ins>+                $this->add_control( 'show_on_front', array(
+                        'label' => __( 'Front page displays' ),
+                        'section' => 'static_front_page',
+                        'type' => 'radio',
+                        'choices' => $choices,
+                ) );
+
</ins><span class="cx">                 $this->add_setting( 'page_on_front', array(
</span><del>-                        'label' => __( 'Front page' ),
</del><ins>+                        'type' => 'option',
+                        'capability' => 'manage_options',
</ins><span class="cx">                 //        'theme_supports' => 'static-front-page',
</span><del>-                        'section' => 'static_front_page',
-                        'control' => 'dropdown-pages',
-                        'type' => 'option',
-                        'capability' => 'manage_options',
-                        'visibility' => array( 'show_on_front', 'page' ),
</del><span class="cx">                 ) );
</span><span class="cx">
</span><ins>+                $this->add_control( 'page_on_front', array(
+                        'label' => __( 'Front page' ),
+                        'section' => 'static_front_page',
+                        'type' => 'dropdown-pages',
+                        'visibility' => array( 'show_on_front', 'page' ),
+                ) );
+
</ins><span class="cx">                 $this->add_setting( 'page_for_posts', array(
</span><del>-                        'label' => __( 'Posts page' ),
-                //        'theme_supports' => 'static-front-page',
-                        'section' => 'static_front_page',
-                        'control' => 'dropdown-pages',
</del><span class="cx">                         'type' => 'option',
</span><span class="cx">                         'capability' => 'manage_options',
</span><del>-                        'visibility' => array( 'show_on_front', 'page' ),
</del><ins>+                //        'theme_supports' => 'static-front-page',
</ins><span class="cx">                 ) );
</span><span class="cx">
</span><ins>+                $this->add_control( 'page_for_posts', array(
+                        'label' => __( 'Posts page' ),
+                        'section' => 'static_front_page',
+                        'type' => 'dropdown-pages',
+                        'visibility' => array( 'show_on_front', 'page' ),
+                ) );
+
</ins><span class="cx">                 /* Site Title & Tagline */
</span><span class="cx">
</span><span class="cx">                 $this->add_section( 'strings', array(
</span><span class="lines">@@ -697,20 +781,26 @@
</span><span class="cx">                 ) );
</span><span class="cx">
</span><span class="cx">                 $this->add_setting( 'blogname', array(
</span><del>-                        'label' => __( 'Site Title' ),
-                        'section' => 'strings',
-                        'default' => get_option( 'blogname' ),
-                        'type' => 'option',
-                        'capability' => 'manage_options',
</del><ins>+                        'default' => get_option( 'blogname' ),
+                        'type' => 'option',
+                        'capability' => 'manage_options',
</ins><span class="cx">                 ) );
</span><span class="cx">
</span><ins>+                $this->add_control( 'blogname', array(
+                        'label' => __( 'Site Title' ),
+                        'section' => 'strings',
+                ) );
+
</ins><span class="cx">                 $this->add_setting( 'blogdescription', array(
</span><del>-                        'label' => __( 'Tagline' ),
-                        'section' => 'strings',
-                        'default' => get_option( 'blogdescription' ),
-                        'type' => 'option',
-                        'capability' => 'manage_options',
</del><ins>+                        'default' => get_option( 'blogdescription' ),
+                        'type' => 'option',
+                        'capability' => 'manage_options',
</ins><span class="cx">                 ) );
</span><ins>+
+                $this->add_control( 'blogdescription', array(
+                        'label' => __( 'Tagline' ),
+                        'section' => 'strings',
+                ) );
</ins><span class="cx">         }
</span><span class="cx"> };
</span><span class="cx">
</span></span></pre></div>
<a id="trunkwpincludescustomizecontrolsphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/customize-controls.php (20294 => 20295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/customize-controls.php        2012-03-28 02:58:21 UTC (rev 20294)
+++ trunk/wp-includes/customize-controls.php        2012-03-28 04:14:09 UTC (rev 20295)
</span><span class="lines">@@ -95,27 +95,30 @@
</span><span class="cx">         $scheme = is_ssl() ? 'https' : 'http';
</span><span class="cx">         $settings = array(
</span><span class="cx">                 'preview' => esc_url( home_url( '/', $scheme ) ),
</span><ins>+                'settings' => array(),
</ins><span class="cx">                 'controls' => array(),
</span><span class="cx">                 'prefix' => WP_Customize_Setting::name_prefix,
</span><span class="cx">         );
</span><span class="cx">
</span><span class="cx">         foreach ( $this->settings as $id => $setting ) {
</span><del>-                $settings['controls'][ $id ] = array(
</del><ins>+                $settings['settings'][ $id ] = array(
</ins><span class="cx">                         'value' => $setting->value(),
</span><del>-                        'control' => $setting->control,
-                        'params' => $setting->control_params,
</del><span class="cx">                 );
</span><ins>+        }
</ins><span class="cx">
</span><del>-                if ( $setting->visibility ) {
-                        if ( is_string( $setting->visibility ) ) {
</del><ins>+        foreach ( $this->controls as $id => $control ) {
+                $settings['controls'][ $id ] = $control->json();
+
+                if ( $control->visibility ) {
+                        if ( is_string( $control->visibility ) ) {
</ins><span class="cx">                                 $settings['controls'][ $id ]['visibility'] = array(
</span><del>-                                        'id' => $setting->visibility,
</del><ins>+                                        'id' => $control->visibility,
</ins><span class="cx">                                         'value' => true,
</span><span class="cx">                                 );
</span><span class="cx">                         } else {
</span><span class="cx">                                 $settings['controls'][ $id ]['visibility'] = array(
</span><del>-                                        'id' => $setting->visibility[0],
-                                        'value' => $setting->visibility[1],
</del><ins>+                                        'id' => $control->visibility[0],
+                                        'value' => $control->visibility[1],
</ins><span class="cx">                                 );
</span><span class="cx">                         }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkwpincludesjscustomizebasedevjs"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/js/customize-base.dev.js (20294 => 20295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/js/customize-base.dev.js        2012-03-28 02:58:21 UTC (rev 20294)
+++ trunk/wp-includes/js/customize-base.dev.js        2012-03-28 04:14:09 UTC (rev 20295)
</span><span class="lines">@@ -397,7 +397,7 @@
</span><span class="cx">
</span><span class="cx">                 add: function( id, value ) {
</span><span class="cx">                         if ( this.has( id ) )
</span><del>-                                return;
</del><ins>+                                return this.value( id );
</ins><span class="cx">
</span><span class="cx">                         this._value[ id ] = value;
</span><span class="cx">                         this._value[ id ]._parent = this._value;
</span></span></pre></div>
<a id="trunkwpincludesjscustomizecontrolsdevjs"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/js/customize-controls.dev.js (20294 => 20295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/js/customize-controls.dev.js        2012-03-28 02:58:21 UTC (rev 20294)
+++ trunk/wp-includes/js/customize-controls.dev.js        2012-03-28 04:14:09 UTC (rev 20295)
</span><span class="lines">@@ -6,19 +6,24 @@
</span><span class="cx">          * - previewer - The Previewer instance to sync with.
</span><span class="cx">          * - method - The method to use for syncing. Supports 'refresh' and 'postMessage'.
</span><span class="cx">          */
</span><del>-        api.Control = api.Value.extend({
</del><ins>+        api.Setting = api.Value.extend({
</ins><span class="cx">                 initialize: function( id, value, options ) {
</span><del>-                        var name = '[name="' + api.settings.prefix + id + '"]';
</del><ins>+                        var element;
</ins><span class="cx">
</span><del>-                        this.params = {};
</del><span class="cx">                         api.Value.prototype.initialize.call( this, value, options );
</span><span class="cx">
</span><span class="cx">                         this.id = id;
</span><del>-                        this.container = $( '#customize-control-' + id );
-                        this.element = this.element || new api.Element( this.container.find( name ) );
-
</del><span class="cx">                         this.method = this.method || 'refresh';
</span><span class="cx">
</span><ins>+                        element = $( '<input />', {
+                                type: 'hidden',
+                                value: this.get(),
+                                name: api.settings.prefix + id
+                        });
+
+                        element.appendTo( this.previewer.form );
+                        this.element = new api.Element( element );
+
</ins><span class="cx">                         this.element.link( this );
</span><span class="cx">                         this.link( this.element );
</span><span class="cx">
</span><span class="lines">@@ -34,65 +39,116 @@
</span><span class="cx">                 }
</span><span class="cx">         });
</span><span class="cx">
</span><ins>+        api.Control = api.Class.extend({
+                initialize: function( id, options ) {
+                        var control = this,
+                                nodes, radios, settings;
+
+                        this.params = {};
+                        $.extend( this, options || {} );
+
+                        this.id = id;
+                        this.container = $( '#customize-control-' + id );
+
+                        settings = $.map( this.params.settings, function( value ) {
+                                return value;
+                        });
+
+                        api.apply( api, settings.concat( function() {
+                                var key;
+
+                                control.settings = {};
+                                for ( key in control.params.settings ) {
+                                        control.settings[ key ] = api( control.params.settings[ key ] );
+                                }
+
+                                control.setting = control.settings['default'] || null;
+                                control.ready();
+                        }) );
+
+                        control.elements = [];
+
+                        nodes = this.container.find('[data-customize-setting-link]');
+                        radios = {};
+
+                        nodes.each( function() {
+                                var node = $(this),
+                                        name;
+
+                                if ( node.is(':radio') ) {
+                                        name = node.prop('name');
+                                        if ( radios[ name ] )
+                                                return;
+
+                                        radios[ name ] = true;
+                                        node = nodes.filter( '[name="' + name + '"]' );
+                                }
+
+                                api( node.data('customizeSettingLink'), function( setting ) {
+                                        var element = new api.Element( node );
+                                        control.elements.push( element );
+                                        element.link( setting ).bind( function( to ) {
+                                                setting( to );
+                                        });
+                                });
+                        });
+                },
+                ready: function() {}
+        });
+
</ins><span class="cx">         api.ColorControl = api.Control.extend({
</span><del>-                initialize: function( id, value, options ) {
-                        var self = this,
</del><ins>+                ready: function() {
+                        var control = this,
</ins><span class="cx">                                 picker, ui, text, toggle, update;
</span><span class="cx">
</span><del>-                        api.Control.prototype.initialize.call( this, id, value, options );
-
</del><span class="cx">                         picker = this.container.find( '.color-picker' );
</span><span class="cx">                         ui = picker.find( '.color-picker-controls' );
</span><span class="cx">                         toggle = picker.find( 'a' );
</span><span class="cx">                         update = function( color ) {
</span><span class="cx">                                 color = '#' + color;
</span><span class="cx">                                 toggle.css( 'background', color );
</span><del>-                                self.farbtastic.setColor( color );
</del><ins>+                                control.farbtastic.setColor( color );
</ins><span class="cx">                         };
</span><span class="cx">
</span><del>-                        this.input = new api.Element( ui.find( 'input' ) ); // Find text input.
-
-                        this.link( this.input );
-                        this.input.link( this );
-
</del><span class="cx">                         picker.on( 'click', 'a', function() {
</span><span class="cx">                                 ui.toggle();
</span><span class="cx">                         });
</span><span class="cx">
</span><span class="cx">                         this.farbtastic = $.farbtastic( picker.find('.farbtastic-placeholder'), function( color ) {
</span><del>-                                self.set( color.replace( '#', '' ) );
</del><ins>+                                control.setting.set( color.replace( '#', '' ) );
</ins><span class="cx">                         });
</span><span class="cx">
</span><del>-                        this.bind( update );
-                        update( this() );
-                },
-                validate: function( to ) {
-                        return /^[a-fA-F0-9]{3}([a-fA-F0-9]{3})?$/.test( to ) ? to : null;
</del><ins>+                        this.setting.bind( update );
+                        update( this.setting() );
</ins><span class="cx">                 }
</span><ins>+                // ,
+                //                 validate: function( to ) {
+                //                         return /^[a-fA-F0-9]{3}([a-fA-F0-9]{3})?$/.test( to ) ? to : null;
+                //                 }
</ins><span class="cx">         });
</span><span class="cx">
</span><span class="cx">         api.UploadControl = api.Control.extend({
</span><del>-                initialize: function( id, value, options ) {
</del><ins>+                ready: function() {
</ins><span class="cx">                         var control = this;
</span><span class="cx">
</span><del>-                        api.Control.prototype.initialize.call( this, id, value, options );
</del><span class="cx">                         this.params.removed = this.params.removed || '';
</span><span class="cx">
</span><span class="cx">                         this.uploader = new wp.Uploader({
</span><span class="cx">                                 browser: this.container.find('.upload'),
</span><span class="cx">                                 success: function( attachment ) {
</span><del>-                                        control.set( attachment.url );
</del><ins>+                                        control.setting.set( attachment.url );
</ins><span class="cx">                                 }
</span><span class="cx">                         });
</span><span class="cx">
</span><span class="cx">                         this.remover = this.container.find('.remove');
</span><span class="cx">                         this.remover.click( function( event ) {
</span><del>-                                control.set( control.params.removed );
</del><ins>+                                control.setting.set( control.params.removed );
</ins><span class="cx">                                 event.preventDefault();
</span><span class="cx">                         });
</span><span class="cx">
</span><del>-                        this.bind( this.removerVisibility );
-                        this.removerVisibility( this.get() );
</del><ins>+                        this.removerVisibility = $.proxy( this.removerVisibility, this );
+                        this.setting.bind( this.removerVisibility );
+                        this.removerVisibility( this.setting.get() );
</ins><span class="cx">
</span><span class="cx">                         if ( this.params.context )
</span><span class="cx">                                 control.uploader.param( 'post_data[context]', this.params.context );
</span><span class="lines">@@ -103,14 +159,13 @@
</span><span class="cx">         });
</span><span class="cx">
</span><span class="cx">         api.ImageControl = api.UploadControl.extend({
</span><del>-                initialize: function( id, value, options ) {
</del><ins>+                ready: function( id, value, options ) {
</ins><span class="cx">                         var control = this;
</span><span class="cx">
</span><del>-                        api.UploadControl.prototype.initialize.call( this, id, value, options );
</del><ins>+                        this.thumbnail = this.container.find('.thumbnail img');
+                        this.thumbnailSrc = $.proxy( this.thumbnailSrc, this );
+                        this.setting.bind( this.thumbnailSrc );
</ins><span class="cx">
</span><del>-                        this.thumbnail = this.container.find('.thumbnail img');
-                        this.bind( this.thumbnailSrc );
-
</del><span class="cx">                         this.library = this.container.find('.library');
</span><span class="cx">                         this.changer = this.container.find('.change');
</span><span class="cx">
</span><span class="lines">@@ -137,7 +192,7 @@
</span><span class="cx">                         });
</span><span class="cx">
</span><span class="cx">                         this.library.on( 'click', 'a', function( event ) {
</span><del>-                                control.set( $(this).attr('href') );
</del><ins>+                                control.setting.set( $(this).attr('href') );
</ins><span class="cx">                                 event.preventDefault();
</span><span class="cx">                         });
</span><span class="cx">                 },
</span><span class="lines">@@ -152,6 +207,9 @@
</span><span class="cx">         // Change objects contained within the main customize object to Settings.
</span><span class="cx">         api.defaultConstructor = api.Setting;
</span><span class="cx">
</span><ins>+        // Create the collection of Control objects.
+        api.control = new api.Values({ defaultConstructor: api.Control });
+
</ins><span class="cx">         api.Previewer = api.Messenger.extend({
</span><span class="cx">                 refreshBuffer: 250,
</span><span class="cx">
</span><span class="lines">@@ -272,7 +330,7 @@
</span><span class="cx">          * Ready.
</span><span class="cx">          * ===================================================================== */
</span><span class="cx">
</span><del>-        api.controls = {
</del><ins>+        api.controlConstructor = {
</ins><span class="cx">                 color: api.ColorControl,
</span><span class="cx">                 upload: api.UploadControl,
</span><span class="cx">                 image: api.ImageControl
</span><span class="lines">@@ -289,11 +347,17 @@
</span><span class="cx">                         url: api.settings.preview
</span><span class="cx">                 });
</span><span class="cx">
</span><ins>+                $.each( api.settings.settings, function( id, data ) {
+                        api.set( id, id, data.value, {
+                                previewer: previewer
+                        } );
+                });
+
</ins><span class="cx">                 $.each( api.settings.controls, function( id, data ) {
</span><del>-                        var constructor = api.controls[ data.control ] || api.Control,
</del><ins>+                        var constructor = api.controlConstructor[ data.type ] || api.Control,
</ins><span class="cx">                                 control;
</span><span class="cx">
</span><del>-                        control = api.add( id, new constructor( id, data.value, {
</del><ins>+                        control = api.control.add( id, new constructor( id, {
</ins><span class="cx">                                 params: data.params,
</span><span class="cx">                                 previewer: previewer
</span><span class="cx">                         } ) );
</span><span class="lines">@@ -326,9 +390,29 @@
</span><span class="cx">                 });
</span><span class="cx">
</span><span class="cx">                 // Background color uses postMessage by default
</span><del>-                api( 'background_color', function( control ) {
</del><ins>+                api.control( 'background_color', function( control ) {
</ins><span class="cx">                         control.method = 'postMessage';
</span><span class="cx">                 });
</span><ins>+
+                api.control( 'display_header_text', function( control ) {
+                        var last = '';
+
+                        control.elements[0].unlink();
+
+                        control.element = new api.Element( control.container.find('input') );
+                        control.element.set( 'blank' !== control.setting() );
+
+                        control.element.bind( function( to ) {
+                                if ( ! to )
+                                        last = api.get( 'header_textcolor' );
+
+                                control.setting.set( to ? last : 'blank' );
+                        });
+
+                        control.setting.bind( function( to ) {
+                                control.element.set( 'blank' !== to );
+                        });
+                });
</ins><span class="cx">         });
</span><span class="cx">
</span><span class="cx"> })( wp, jQuery );
</span><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkwpincludesjspluploadwppluploaddevjs"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/js/plupload/wp-plupload.dev.js (20294 => 20295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/js/plupload/wp-plupload.dev.js        2012-03-28 02:58:21 UTC (rev 20294)
+++ trunk/wp-includes/js/plupload/wp-plupload.dev.js        2012-03-28 04:14:09 UTC (rev 20295)
</span><span class="lines">@@ -66,7 +66,11 @@
</span><span class="cx">                 this.uploader.bind( 'UploadProgress', this.progress );
</span><span class="cx">
</span><span class="cx">                 this.uploader.bind( 'FileUploaded', function( up, file, response ) {
</span><del>-                        response = JSON.parse( response.response );
</del><ins>+                        try {
+                                response = JSON.parse( response.response );
+                        } catch ( e ) {
+                                return self.error( pluploadL10n.default_error, e );
+                        }
</ins><span class="cx">
</span><span class="cx">                         if ( ! response || ! response.type || ! response.data )
</span><span class="cx">                                 return self.error( pluploadL10n.default_error );
</span></span></pre>
</div>
</div>
</body>
</html>