diff --git a/wp-includes/class-wp-customize-control.php b/wp-includes/class-wp-customize-control.php
new file mode 100644
index 0000000000..10ce6ce3dd
--- /dev/null
+++ b/wp-includes/class-wp-customize-control.php
@@ -0,0 +1,329 @@
+$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;"';
+ }
+
+ ?>
>
+ render_content(); ?>
+ 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':
+ ?>
+
+
+
+
+
+ choices ) )
+ return;
+
+ $name = '_customize-radio-' . $this->id;
+
+ ?>
+ label ); ?>
+ choices as $value => $label ) :
+ ?>
+
+ choices ) )
+ return;
+
+ ?>
+
+
+
+ value();
+
+ $image = $value;
+ if ( isset( $this->control_params['get_url'] ) )
+ $image = call_user_func( $this->control_params['get_url'], $image );
+
+ ?>
+
+ %s %s',
+ $this->label,
+ wp_dropdown_pages(
+ array(
+ // @todo: this is going to need fixing.
+ // 'name' => $this->get_name(),
+ 'echo' => 0,
+ 'show_option_none' => __( '— Select —' ),
+ 'option_none_value' => '0',
+ 'selected' => $this->value(),
+ )
+ )
+ );
+ break;
+ }
+ }
+}
\ No newline at end of file
diff --git a/wp-includes/class-wp-customize-section.php b/wp-includes/class-wp-customize-section.php
index 21f751a49f..4c9f9ad7de 100644
--- a/wp-includes/class-wp-customize-section.php
+++ b/wp-includes/class-wp-customize-section.php
@@ -15,7 +15,7 @@ class WP_Customize_Section {
public $theme_supports = '';
public $title = '';
public $description = '';
- public $settings;
+ public $controls;
/**
* Constructor.
@@ -35,7 +35,7 @@ class WP_Customize_Section {
$this->manager = $manager;
$this->id = $id;
- $this->settings = array(); // Users cannot customize the $settings array.
+ $this->controls = array(); // Users cannot customize the $controls array.
return $this;
}
@@ -84,8 +84,8 @@ class WP_Customize_Section {
title ); ?>
settings as $setting )
- $setting->maybe_render();
+ foreach ( $this->controls as $control )
+ $control->maybe_render();
?>
diff --git a/wp-includes/class-wp-customize-setting.php b/wp-includes/class-wp-customize-setting.php
index e38d7fc6db..5a4ed19d56 100644
--- a/wp-includes/class-wp-customize-setting.php
+++ b/wp-includes/class-wp-customize-setting.php
@@ -10,18 +10,12 @@
class WP_Customize_Setting {
public $manager;
public $id;
- public $priority = 10;
- public $section = '';
- public $label = '';
- public $control = 'text';
- public $control_params = array();
+
public $type = 'theme_mod';
- public $choices = array();
public $capability = 'edit_theme_options';
public $theme_supports = '';
public $default = '';
public $sanitize_callback = '';
- public $visibility;
protected $id_data = array();
private $_post_value; // Cached, sanitized $_POST value.
@@ -63,23 +57,6 @@ class WP_Customize_Setting {
return $this;
}
- /**
- * 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;
- }
- }
-
/**
* Handle previewing the setting.
*
@@ -275,229 +252,9 @@ class WP_Customize_Setting {
if ( $this->theme_supports && ! call_user_func_array( 'current_theme_supports', (array) $this->theme_supports ) )
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_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;"';
- }
-
- ?>>
- render_content(); ?>
- control ) {
- case 'text':
- ?>
-
-
-
-
-
- choices ) )
- return;
-
- ?>
- label ); ?>
- choices as $value => $label ) :
- ?>
-
- choices ) )
- return;
-
- ?>
-
-
-
- value();
-
- $image = $value;
- if ( isset( $this->control_params['get_url'] ) )
- $image = call_user_func( $this->control_params['get_url'], $image );
-
- ?>
-
- %s %s',
- $this->label,
- wp_dropdown_pages(
- array(
- 'name' => $this->get_name(),
- 'echo' => 0,
- 'show_option_none' => __( '— Select —' ),
- '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() . '"';
- }
-
/**
* Multidimensional helper function.
*
diff --git a/wp-includes/class-wp-customize.php b/wp-includes/class-wp-customize.php
index 30a6294a8c..d7803fae04 100644
--- a/wp-includes/class-wp-customize.php
+++ b/wp-includes/class-wp-customize.php
@@ -14,6 +14,7 @@ final class WP_Customize {
protected $settings = array();
protected $sections = array();
+ protected $controls = array();
/**
* Constructor.
@@ -23,6 +24,7 @@ final class WP_Customize {
public function __construct() {
require( ABSPATH . WPINC . '/class-wp-customize-setting.php' );
require( ABSPATH . WPINC . '/class-wp-customize-section.php' );
+ require( ABSPATH . WPINC . '/class-wp-customize-control.php' );
add_action( 'setup_theme', array( $this, 'setup_theme' ) );
add_action( 'admin_init', array( $this, 'admin_init' ) );
@@ -357,12 +359,15 @@ final class WP_Customize {
*
* @since 3.4.0
*
- * @param string $id An specific ID of the setting. Can be a
+ * @param string $id A specific ID of the setting. Can be a
* theme mod or option name.
* @param array $args Setting arguments.
*/
public function add_setting( $id, $args = array() ) {
- $setting = new WP_Customize_Setting( $this, $id, $args );
+ if ( is_a( $id, 'WP_Customize_Setting' ) )
+ $setting = $id;
+ else
+ $setting = new WP_Customize_Setting( $this, $id, $args );
$this->settings[ $setting->id ] = $setting;
}
@@ -372,7 +377,7 @@ final class WP_Customize {
*
* @since 3.4.0
*
- * @param string $id An specific ID of the setting.
+ * @param string $id A specific ID of the setting.
* @return object The settings object.
*/
public function get_setting( $id ) {
@@ -385,7 +390,7 @@ final class WP_Customize {
*
* @since 3.4.0
*
- * @param string $id An specific ID of the setting.
+ * @param string $id A specific ID of the setting.
*/
public function remove_setting( $id ) {
unset( $this->settings[ $id ] );
@@ -396,11 +401,14 @@ final class WP_Customize {
*
* @since 3.4.0
*
- * @param string $id An specific ID of the section.
+ * @param string $id A specific ID of the section.
* @param array $args Section arguments.
*/
public function add_section( $id, $args = array() ) {
- $section = new WP_Customize_Section( $this, $id, $args );
+ if ( is_a( $id, 'WP_Customize_Section' ) )
+ $section = $id;
+ else
+ $section = new WP_Customize_Section( $this, $id, $args );
$this->sections[ $section->id ] = $section;
}
@@ -410,7 +418,7 @@ final class WP_Customize {
*
* @since 3.4.0
*
- * @param string $id An specific ID of the section.
+ * @param string $id A specific ID of the section.
* @return object The section object.
*/
public function get_section( $id ) {
@@ -423,12 +431,53 @@ final class WP_Customize {
*
* @since 3.4.0
*
- * @param string $id An specific ID of the section.
+ * @param string $id A specific ID of the section.
*/
public function remove_section( $id ) {
unset( $this->sections[ $id ] );
}
+ /**
+ * 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 ] );
+ }
+
/**
* Helper function to compare two objects by priority.
*
@@ -452,20 +501,20 @@ final class WP_Customize {
* @since 3.4.0
*/
public function prepare_controls() {
- // Prepare settings
+ // Prepare controls
// Reversing makes uasort sort by time added when conflicts occur.
- $this->settings = array_reverse( $this->settings );
- $settings = array();
+ $this->controls = array_reverse( $this->controls );
+ $controls = array();
- foreach ( $this->settings as $id => $setting ) {
- if ( ! isset( $this->sections[ $setting->section ] ) || ! $setting->check_capabilities() )
+ foreach ( $this->controls as $id => $control ) {
+ if ( ! isset( $this->sections[ $control->section ] ) || ! $control->check_capabilities() )
continue;
- $this->sections[ $setting->section ]->settings[] = $setting;
- $settings[ $id ] = $setting;
+ $this->sections[ $control->section ]->controls[] = $control;
+ $controls[ $id ] = $control;
}
- $this->settings = $settings;
+ $this->controls = $controls;
// Prepare sections
$this->sections = array_reverse( $this->sections );
@@ -473,10 +522,10 @@ final class WP_Customize {
$sections = array();
foreach ( $this->sections as $section ) {
- if ( ! $section->check_capabilities() || ! $section->settings )
+ if ( ! $section->check_capabilities() || ! $section->controls )
continue;
- usort( $section->settings, array( $this, '_cmp_priority' ) );
+ usort( $section->controls, array( $this, '_cmp_priority' ) );
$sections[] = $section;
}
$this->sections = $sections;
@@ -488,8 +537,8 @@ final class WP_Customize {
* @since 3.4.0
*/
public function enqueue_control_scripts() {
- foreach ( $this->settings as $setting ) {
- $setting->enqueue();
+ foreach ( $this->controls as $control ) {
+ $control->enqueue();
}
}
@@ -508,36 +557,37 @@ final class WP_Customize {
) );
$this->add_setting( 'header_textcolor', array(
- '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' ),
+ // @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' ),
) );
- /*
- $this->add_setting( 'display_header', array(
- 'label' => 'Display Text',
- 'section' => 'header',
- '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,
+ $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' ),
+ 'section' => 'header',
+ 'type' => 'color',
) );
- */
// Input type: checkbox
// With custom value
$this->add_setting( 'header_image', array(
+ 'default' => get_theme_support( 'custom-header', 'default-image' ),
+ 'theme_supports' => 'custom-header',
+ ) );
+
+ $this->add_control( 'header_image', array(
'label' => 'Header Image',
'section' => 'header',
- 'control' => 'image',
- 'default' => get_theme_support( 'custom-header', 'default-image' ),
+ 'type' => 'image',
'control_params' => array(
'context' => 'custom-header',
'removed' => 'remove-header',
@@ -559,60 +609,80 @@ final class WP_Customize {
// Input type: Color
// With sanitize_callback
$this->add_setting( 'background_color', array(
- 'label' => 'Background Color',
- 'section' => 'background',
- 'control' => 'color',
'default' => get_theme_support( 'custom-background', 'default-color' ),
'sanitize_callback' => 'sanitize_hexcolor',
+ 'theme_supports' => 'custom-background',
+ ) );
+
+ $this->add_control( 'background_color', array(
+ 'label' => __( 'Background Color' ),
+ 'section' => 'background',
+ 'type' => 'color',
) );
$this->add_setting( 'background_image', array(
- 'label' => 'Background Image',
- 'section' => 'background',
- 'control' => 'upload',
'default' => get_theme_support( 'custom-background', 'default-image' ),
+ 'theme_supports' => 'custom-background',
+ ) );
+
+ $this->add_control( 'background_image', array(
+ 'label' => __( 'Background Image' ),
+ 'section' => 'background',
+ 'type' => 'upload',
'control_params' => array(
'context' => 'custom-background',
),
) );
$this->add_setting( 'background_repeat', array(
- 'label' => 'Background Repeat',
+ 'default' => 'repeat',
+ 'theme_supports' => 'custom-background',
+ ) );
+
+ $this->add_control( 'background_repeat', array(
+ 'label' => __( 'Background Repeat' ),
'section' => 'background',
'visibility' => 'background_image',
- 'control' => 'radio',
+ 'type' => 'radio',
'choices' => array(
'no-repeat' => __('No Repeat'),
'repeat' => __('Tile'),
'repeat-x' => __('Tile Horizontally'),
'repeat-y' => __('Tile Vertically'),
),
- 'default' => 'repeat',
) );
$this->add_setting( 'background_position_x', array(
- 'label' => 'Background Position',
+ 'default' => 'left',
+ 'theme_supports' => 'custom-background',
+ ) );
+
+ $this->add_control( 'background_position_x', array(
+ 'label' => __( 'Background Position' ),
'section' => 'background',
'visibility' => 'background_image',
- 'control' => 'radio',
+ 'type' => 'radio',
'choices' => array(
'left' => __('Left'),
'center' => __('Center'),
'right' => __('Right'),
),
- 'default' => 'left',
) );
$this->add_setting( 'background_attachment', array(
- 'label' => 'Background Attachment',
+ 'default' => 'fixed',
+ 'theme_supports' => 'custom-background',
+ ) );
+
+ $this->add_control( 'background_attachment', array(
+ 'label' => __( 'Background Attachment' ),
'section' => 'background',
'visibility' => 'background_image',
- 'control' => 'radio',
+ 'type' => 'radio',
'choices' => array(
'fixed' => __('Fixed'),
'scroll' => __('Scroll'),
),
- 'default' => 'fixed',
) );
/* Nav Menus */
@@ -636,13 +706,18 @@ final class WP_Customize {
$choices[ $menu->term_id ] = $truncated_name;
}
- $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,
+ $menu_setting_id = "nav_menu_locations[{$location}]";
+
+ $this->add_setting( $menu_setting_id, array(
'sanitize_callback' => 'absint',
+ 'theme_supports' => 'menus',
+ ) );
+
+ $this->add_control( $menu_setting_id, array(
+ 'label' => $description,
+ 'section' => 'nav',
+ 'type' => 'select',
+ 'choices' => $choices,
) );
}
@@ -660,34 +735,43 @@ final class WP_Customize {
$choices['page'] = __( 'A static page (select below)' );
$this->add_setting( 'show_on_front', array(
- 'label' => __( 'Front page displays' ),
- // 'theme_supports' => 'static-front-page',
- 'section' => 'static_front_page',
- 'control' => 'radio',
- 'choices' => $choices,
'default' => get_option( 'show_on_front' ),
- 'type' => 'option',
'capability' => 'manage_options',
+ 'type' => 'option',
+ // 'theme_supports' => 'static-front-page',
+ ) );
+
+ $this->add_control( 'show_on_front', array(
+ 'label' => __( 'Front page displays' ),
+ 'section' => 'static_front_page',
+ 'type' => 'radio',
+ 'choices' => $choices,
) );
$this->add_setting( 'page_on_front', array(
- 'label' => __( 'Front page' ),
+ 'type' => 'option',
+ 'capability' => 'manage_options',
// 'theme_supports' => 'static-front-page',
- 'section' => 'static_front_page',
- 'control' => 'dropdown-pages',
- 'type' => 'option',
- 'capability' => 'manage_options',
- 'visibility' => array( 'show_on_front', 'page' ),
+ ) );
+
+ $this->add_control( 'page_on_front', array(
+ 'label' => __( 'Front page' ),
+ 'section' => 'static_front_page',
+ 'type' => 'dropdown-pages',
+ 'visibility' => array( 'show_on_front', 'page' ),
) );
$this->add_setting( 'page_for_posts', array(
- 'label' => __( 'Posts page' ),
- // 'theme_supports' => 'static-front-page',
- 'section' => 'static_front_page',
- 'control' => 'dropdown-pages',
'type' => 'option',
'capability' => 'manage_options',
- 'visibility' => array( 'show_on_front', 'page' ),
+ // 'theme_supports' => 'static-front-page',
+ ) );
+
+ $this->add_control( 'page_for_posts', array(
+ 'label' => __( 'Posts page' ),
+ 'section' => 'static_front_page',
+ 'type' => 'dropdown-pages',
+ 'visibility' => array( 'show_on_front', 'page' ),
) );
/* Site Title & Tagline */
@@ -697,19 +781,25 @@ final class WP_Customize {
) );
$this->add_setting( 'blogname', array(
- 'label' => __( 'Site Title' ),
- 'section' => 'strings',
- 'default' => get_option( 'blogname' ),
- 'type' => 'option',
- 'capability' => 'manage_options',
+ 'default' => get_option( 'blogname' ),
+ 'type' => 'option',
+ 'capability' => 'manage_options',
+ ) );
+
+ $this->add_control( 'blogname', array(
+ 'label' => __( 'Site Title' ),
+ 'section' => 'strings',
) );
$this->add_setting( 'blogdescription', array(
- 'label' => __( 'Tagline' ),
- 'section' => 'strings',
- 'default' => get_option( 'blogdescription' ),
- 'type' => 'option',
- 'capability' => 'manage_options',
+ 'default' => get_option( 'blogdescription' ),
+ 'type' => 'option',
+ 'capability' => 'manage_options',
+ ) );
+
+ $this->add_control( 'blogdescription', array(
+ 'label' => __( 'Tagline' ),
+ 'section' => 'strings',
) );
}
};
diff --git a/wp-includes/customize-controls.php b/wp-includes/customize-controls.php
index 3780968bfb..97fb0c48b5 100644
--- a/wp-includes/customize-controls.php
+++ b/wp-includes/customize-controls.php
@@ -95,27 +95,30 @@ do_action( 'customize_controls_print_scripts' );
$scheme = is_ssl() ? 'https' : 'http';
$settings = array(
'preview' => esc_url( home_url( '/', $scheme ) ),
+ 'settings' => array(),
'controls' => array(),
'prefix' => WP_Customize_Setting::name_prefix,
);
foreach ( $this->settings as $id => $setting ) {
- $settings['controls'][ $id ] = array(
+ $settings['settings'][ $id ] = array(
'value' => $setting->value(),
- 'control' => $setting->control,
- 'params' => $setting->control_params,
);
+ }
- if ( $setting->visibility ) {
- if ( is_string( $setting->visibility ) ) {
+ foreach ( $this->controls as $id => $control ) {
+ $settings['controls'][ $id ] = $control->json();
+
+ if ( $control->visibility ) {
+ if ( is_string( $control->visibility ) ) {
$settings['controls'][ $id ]['visibility'] = array(
- 'id' => $setting->visibility,
+ 'id' => $control->visibility,
'value' => true,
);
} else {
$settings['controls'][ $id ]['visibility'] = array(
- 'id' => $setting->visibility[0],
- 'value' => $setting->visibility[1],
+ 'id' => $control->visibility[0],
+ 'value' => $control->visibility[1],
);
}
diff --git a/wp-includes/js/customize-base.dev.js b/wp-includes/js/customize-base.dev.js
index 4ea8b10506..ca3a2376dd 100644
--- a/wp-includes/js/customize-base.dev.js
+++ b/wp-includes/js/customize-base.dev.js
@@ -397,7 +397,7 @@ if ( typeof wp === 'undefined' )
add: function( id, value ) {
if ( this.has( id ) )
- return;
+ return this.value( id );
this._value[ id ] = value;
this._value[ id ]._parent = this._value;
diff --git a/wp-includes/js/customize-controls.dev.js b/wp-includes/js/customize-controls.dev.js
index 4fc0c6f37f..043fe3365e 100644
--- a/wp-includes/js/customize-controls.dev.js
+++ b/wp-includes/js/customize-controls.dev.js
@@ -6,19 +6,24 @@
* - previewer - The Previewer instance to sync with.
* - method - The method to use for syncing. Supports 'refresh' and 'postMessage'.
*/
- api.Control = api.Value.extend({
+ api.Setting = api.Value.extend({
initialize: function( id, value, options ) {
- var name = '[name="' + api.settings.prefix + id + '"]';
+ var element;
- this.params = {};
api.Value.prototype.initialize.call( this, value, options );
this.id = id;
- this.container = $( '#customize-control-' + id );
- this.element = this.element || new api.Element( this.container.find( name ) );
-
this.method = this.method || 'refresh';
+ element = $( '', {
+ type: 'hidden',
+ value: this.get(),
+ name: api.settings.prefix + id
+ });
+
+ element.appendTo( this.previewer.form );
+ this.element = new api.Element( element );
+
this.element.link( this );
this.link( this.element );
@@ -34,12 +39,67 @@
}
});
- api.ColorControl = api.Control.extend({
- initialize: function( id, value, options ) {
- var self = this,
- picker, ui, text, toggle, update;
+ api.Control = api.Class.extend({
+ initialize: function( id, options ) {
+ var control = this,
+ nodes, radios, settings;
- api.Control.prototype.initialize.call( this, id, value, options );
+ 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() {}
+ });
+
+ api.ColorControl = api.Control.extend({
+ ready: function() {
+ var control = this,
+ picker, ui, text, toggle, update;
picker = this.container.find( '.color-picker' );
ui = picker.find( '.color-picker-controls' );
@@ -47,52 +107,48 @@
update = function( color ) {
color = '#' + color;
toggle.css( 'background', color );
- self.farbtastic.setColor( color );
+ control.farbtastic.setColor( color );
};
- this.input = new api.Element( ui.find( 'input' ) ); // Find text input.
-
- this.link( this.input );
- this.input.link( this );
-
picker.on( 'click', 'a', function() {
ui.toggle();
});
this.farbtastic = $.farbtastic( picker.find('.farbtastic-placeholder'), function( color ) {
- self.set( color.replace( '#', '' ) );
+ control.setting.set( color.replace( '#', '' ) );
});
- this.bind( update );
- update( this() );
- },
- validate: function( to ) {
- return /^[a-fA-F0-9]{3}([a-fA-F0-9]{3})?$/.test( to ) ? to : null;
+ this.setting.bind( update );
+ update( this.setting() );
}
+ // ,
+ // validate: function( to ) {
+ // return /^[a-fA-F0-9]{3}([a-fA-F0-9]{3})?$/.test( to ) ? to : null;
+ // }
});
api.UploadControl = api.Control.extend({
- initialize: function( id, value, options ) {
+ ready: function() {
var control = this;
- api.Control.prototype.initialize.call( this, id, value, options );
this.params.removed = this.params.removed || '';
this.uploader = new wp.Uploader({
browser: this.container.find('.upload'),
success: function( attachment ) {
- control.set( attachment.url );
+ control.setting.set( attachment.url );
}
});
this.remover = this.container.find('.remove');
this.remover.click( function( event ) {
- control.set( control.params.removed );
+ control.setting.set( control.params.removed );
event.preventDefault();
});
- this.bind( this.removerVisibility );
- this.removerVisibility( this.get() );
+ this.removerVisibility = $.proxy( this.removerVisibility, this );
+ this.setting.bind( this.removerVisibility );
+ this.removerVisibility( this.setting.get() );
if ( this.params.context )
control.uploader.param( 'post_data[context]', this.params.context );
@@ -103,13 +159,12 @@
});
api.ImageControl = api.UploadControl.extend({
- initialize: function( id, value, options ) {
+ ready: function( id, value, options ) {
var control = this;
- api.UploadControl.prototype.initialize.call( this, id, value, options );
-
- this.thumbnail = this.container.find('.thumbnail img');
- this.bind( this.thumbnailSrc );
+ this.thumbnail = this.container.find('.thumbnail img');
+ this.thumbnailSrc = $.proxy( this.thumbnailSrc, this );
+ this.setting.bind( this.thumbnailSrc );
this.library = this.container.find('.library');
this.changer = this.container.find('.change');
@@ -137,7 +192,7 @@
});
this.library.on( 'click', 'a', function( event ) {
- control.set( $(this).attr('href') );
+ control.setting.set( $(this).attr('href') );
event.preventDefault();
});
},
@@ -152,6 +207,9 @@
// Change objects contained within the main customize object to Settings.
api.defaultConstructor = api.Setting;
+ // Create the collection of Control objects.
+ api.control = new api.Values({ defaultConstructor: api.Control });
+
api.Previewer = api.Messenger.extend({
refreshBuffer: 250,
@@ -272,7 +330,7 @@
* Ready.
* ===================================================================== */
- api.controls = {
+ api.controlConstructor = {
color: api.ColorControl,
upload: api.UploadControl,
image: api.ImageControl
@@ -289,11 +347,17 @@
url: api.settings.preview
});
+ $.each( api.settings.settings, function( id, data ) {
+ api.set( id, id, data.value, {
+ previewer: previewer
+ } );
+ });
+
$.each( api.settings.controls, function( id, data ) {
- var constructor = api.controls[ data.control ] || api.Control,
+ var constructor = api.controlConstructor[ data.type ] || api.Control,
control;
- control = api.add( id, new constructor( id, data.value, {
+ control = api.control.add( id, new constructor( id, {
params: data.params,
previewer: previewer
} ) );
@@ -326,9 +390,29 @@
});
// Background color uses postMessage by default
- api( 'background_color', function( control ) {
+ api.control( 'background_color', function( control ) {
control.method = 'postMessage';
});
+
+ 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 );
+ });
+ });
});
})( wp, jQuery );
\ No newline at end of file
diff --git a/wp-includes/js/plupload/wp-plupload.dev.js b/wp-includes/js/plupload/wp-plupload.dev.js
index 8ad2738606..bbd20ba0eb 100644
--- a/wp-includes/js/plupload/wp-plupload.dev.js
+++ b/wp-includes/js/plupload/wp-plupload.dev.js
@@ -66,7 +66,11 @@ if ( typeof wp === 'undefined' )
this.uploader.bind( 'UploadProgress', this.progress );
this.uploader.bind( 'FileUploaded', function( up, file, response ) {
- response = JSON.parse( response.response );
+ try {
+ response = JSON.parse( response.response );
+ } catch ( e ) {
+ return self.error( pluploadL10n.default_error, e );
+ }
if ( ! response || ! response.type || ! response.data )
return self.error( pluploadL10n.default_error );