Index: bp-xprofile/bp-xprofile-classes.php
===================================================================
--- bp-xprofile/bp-xprofile-classes.php	(revision 9035)
+++ bp-xprofile/bp-xprofile-classes.php	(working copy)
@@ -2515,6 +2515,255 @@
 }
 
 /**
+ * Visual Editor xprofile field type.
+ *
+ * @since BuddyPress (2.2.0)
+ */
+class BP_XProfile_Field_Type_Richtext extends BP_XProfile_Field_Type {
+	
+	/**
+	 * Constructor for the Rich Text field type
+ 	 */
+	public function __construct() {
+	
+		parent::__construct();
+
+		$this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' );
+		$this->name     = _x( 'Visual Editor', 'xprofile field type', 'buddypress' );
+		$this->type     = 'richtext';
+		
+		// allow all values to pass validation
+		$this->set_format( '/.*/', 'replace' );
+		
+		// create custom filters that mirror 'the_content' for formatting output
+		add_filter( 'bp_xprofile_field_type_richtext_content', 'wptexturize'        );
+		add_filter( 'bp_xprofile_field_type_richtext_content', 'convert_smilies'    );
+		add_filter( 'bp_xprofile_field_type_richtext_content', 'convert_chars'      );
+		add_filter( 'bp_xprofile_field_type_richtext_content', 'wpautop'            );
+		add_filter( 'bp_xprofile_field_type_richtext_content', 'shortcode_unautop'  );
+
+		// override and augment allowed tags
+		add_filter( 'xprofile_allowed_tags', array( $this, 'allowed_tags' ), 30, 2 );
+		
+		// we need to parse the edit value
+		add_filter( 'bp_get_the_profile_field_edit_value', array( $this, 'get_field_value' ), 30, 3 );
+		
+		// filter for those who use xprofile_get_field_data instead of get_field_value
+		add_filter( 'xprofile_get_field_data', array( $this, 'get_field_data' ), 15, 3 );
+		
+		do_action( 'bp_xprofile_field_type_richtext', $this );
+		
+	}
+	
+	/**
+	 * Output the edit field HTML for this field type.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array
+	 */
+	public function edit_field_html( array $raw_properties = array() ) {
+
+		// user_id is a special optional parameter that certain other fields types pass to {@link bp_the_profile_field_options()}.
+		if ( isset( $raw_properties['user_id'] ) ) {
+			unset( $raw_properties['user_id'] );
+		}
+		
+		?>
+		<label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
+		<?php do_action( bp_get_the_profile_field_errors_action() ); ?>
+		<?php
+		
+		// define some default buttons for cases where teeny TInyMCE is set to false
+		$buttons = array(
+			'theme_advanced_buttons1' => 'bold,italic,underline,blockquote,strikethrough,|,link,unlink,|,spellchecker,removeformat,fullscreen',
+			'theme_advanced_buttons2' => '',
+			'theme_advanced_buttons3' => ''
+		);
+	
+		// define our editor
+		wp_editor( 
+	
+			bp_get_the_profile_field_edit_value(),
+			bp_get_the_profile_field_input_name(),
+			array(
+				'media_buttons' => apply_filters( 'bp_xprofile_field_type_richtext_addmedia', false ), 
+				'teeny' => apply_filters( 'bp_xprofile_field_type_richtext_teeny', true ), 
+				'quicktags' => apply_filters( 'bp_xprofile_field_type_richtext_quicktags', false ),
+				'tinymce' => apply_filters( 'bp_xprofile_field_type_richtext_buttons', $buttons )
+			)
+		
+		);
+	
+	}
+	
+	/**
+	 * Output HTML for this field type on the wp-admin Profile Fields screen
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
+	 */
+	public function admin_field_html( array $raw_properties = array() ) {
+	
+		// define some default buttons for cases where teeny TInyMCE is set to false
+		$buttons = array(
+			'theme_advanced_buttons1' => 'bold,italic,underline,blockquote,strikethrough,|,link,unlink,|,spellchecker,removeformat,fullscreen',
+			'theme_advanced_buttons2' => '',
+			'theme_advanced_buttons3' => ''
+		);
+	
+		// define our editor
+		wp_editor( 
+	
+			'', 
+			'xprofile_richtext',
+			array( 
+				'media_buttons' => apply_filters( 'bp_xprofile_field_type_richtext_addmedia', false ), 
+				'teeny' => apply_filters( 'bp_xprofile_field_type_richtext_teeny', true ), 
+				'quicktags' => apply_filters( 'bp_xprofile_field_type_richtext_quicktags', false ),
+				'tinymce' => apply_filters( 'bp_xprofile_field_type_richtext_buttons', $buttons )
+			)
+		
+		);
+	
+	}
+	
+	/**
+	 * This method usually outputs HTML for this field type's children options on the wp-admin Profile Fields
+	 * "Add Field" and "Edit Field" screens, but for this field type, we don't want it, so it's stubbed out.
+	 *
+	 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen.
+	 * @param string $control_type Optional. HTML input type used to render the current field's child options.
+	 */
+	public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {}
+	
+	/**
+	 * Format Visual Editor content for display.
+	 *
+	 * @since BuddyPress (2.1.0)
+	 *
+	 * @param string $field_value The Visual Editor content, as saved in the database.
+	 * @return string Formatted HTML.
+	 */
+	public static function display_filter( $field_value ) {
+
+		/**
+		 * This is a bit of a hack because formatted text looks strange with the
+		 * 'xprofile_filter_link_profile_data' filter applied. If instead, we parse
+		 * this field type in read mode after all BuddyPress filters have been applied
+		 * we can avoid this. Moreover, this method is called outside the scope of $this,
+		 * so we have to directly reference the name of this class in the filter
+		 */
+		add_filter( 'bp_get_the_profile_field_value', array( 'BP_XProfile_Field_Type_Richtext', 'get_field_value' ), 30, 3 );
+		
+		// return the data as received and format in get_field_value() below
+		return $field_value;
+		
+	}
+
+	/**
+	 * Show our field type in read mode
+	 *
+	 * @param string $value
+	 * @param string $type
+	 * @param integer $id
+	 * @return string
+	 */
+	public function get_field_value( $value = '', $type = '', $id = '' ) {
+	
+		// is it our field type?
+		if ( $type == 'richtext' ) {
+	
+			// we want the raw data, unfiltered
+			global $field;
+			$value = $field->data->value;
+		
+			// apply content filter
+			$value = apply_filters( 'bp_xprofile_field_type_richtext_content', stripslashes( $value ) );
+			
+			return apply_filters( 'bp_xprofile_field_type_richtext_value', $value );
+
+		}
+	
+		// fallback
+		return $value;
+		
+	}
+	
+	/**
+	 * Filter for those who use xprofile_get_field_data instead of get_field_value
+	 *
+	 * @param string $value
+	 * @param integer $field_id
+	 * @param integer $user_id
+	 * @return string
+	 */
+	function get_field_data( $value = '', $field_id = '', $user_id = '' ) {
+	
+		// check we get a field ID
+		if ( $field_id === '' ) return $value;
+	
+		// get field object
+		$field = new BP_XProfile_Field( $field_id );
+	
+		// is it ours?
+		if ( $field->type == $this->type ) {
+
+			// apply content filter
+			$value = apply_filters( 'bp_xprofile_field_type_richtext_content', stripslashes( $value ) );
+
+			// return filtered value
+			return apply_filters( 'bp_xprofile_field_type_richtext_value', $value );
+			
+		}
+		
+		// fallback
+		return $value;
+
+	}
+	
+	/**
+	 * Callback to allow tags that teeny TinyMCE enables
+	 *
+	 * @since BuddyPress (2.2.0)
+	 *
+	 * @param array $allowedtags The array of allowed tags
+	 * @param object $data_obj The xProfile data object (BP 2.1+)
+	 * @return array $allowedtags The modified array of allowed tags
+	 */
+	public function allowed_tags( $allowedtags, $data_obj = null ) {
+		
+		// test if BP has sent the data object
+		if ( ! is_null( $data_obj ) ) {
+			
+			// get field from data object
+			$field = new BP_XProfile_Field( $data_obj->field_id );
+			
+			// if this isn't our field, skip amending allowed tags
+			if ( $field->type != $this->type ) return $allowedtags;
+			
+		}
+		
+		// default tags we need to enable the teeny TinyMCE editor markup
+		$richtext_tags = array( 
+			'img'    => array( 'id' => 1, 'class' => 1, 'src' => 1, 'alt' => 1, 'width' => 1, 'height' => 1 ),
+			'ul'     => array( 'id' => 1, 'class' => 1 ),
+			'ol'     => array( 'id' => 1, 'class' => 1 ),
+			'li'     => array( 'id' => 1, 'class' => 1 ),
+			'span'   => array( 'style' => 1 ),
+			'p'      => array( 'style' => 1 ),
+		);
+		
+		$allowedtags = array_merge( $allowedtags, $richtext_tags );
+		
+		return apply_filters( 'bp_xprofile_field_type_richtext_allowedtags', $allowedtags, $data_obj );
+		
+	}
+	
+}
+
+/**
  * Textbox xprofile field type.
  *
  * @since BuddyPress (2.0.0)
Index: bp-xprofile/bp-xprofile-functions.php
===================================================================
--- bp-xprofile/bp-xprofile-functions.php	(revision 9035)
+++ bp-xprofile/bp-xprofile-functions.php	(working copy)
@@ -143,6 +143,7 @@
 		'radio'          => 'BP_XProfile_Field_Type_Radiobutton',
 		'selectbox'      => 'BP_XProfile_Field_Type_Selectbox',
 		'textarea'       => 'BP_XProfile_Field_Type_Textarea',
+		'richtext'       => 'BP_XProfile_Field_Type_Richtext',
 		'textbox'        => 'BP_XProfile_Field_Type_Textbox',
 	);
 
