+/**
+ * Remove custom background support.
+ *
+ * @since 3.1.0
+ * @see add_custom_background()
+ *
+ * @return bool Whether support was removed.
+ */
+function remove_custom_background() {
+ if ( ! current_theme_supports( 'custom-background' ) )
+ return false;
+
+ $callback = get_theme_support( 'custom-background' );
+ remove_action( 'wp_head', $callback[0]['callback'] );
+ _remove_theme_support( 'custom-background' );
+
+ if ( is_admin() ) {
+ remove_action( 'admin_menu', array( &$GLOBALS['custom_background'], 'init' ) );
+ unset( $GLOBALS['custom_background'] );
+ }
+
+ return true;
+}
+
+/**
+ * Default custom background callback.
+ *
+ * @since 3.0.0
+ * @see add_custom_background()
+ * @access protected
+ */
+function _custom_background_cb() {
+ $background = get_background_image();
+ $color = get_background_color();
+ if ( ! $background && ! $color )
+ return;
+
+ $style = $color ? "background-color: #$color;" : '';
+
+ if ( $background ) {
+ $image = " background-image: url('$background');";
+
+ $repeat = get_theme_mod( 'background_repeat', 'repeat' );
+ if ( ! in_array( $repeat, array( 'no-repeat', 'repeat-x', 'repeat-y', 'repeat' ) ) )
+ $repeat = 'repeat';
+ $repeat = " background-repeat: $repeat;";
+
+ $position = get_theme_mod( 'background_position_x', 'left' );
+ if ( ! in_array( $position, array( 'center', 'right', 'left' ) ) )
+ $position = 'left';
+ $position = " background-position: top $position;";
+
+ $attachment = get_theme_mod( 'background_attachment', 'scroll' );
+ if ( ! in_array( $attachment, array( 'fixed', 'scroll' ) ) )
+ $attachment = 'scroll';
+ $attachment = " background-attachment: $attachment;";
+
+ $style .= $image . $repeat . $position . $attachment;
+ }
+?>
+<style type="text/css">
+body { <?php echo trim( $style ); ?> }
+</style>
+<?php
+}
+
+/**
+ * Add callback for custom TinyMCE editor stylesheets.
+ *
+ * The parameter $stylesheet is the name of the stylesheet, relative to
+ * the theme root. It also accepts an array of stylesheets.
+ * It is optional and defaults to 'editor-style.css'.
+ *
+ * Supports RTL stylesheets automatically by searching for the -rtl prefix, e.g.
+ * editor-style-rtl.css. If an array of stylesheets is passed to add_editor_style(),
+ * RTL is only added for the first stylesheet.
+ *
+ * @since 3.0.0
+ *
+ * @param mixed $stylesheet Optional. Stylesheet name or array thereof, relative to theme root.
+ * Defaults to 'editor-style.css'
+ */
+function add_editor_style( $stylesheet = 'editor-style.css' ) {
+
+ add_theme_support( 'editor-style' );
+
+ if ( ! is_admin() )
+ return;
+
+ global $editor_styles;
+ $editor_styles = (array) $editor_styles;
+ $stylesheet = (array) $stylesheet;
+ if ( is_rtl() ) {
+ $rtl_stylesheet = str_replace('.css', '-rtl.css', $stylesheet[0]);
+ $stylesheet[] = $rtl_stylesheet;
+ }
+
+ $editor_styles = array_merge( $editor_styles, $stylesheet );
+}
+
+/**
+ * Removes all visual editor stylesheets.
+ *
+ * @since 3.1.0
+ *
+ * @return bool True on success, false if there were no stylesheets to remove.
+ */
+function remove_editor_styles() {
+ if ( ! current_theme_supports( 'editor-style' ) )
+ return false;
+ _remove_theme_support( 'editor-style' );
+ if ( is_admin() )
+ $GLOBALS['editor_styles'] = array();
+ return true;
+}
+
+/**
+ * Allows a theme to register its support of a certain feature
+ *
+ * Must be called in the theme's functions.php file to work.
+ * If attached to a hook, it must be after_setup_theme.
+ * The init hook may be too late for some features.
+ *
+ * @since 2.9.0
+ * @param string $feature the feature being added
+ */
+function add_theme_support( $feature ) {
+ global $_wp_theme_features;
+
+ if ( func_num_args() == 1 )
+ $_wp_theme_features[$feature] = true;
+ else
+ $_wp_theme_features[$feature] = array_slice( func_get_args(), 1 );
+
+ if ( $feature == 'post-formats' && is_array( $_wp_theme_features[$feature][0] ) )
+ $_wp_theme_features[$feature][0] = array_intersect( $_wp_theme_features[$feature][0], array_keys( get_post_format_slugs() ) );
+}
+
+/**
+ * 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;
+ else
+ return $_wp_theme_features[$feature];
+}
+
+/**
+ * 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( 'custom-background', 'custom-header', '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;
+
+ if ( ! isset( $_wp_theme_features[$feature] ) )
+ return false;
+ unset( $_wp_theme_features[$feature] );
+ return true;
+}
+
+/**
+ * Checks a theme's support for a given feature
+ *
+ * @since 2.9.0
+ * @param string $feature the feature being checked
+ * @return boolean
+ */
+function current_theme_supports( $feature ) {
+ global $_wp_theme_features;
+
+ if ( !isset( $_wp_theme_features[$feature] ) )
+ return false;
+
+ // If no args passed then no extra checks need be performed
+ if ( func_num_args() <= 1 )
+ return true;
+
+ $args = array_slice( func_get_args(), 1 );
+
+ // @todo Allow pluggable arg checking
+ switch ( $feature ) {
+ case 'post-thumbnails':
+ // post-thumbnails can be registered for only certain content/post types by passing
+ // an array of types to add_theme_support(). If no array was passed, then
+ // any type is accepted
+ if ( true === $_wp_theme_features[$feature] ) // Registered for all types
+ return true;
+ $content_type = $args[0];
+ if ( in_array($content_type, $_wp_theme_features[$feature][0]) )
+ return true;
+ else
+ return false;
+ break;
+ }
+
+ return true;
+}
+
+/**
+ * Checks a theme's support for a given feature before loading the functions which implement it.
+ *
+ * @since 2.9.0
+ * @param string $feature the feature being checked
+ * @param string $include the file containing the functions that implement the feature
+ */
+function require_if_theme_supports( $feature, $include) {
+ if ( current_theme_supports( $feature ) )
+ require ( $include );
+}
+
+/**
+ * Checks an attachment being deleted to see if it's a header or background image.
+ *
+ * If true it removes the theme modification which would be pointing at the deleted
+ * attachment
+ *
+ * @access private
+ * @since 3.0.0
+ * @param int $id the attachment id
+ */
+function _delete_attachment_theme_mod( $id ) {
+ $attachment_image = wp_get_attachment_url( $id );
+ $header_image = get_header_image();
+ $background_image = get_background_image();
+
+ if ( $header_image && $header_image == $attachment_image )
+ remove_theme_mod( 'header_image' );
+
+ if ( $background_image && $background_image == $attachment_image )
+ remove_theme_mod( 'background_image' );
+}
+
+add_action( 'delete_attachment', '_delete_attachment_theme_mod' );
+