Index: wp-admin/includes/template.php
===================================================================
--- wp-admin/includes/template.php	(revision 18921)
+++ wp-admin/includes/template.php	(working copy)
@@ -1630,52 +1630,125 @@
 }
 
 /**
- * Initializes the new feature pointers.
+ * Special function for managing WP one off pointer registrations.
  *
+ * @since 3.3-aortic-dissection
+ *
+ * It's likely better to call wp_register_pointer() in somewhere in upgrade.php
+ * So that this function isn't necassary. Up for discussion
+ */
+function wp_core_pointers() {
+	$pointer = 'wp330-admin-bar';
+	
+	$done = (array) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true );
+	
+	if ( ! in_array( $pointer, $done ) && apply_filters( 'show_wp_pointer_admin_bar', true ) ) {
+		wp_register_pointer( $pointer, '_wp_pointer_print_admin_bar' );
+		$done[] = $pointer; 
+		update_user_meta( get_current_user_id(), 'dismissed_wp_pointers', $done );
+		
+	}
+}
+add_action( 'admin_enqueue_scripts', 'wp_core_pointers' );
+
+/**
+ * Register a pointer.
+ *
  * @since 3.3.0
  *
- * Pointer user settings:
- *    p0 - Admin bar pointer, added 3.3.
+ * Should only be called where the code is executed once, for example, on upgrade, install, or on user-action.
+ *
  */
+function wp_register_pointer( $pointer, $callback, $hook_suffix = 'all', $args = array() ) {
+	$queued = (array) get_user_meta( get_current_user_id(), 'queued_wp_pointers', true );
+	$queued[ $hook_suffix ][ $pointer ] = array_merge( array( 'callback' => $callback ), $args );
+	update_user_meta( get_current_user_id(), 'queued_wp_pointers', $queued ); 
+}
+
+/**
+ * Initializes the new feature pointers.
+ *
+ * @since 3.3.0
+ */
 function wp_pointer_enqueue( $hook_suffix ) {
-	$enqueue = false;
-
-	$admin_bar = get_user_setting( 'p0', 0 );
-	if ( ! $admin_bar && apply_filters( 'show_wp_pointer_admin_bar', true ) ) {
-		$enqueue = true;
-		add_action( 'admin_print_footer_scripts', '_wp_pointer_print_admin_bar' );
+	$queued = (array) get_user_meta( get_current_user_id(), 'queued_wp_pointers', true );
+	
+	if ( empty( $queued[ 'all' ] ) && empty( $queued[ $hook_suffix] ) ) return;
+	
+	if ( ! empty( $queued[ 'all' ] ) ) {
+		foreach( $queued[ 'all' ] as $pointer ) {
+			add_action( 'admin_print_footer_scripts', $pointer[ 'callback' ] );
+		}
 	}
-
-	if ( $enqueue ) {
-		wp_enqueue_style( 'wp-pointer' );
-		wp_enqueue_script( 'wp-pointer' );
-		wp_enqueue_script( 'utils' );
+	if ( ! empty( $queued[ $hook_suffix] ) ) {
+		foreach( $queued[ $hook_suffix] as $pointer ) {
+			add_action( 'admin_print_footer_scripts', $pointer[ 'callback' ] );
+		}
 	}
+	wp_enqueue_style( 'wp-pointer' );
+	wp_enqueue_script( 'wp-pointer' );
+	wp_enqueue_script( 'utils' );
 }
 add_action( 'admin_enqueue_scripts', 'wp_pointer_enqueue' );
 
+/**
+ * Prints admin_bar pointer.
+ *
+ * @since 3.3.0
+ */
 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 this <a href="%s">ticket</a>.'), 'http://core.trac.wordpress.org/ticket/18197' ) . '</p>';
-	$pointer_content .= '<p>' . sprintf( ('P.S. You are looking at a new admin pointer. Chime in <a href="%s">here</a>.'), 'http://core.trac.wordpress.org/ticket/18693' ) . '</p>';
+	$pointer_content  = '<h3>' . __('The admin bar has been updated in WordPress 3.3.') . '</h3>'; 
+	$pointer_content .= '<p>' . sprintf( __('Have some feedback? Visit this <a href="%s">ticket</a>.'), 'http://core.trac.wordpress.org/ticket/18197' ) . '</p>'; 
+	$pointer_content .= '<p>' . sprintf( __('P.S. You are looking at a new admin pointer. Chime in <a href="%s">here</a>.'), 'http://core.trac.wordpress.org/ticket/18693' ) . '</p>'; 
 
-?>
-<script type="text/javascript">
-//<![CDATA[
-jQuery(document).ready( function($) {
-	$('#wpadminbar').pointer({
-		content: '<?php echo $pointer_content; ?>',
-		position: {
-			my: 'left top',
-			at: 'center bottom',
-			offset: '-25 0'
-		},
+?> 
+<script type="text/javascript"> 
+//<![CDATA[ 
+jQuery(document).ready( function($) { 
+	$('#wpadminbar').pointer({ 
+		content: '<?php echo $pointer_content; ?>', 
+		position: { 
+			my: 'left top', 
+			at: 'center bottom', 
+			offset: '-25 0' 
+		}, 
 		close: function() {
-			setUserSetting( 'p0', '1' );
-		}
-	}).pointer('open');
-});
-//]]>
-</script>
-<?php
+			$.post( ajaxurl, { 
+				pointer: 'wp330-admin-bar', 
+		//		_ajax_nonce: $('#_ajax_nonce').val(), 
+				action: 'dismiss-wp-pointer' 
+			}); 
+		} 
+	}).pointer('open'); 
+}); 
+//]]> 
+</script> 
+<?php 
 }
+
+/**
+ * Removes a pointer via AJAX.
+ *
+ * @since 3.3.0
+ */
+function dismiss_wp_pointer() {
+	$pointer = sanitize_key( $_POST[ 'pointer' ] ); 
+	
+	$hook_suffix = ( isset( $_POST[ 'page' ] ) ) ? sanitize_key( $_POST[ 'page' ] ): 'all';
+ 	
+	//	check_ajax_referer( 'dismiss-pointer_' . $pointer ); 
+ 	 
+	$queued = (array) get_user_meta( get_current_user_id(), 'queued_wp_pointers', true ); 
+	if ( empty( $queued[ $hook_suffix ][ $pointer ] ) ) 
+		die( '0' );
+	
+	unset( $queued[ $hook_suffix ][ $pointer ] );
+
+	update_user_meta( get_current_user_id(), 'queued_wp_pointers', $queued ); 
+	
+	die( '1' ); 
+	break; 
+}
+add_action( 'wp_ajax_dismiss-wp-pointer', 'dismiss_wp_pointer' );
+
+?>
