Index: wp-admin/includes/template.php
===================================================================
--- wp-admin/includes/template.php	(revision 19363)
+++ wp-admin/includes/template.php	(working copy)
@@ -1669,45 +1669,91 @@
  *
  * @since 3.3.0
  *
- * Pointer user settings:
- *    p0 - Admin bar pointer, added 3.3.
  */
 function wp_pointer_enqueue( $hook_suffix ) {
-	$enqueue = false;
-
+	/*
+	 * Pointers to show
+	 * Format:
+	 * array( hook_suffix => pointer_id )
+	 * You can use 'all' as hook_suffix to diplay the pointer on all screens.
+	 */
+	$pointers = apply_filters( 'wp_pointers', array(
+		'index.php' => array(
+				'wp330-toolbar',
+				'wp330-flyout-menus'
+			),
+		'post-new.php' => 'wp330-media-uploader',
+		'themes.php' => 'wp330-saving-widgets',
+		'all' => ''
+	) );
+	
+	// Get screen relevant pointers
+	$pointers = array_merge( (array) $pointers[$hook_suffix], (array) $pointers['all'] ) ;
+	
+	// No pointers to show
+	if ( empty( $pointers ) )
+		return;
+	
+	// Get pointers which are dismissed
 	$dismissed = explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
 
-	if ( ! in_array( 'wp330-admin-bar', $dismissed ) ) {
-		$enqueue = true;
-		add_action( 'admin_print_footer_scripts', '_wp_pointer_print_admin_bar' );
-	}
+	// Sort dismissed pointers out
+	$pointers = array_diff( $pointers, $dismissed );
 
-	if ( $enqueue ) {
-		wp_enqueue_style( 'wp-pointer' );
-		wp_enqueue_script( 'wp-pointer' );
-	}
+	// All pointers were already shown
+	if ( empty( $pointers ) )
+		return;
+
+	// Print pointers
+	foreach ( $pointers as $pointer )
+			add_action( 'admin_print_footer_scripts', '_wp_pointer_print_' . str_replace( '-', '_', $pointer ) );
+
+	// Load pointers script and style
+	wp_enqueue_style( 'wp-pointer' );
+	wp_enqueue_script( 'wp-pointer' );
+
 }
 add_action( 'admin_enqueue_scripts', 'wp_pointer_enqueue' );
 
