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 ); ?>

    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 );