+ $args = array_slice( func_get_args(), 1 );
+
+ switch ( $feature ) {
+ case 'post-formats' :
+ if ( is_array( $args[0] ) )
+ $args[0] = array_intersect( $args[0], array_keys( get_post_format_slugs() ) );
+ break;
+
+ case 'html5' :
+ // You can't just pass 'html5', you need to pass an array of types.
+ if ( empty( $args[0] ) ) {
+ $args = array( 0 => array( 'comment-list', 'comment-form', 'search-form' ) );
+ } elseif ( ! is_array( $args[0] ) ) {
+ _doing_it_wrong( "add_theme_support( 'html5' )", 'You need to pass an array of types.', '3.6.1' );
+ return false;
+ }
+
+ // Calling 'html5' again merges, rather than overwrites.
+ if ( isset( $_wp_theme_features['html5'] ) )
+ $args[0] = array_merge( $_wp_theme_features['html5'][0], $args[0] );
+ break;
+
+ case 'custom-header-uploads' :
+ return add_theme_support( 'custom-header', array( 'uploads' => true ) );
+ break;
+
+ case 'custom-header' :
+ if ( ! is_array( $args ) )
+ $args = array( 0 => array() );
+
+ $defaults = array(
+ 'default-image' => '',
+ 'random-default' => false,
+ 'width' => 0,
+ 'height' => 0,
+ 'flex-height' => false,
+ 'flex-width' => false,
+ 'default-text-color' => '',
+ 'header-text' => true,
+ 'uploads' => true,
+ 'wp-head-callback' => '',
+ 'admin-head-callback' => '',
+ 'admin-preview-callback' => '',
+ );
+
+ $jit = isset( $args[0]['__jit'] );
+ unset( $args[0]['__jit'] );
+
+ // Merge in data from previous add_theme_support() calls.
+ // The first value registered wins. (A child theme is set up first.)
+ if ( isset( $_wp_theme_features['custom-header'] ) )
+ $args[0] = wp_parse_args( $_wp_theme_features['custom-header'][0], $args[0] );
+
+ // Load in the defaults at the end, as we need to insure first one wins.
+ // This will cause all constants to be defined, as each arg will then be set to the default.
+ if ( $jit )
+ $args[0] = wp_parse_args( $args[0], $defaults );
+
+ // If a constant was defined, use that value. Otherwise, define the constant to ensure
+ // the constant is always accurate (and is not defined later, overriding our value).
+ // As stated above, the first value wins.
+ // Once we get to wp_loaded (just-in-time), define any constants we haven't already.
+ // Constants are lame. Don't reference them. This is just for backwards compatibility.
+
+ if ( defined( 'NO_HEADER_TEXT' ) )
+ $args[0]['header-text'] = ! NO_HEADER_TEXT;
+ elseif ( isset( $args[0]['header-text'] ) )
+ define( 'NO_HEADER_TEXT', empty( $args[0]['header-text'] ) );
+
+ if ( defined( 'HEADER_IMAGE_WIDTH' ) )
+ $args[0]['width'] = (int) HEADER_IMAGE_WIDTH;
+ elseif ( isset( $args[0]['width'] ) )
+ define( 'HEADER_IMAGE_WIDTH', (int) $args[0]['width'] );
+
+ if ( defined( 'HEADER_IMAGE_HEIGHT' ) )
+ $args[0]['height'] = (int) HEADER_IMAGE_HEIGHT;
+ elseif ( isset( $args[0]['height'] ) )
+ define( 'HEADER_IMAGE_HEIGHT', (int) $args[0]['height'] );
+
+ if ( defined( 'HEADER_TEXTCOLOR' ) )
+ $args[0]['default-text-color'] = HEADER_TEXTCOLOR;
+ elseif ( isset( $args[0]['default-text-color'] ) )
+ define( 'HEADER_TEXTCOLOR', $args[0]['default-text-color'] );
+
+ if ( defined( 'HEADER_IMAGE' ) )
+ $args[0]['default-image'] = HEADER_IMAGE;
+ elseif ( isset( $args[0]['default-image'] ) )
+ define( 'HEADER_IMAGE', $args[0]['default-image'] );
+
+ if ( $jit && ! empty( $args[0]['default-image'] ) )
+ $args[0]['random-default'] = false;
+
+ // If headers are supported, and we still don't have a defined width or height,
+ // we have implicit flex sizes.
+ if ( $jit ) {
+ if ( empty( $args[0]['width'] ) && empty( $args[0]['flex-width'] ) )
+ $args[0]['flex-width'] = true;
+ if ( empty( $args[0]['height'] ) && empty( $args[0]['flex-height'] ) )
+ $args[0]['flex-height'] = true;
+ }
+
+ break;
+
+ case 'custom-background' :
+ if ( ! is_array( $args ) )
+ $args = array( 0 => array() );
+
+ $defaults = array(
+ 'default-image' => '',
+ 'default-repeat' => 'repeat',
+ 'default-position-x' => 'left',
+ 'default-attachment' => 'scroll',
+ 'default-color' => '',
+ 'wp-head-callback' => '_custom_background_cb',
+ 'admin-head-callback' => '',
+ 'admin-preview-callback' => '',
+ );
+
+ $jit = isset( $args[0]['__jit'] );
+ unset( $args[0]['__jit'] );
+
+ // Merge in data from previous add_theme_support() calls. The first value registered wins.
+ if ( isset( $_wp_theme_features['custom-background'] ) )
+ $args[0] = wp_parse_args( $_wp_theme_features['custom-background'][0], $args[0] );
+
+ if ( $jit )
+ $args[0] = wp_parse_args( $args[0], $defaults );
+
+ if ( defined( 'BACKGROUND_COLOR' ) )
+ $args[0]['default-color'] = BACKGROUND_COLOR;
+ elseif ( isset( $args[0]['default-color'] ) || $jit )
+ define( 'BACKGROUND_COLOR', $args[0]['default-color'] );
+
+ if ( defined( 'BACKGROUND_IMAGE' ) )
+ $args[0]['default-image'] = BACKGROUND_IMAGE;
+ elseif ( isset( $args[0]['default-image'] ) || $jit )
+ define( 'BACKGROUND_IMAGE', $args[0]['default-image'] );
+
+ break;
+ }
+
+ $_wp_theme_features[ $feature ] = $args;
+}
+
+/**
+ * Registers the internal custom header and background routines.
+ *
+ * @since 3.4.0
+ * @access private
+ */
+function _custom_header_background_just_in_time() {
+ global $custom_image_header, $custom_background;
+
+ if ( current_theme_supports( 'custom-header' ) ) {
+ // In case any constants were defined after an add_custom_image_header() call, re-run.
+ add_theme_support( 'custom-header', array( '__jit' => true ) );
+
+ $args = get_theme_support( 'custom-header' );
+ if ( $args[0]['wp-head-callback'] )
+ add_action( 'wp_head', $args[0]['wp-head-callback'] );
+
+ if ( is_admin() ) {
+ require_once( ABSPATH . 'wp-admin/custom-header.php' );
+ $custom_image_header = new Custom_Image_Header( $args[0]['admin-head-callback'], $args[0]['admin-preview-callback'] );
+ }
+ }
+
+ if ( current_theme_supports( 'custom-background' ) ) {
+ // In case any constants were defined after an add_custom_background() call, re-run.
+ add_theme_support( 'custom-background', array( '__jit' => true ) );
+
+ $args = get_theme_support( 'custom-background' );
+ add_action( 'wp_head', $args[0]['wp-head-callback'] );
+
+ if ( is_admin() ) {
+ require_once( ABSPATH . 'wp-admin/custom-background.php' );
+ $custom_background = new Custom_Background( $args[0]['admin-head-callback'], $args[0]['admin-preview-callback'] );
+ }
+ }
+}
+add_action( 'wp_loaded', '_custom_header_background_just_in_time' );
+
+/**
+ * Gets the theme support arguments passed when registering that support
+ *
+ * @since 3.1
+ * @param string $feature the feature to check
+ * @return array The array of extra arguments
+ */
+function get_theme_support( $feature ) {
+ global $_wp_theme_features;
+ if ( ! isset( $_wp_theme_features[ $feature ] ) )
+ return false;
+
+ if ( func_num_args() <= 1 )
+ return $_wp_theme_features[ $feature ];
+
+ $args = array_slice( func_get_args(), 1 );
+ switch ( $feature ) {
+ case 'custom-header' :
+ case 'custom-background' :
+ if ( isset( $_wp_theme_features[ $feature ][0][ $args[0] ] ) )
+ return $_wp_theme_features[ $feature ][0][ $args[0] ];
+ return false;
+ break;
+ default :
+ return $_wp_theme_features[ $feature ];
+ break;
+ }
+}
+
+/**
+ * Allows a theme to de-register its support of a certain feature
+ *
+ * Should be called in the theme's functions.php file. Generally would
+ * be used for child themes to override support from the parent theme.
+ *
+ * @since 3.0.0
+ * @see add_theme_support()
+ * @param string $feature the feature being added
+ * @return bool Whether feature was removed.
+ */
+function remove_theme_support( $feature ) {
+ // Blacklist: for internal registrations not used directly by themes.
+ if ( in_array( $feature, array( 'editor-style', 'widgets', 'menus' ) ) )
+ return false;
+
+ return _remove_theme_support( $feature );
+}
+
+/**
+ * Do not use. Removes theme support internally, ignorant of the blacklist.
+ *
+ * @access private
+ * @since 3.1.0
+ */
+function _remove_theme_support( $feature ) {
+ global $_wp_theme_features;
+
+ switch ( $feature ) {
+ case 'custom-header-uploads' :
+ if ( ! isset( $_wp_theme_features['custom-header'] ) )
+ return false;
+ add_theme_support( 'custom-header', array( 'uploads' => false ) );
+ return; // Do not continue - custom-header-uploads no longer exists.
+ }
+
+ if ( ! isset( $_wp_theme_features[ $feature ] ) )
+ return false;
+
+ switch ( $feature ) {
+ case 'custom-header' :
+ if ( ! did_action( 'wp_loaded' ) )
+ break;
+ $support = get_theme_support( 'custom-header' );
+ if ( $support[0]['wp-head-callback'] )
+ remove_action( 'wp_head', $support[0]['wp-head-callback'] );
+ remove_action( 'admin_menu', array( $GLOBALS['custom_image_header'], 'init' ) );
+ unset( $GLOBALS['custom_image_header'] );
+ break;
+
+ case 'custom-background' :
+ if ( ! did_action( 'wp_loaded' ) )
+ break;
+ $support = get_theme_support( 'custom-background' );
+ remove_action( 'wp_head', $support[0]['wp-head-callback'] );
+ remove_action( 'admin_menu', array( $GLOBALS['custom_background'], 'init' ) );
+ unset( $GLOBALS['custom_background'] );
+ break;
+ }
+
+ unset( $_wp_theme_features[ $feature ] );
+ return true;