-function _wp_pointer_print_admin_bar() {
-	$pointer_content  = '<h3>' . 'The admin bar has been updated in WordPress 3.3.' . '</h3>';
-	$pointer_content .= '<p>' . sprintf( 'Have some feedback? Visit the <a href="%s">forum</a>.', 'http://wordpress.org/support/forum/alphabeta' ) . '</p>';
-	$pointer_content .= '<p>' . 'P.S. You are looking at a new admin pointer.' . '</p>';
+/**
+ * Print the pointer javascript data.
+ *
+ * @since 3.3.0
+ *
+ * @param string $pointer_id The pointer ID
+ * @param string $selector The HTML elements, on which the pointer should be attached.
+ * @param string $content The pointer content
+ * @param array|string $position The pointer position. Defaults to edge = top and align = center
+ */
+function _wp_pointer_javascript( $pointer_id, $selector, $content, $position ) {
+	if ( empty( $pointer_id ) || empty( $selector ) || empty( $content ) )
+		return;
 
+	/* TODO: Match wp-pointers.js defaults */
+	$_position = '';
+	if ( is_string( $position ) )
+		$_position = "position: '{$position}',";
+	elseif( is_array( $position ) ) {
+		if ( ! empty( $position['edge'] ) && ! empty( $position['align'] ) ) {
+			$_position = "position: { edge: '{$position['edge']}', align: '{$position['align']}' },";
+		} elseif ( ! empty( $position['edge'] ) ) {
+			$_position = "position: { edge: '{$position['edge']}' },";
+		} elseif ( ! empty( $position['align'] ) ) {
+			$_position = "position: { align: '{$position['align']}' },";
+		}
+	}
+
+
 ?>
 <script type="text/javascript">
 //<![CDATA[
 jQuery(document).ready( function($) {
-	$('#wpadminbar').pointer({
-		content: '<?php echo $pointer_content; ?>',
-		position: {
-			edge:  'top',
-			align: 'center'
-		},
+	$('<?php echo $selector; ?>').pointer({
+		content: '<?php echo $content; ?>',
+		<?php if ( !empty( $_position) ) echo $_position; ?>
 		close: function() {
 			$.post( ajaxurl, {
-					pointer: 'wp330-admin-bar',
-				//	_ajax_nonce: $('#_ajax_nonce').val(),
+					pointer: '<?php echo $pointer_id; ?>',
 					action: 'dismiss-wp-pointer'
 			});
 		}
@@ -1717,3 +1763,67 @@
 </script>
 <?php
 }
+
+
+/**
+ * Print 'New Feature: Toolbar' for 3.3.0.
+ *
+ * @since 3.3.0
+ */
+function _wp_pointer_print_wp330_toolbar() {
+	$content  = '<h3>' . esc_js( __( 'New Feature: Toolbar' ) ). '</h3>';
+	$content .= '<p>' . esc_js( __( "We've combined the admin bar and the old Dashboard header into one persistent toolbar. Hover over the toolbar items to see what's new." ) ) . '</p>';
+
+	if ( is_multisite() && is_super_admin() )
+		$content .= '<p>' .esc_js( __( 'Network Admin is now located in the My Sites menu.' ) ) . '</p>';
+
+	$position['align'] = 'right';
+	$position['edge'] = 'top';
+
+	_wp_pointer_javascript( 'wp330-toolbar', '#wpadminbar', $content, $position );
+}
+
+/**
+ * Print 'New Feature: Flyout Menus' for 3.3.0.
+ *
+ * @since 3.3.0
+ */
+function _wp_pointer_print_wp330_flyout_menus() {
+	$content  = '<h3>' .  esc_js( __( 'New Feature: Flyout Menus' ) ) . '</h3>';
+	$content .= '<p>' .  esc_js( __( 'Instead of clicking to open and close navigation sections, just hover over a menu item and the submenu will "fly out" to the side, allowing single-click access to any screen.' ) ) . '</p>';
+
+	$position['edge'] = 'left';
+	$position['align'] = 'bottom';
+
+	_wp_pointer_javascript( 'wp330-flyout-menus', '#adminmenu', $content, $position );
+}
+
+/**
+ * Print 'Updated Media Uploader' for 3.3.0.
+ *
+ * @since 3.3.0
+ */
+function _wp_pointer_print_wp330_media_uploader() {
+	$content  = '<h3>' . esc_js( __( 'Updated Media Uploader' ) ) . '</h3>';
+	$content .= '<p>' . esc_js( __( 'The single media icon now launches the uploader for all file types, and the new drag and drop interface makes uploading a breeze.' ) ) . '</p>';
+
+	$position['align'] = 'right';
+	$position['edge'] = 'top';
+
+	_wp_pointer_javascript( 'wp330-media-uploader', '#content-add_media', $content, $position );
+}
+
+/**
+ * Print 'New Feature: Saving Widgets' for 3.3.0.
+ *
+ * @since 3.3.0
+ */
+function _wp_pointer_print_wp330_saving_widgets() {
+	$content  = '<h3>' . esc_js( __( 'New Feature: Saving Widgets' ) ) . '</h3>';
+	$content .= '<p>' . esc_js( __( "If you change your mind and revert to your previous theme, we'll put the widgets back the way you had them." ) ) . '</p>';
+
+	$position['align'] = 'left';
+	$position['edge'] = 'top';
+
+	_wp_pointer_javascript( 'wp330-saving-widgets', '#message2', $content, $position );
+}
