Index: wp-admin/admin-ajax.php
===================================================================
--- wp-admin/admin-ajax.php	(revision 21546)
+++ wp-admin/admin-ajax.php	(working copy)
@@ -50,7 +50,7 @@
 	'menu-locations-save', 'menu-quick-search', 'meta-box-order', 'get-permalink',
 	'sample-permalink', 'inline-save', 'inline-save-tax', 'find_posts', 'widgets-order',
 	'save-widget', 'set-post-thumbnail', 'date_format', 'time_format', 'wp-fullscreen-save-post',
-	'wp-remove-post-lock', 'dismiss-wp-pointer', 'upload-attachment',
+	'wp-remove-post-lock', 'dismiss-wp-pointer', 'upload-attachment', 'mce-gallery-preview',
 );
 
 // Register core Ajax calls.
Index: wp-admin/includes/ajax-actions.php
===================================================================
--- wp-admin/includes/ajax-actions.php	(revision 21546)
+++ wp-admin/includes/ajax-actions.php	(working copy)
@@ -50,6 +50,7 @@
 
 	wp_die( 0 );
 }
+
 function wp_ajax_ajax_tag_search() {
 	global $wpdb;
 
@@ -1801,3 +1802,21 @@
 	update_user_meta( get_current_user_id(), 'dismissed_wp_pointers', $dismissed );
 	wp_die( 1 );
 }
+
+function wp_ajax_mce_gallery_preview() {
+	if ( empty($_POST['post_ID']) || empty($_POST['shortcode']) )
+		wp_die( 0 );
+
+	$post_id = (int) $_POST['post_ID'];
+	if ( !current_user_can('edit_post', $post_id) )
+		wp_die('-1');
+
+	$shortcode_args = trim( str_replace('[gallery', '', $_POST['shortcode']), '[] //' );
+	$args = $shortcode_args ? shortcode_parse_atts( stripslashes($shortcode_args) ) : array();
+	$args['id'] = $post_id;
+	$args['mce_preview'] = true;
+
+	echo preg_replace('/[^a-z0-9_]+/', '', $_POST['mcediv_id']) . gallery_shortcode( $args );
+	wp_die();
+}
+
Index: wp-admin/includes/media.php
===================================================================
--- wp-admin/includes/media.php	(revision 21546)
+++ wp-admin/includes/media.php	(working copy)
@@ -470,10 +470,8 @@
 
 	if ( isset($_POST['insert-gallery']) || isset($_POST['update-gallery']) ) { ?>
 		<script type="text/javascript">
-		/* <![CDATA[ */
 		var win = window.dialogArguments || opener || parent || top;
 		win.tb_remove();
-		/* ]]> */
 		</script>
 		<?php
 		exit;
@@ -1630,7 +1628,6 @@
 ?>
 
 <script type="text/javascript">
-<!--
 jQuery(function($){
 	var preloaded = $(".media-item.preloaded");
 	if ( preloaded.length > 0 ) {
@@ -1638,7 +1635,6 @@
 		updateMediaForm();
 	}
 });
--->
 </script>
 <div id="sort-buttons" class="hide-if-no-js">
 <span>
@@ -1675,6 +1671,11 @@
 
 <div id="gallery-settings" style="display:none;">
 <div class="title"><?php _e('Gallery Settings'); ?></div>
+
+<p>(Temporary, for testing only. UI is changing)</p>
+<p><input type="text" style="width:60%;" id="shortcode" value="[gallery]"></p>
+
+<!--
 <table id="basic" class="describe"><tbody>
 	<tr>
 	<th scope="row" class="label">
@@ -1743,6 +1744,7 @@
 	</td>
 	</tr>
 </tbody></table>
+-->
 
 <p class="ml-submit">
 <input type="button" class="button" style="display:none;" onMouseDown="wpgallery.update();" name="insert-gallery" id="insert-gallery" value="<?php esc_attr_e( 'Insert gallery' ); ?>" />
Index: wp-admin/js/gallery.dev.js
===================================================================
--- wp-admin/js/gallery.dev.js	(revision 21546)
+++ wp-admin/js/gallery.dev.js	(working copy)
@@ -60,9 +60,8 @@
 		w = wpgallery.getWin();
 
 		$('#save-all, #gallery-settings').show();
-		if ( typeof w.tinyMCE != 'undefined' && w.tinyMCE.activeEditor && ! w.tinyMCE.activeEditor.isHidden() ) {
-			wpgallery.mcemode = true;
-			wpgallery.init();
+		if ( typeof w.tinymce != 'undefined' && w.tinymce.activeEditor && ! w.tinymce.activeEditor.isHidden() ) {
+			wpgallery.init(true);
 		} else {
 			$('#insert-gallery').show();
 		}
@@ -74,38 +73,48 @@
 /* gallery settings */
 var tinymce = null, tinyMCE, wpgallery;
 
+(function($){
 wpgallery = {
 	mcemode : false,
 	editor : {},
 	dom : {},
 	is_update : false,
 	el : {},
+	args : '',
 
-	I : function(e) {
-		return document.getElementById(e);
-	},
+	init: function(mcemode) {
+		var t = this, query, args = {}, i, val, w = t.getWin();
 
-	init: function() {
-		var t = this, li, q, i, it, w = t.getWin();
+		if ( mcemode )
+			t.mcemode = true;
+		else
+			return;
 
-		if ( ! t.mcemode ) return;
+		query = ('' + document.location.search).replace(/^\?/, '').split('&');
 
-		li = ('' + document.location.search).replace(/^\?/, '').split('&');
-		q = {};
-		for (i=0; i<li.length; i++) {
-			it = li[i].split('=');
-			q[unescape(it[0])] = unescape(it[1]);
+		for ( i in query ) {
+			if ( query[i] ) {
+				val = query[i].split('=');
+				args[decodeURIComponent(val[0])] = decodeURIComponent(val[1]);
+			}
 		}
 
-		if (q.mce_rdomain)
-			document.domain = q.mce_rdomain;
-
 		// Find window & API
 		tinymce = w.tinymce;
 		tinyMCE = w.tinyMCE;
 		t.editor = tinymce.EditorManager.activeEditor;
+		t.args = args;
+		
+		// temp, UI is changing
+		if ( args.shortcode ) {
+			t.is_update = true;
+			$('#update-gallery').show();
+			$('#shortcode').val( args.shortcode );
+		} else {
+			$('#insert-gallery').show();
+		}
 
-		t.setup();
+	//	t.setup();
 	},
 
 	getWin : function() {
@@ -113,87 +122,95 @@
 	},
 
 	setup : function() {
-		var t = this, a, ed = t.editor, g, columns, link, order, orderby;
-		if ( ! t.mcemode ) return;
+		var t = this, shortcode = t.args.shortcode, sh, a, ed = t.editor, g, columns, link, order, orderby, val;
+		
+		if ( ! t.mcemode )
+			return;
 
-		t.el = ed.selection.getNode();
+		if ( shortcode ) {
+			$('#update-gallery').show();
+			t.is_update = true;
 
-		if ( t.el.nodeName != 'IMG' || ! ed.dom.hasClass(t.el, 'wpGallery') ) {
-			if ( (g = ed.dom.select('img.wpGallery')) && g[0] ) {
-				t.el = g[0];
-			} else {
-				if ( getUserSetting('galfile') == '1' ) t.I('linkto-file').checked = "checked";
-				if ( getUserSetting('galdesc') == '1' ) t.I('order-desc').checked = "checked";
-				if ( getUserSetting('galcols') ) t.I('columns').value = getUserSetting('galcols');
-				if ( getUserSetting('galord') ) t.I('orderby').value = getUserSetting('galord');
-				jQuery('#insert-gallery').show();
-				return;
-			}
+			columns = shortcode.match(/columns=['"]([0-9]+)['"]/);
+			link = shortcode.match(/link=['"]([^'"]+)['"]/i);
+			order = shortcode.match(/order=['"]([^'"]+)['"]/i);
+			orderby = shortcode.match(/orderby=['"]([^'"]+)['"]/i);
+
+			// console.log( columns );console.log( link );console.log( order );console.log( orderby );
+		} else {
+			$('#insert-gallery').show();
 		}
+		
+		// If inserting new gallery, use the user states, if editing a gallery, use defaults + shortcode
+		if ( ( ! t.is_update && getUserSetting('galfile') ) || ( link && link[1] ) )
+			$('#linkto-file').prop('checked', true);
 
-		a = ed.dom.getAttrib(t.el, 'title');
-		a = ed.dom.decode(a);
+		if ( ( ! t.is_update && getUserSetting('galdesc') ) || ( order && order[1] ) )
+			$('#order-desc').prop('checked', true);
 
-		if ( a ) {
-			jQuery('#update-gallery').show();
-			t.is_update = true;
+		if ( columns && columns[1] )
+			$('#columns').val( columns[1] );
+		else if ( ! t.is_update && ( val = getUserSetting('galcols') ) )
+			$('#columns').val( val );
 
-			columns = a.match(/columns=['"]([0-9]+)['"]/);
-			link = a.match(/link=['"]([^'"]+)['"]/i);
-			order = a.match(/order=['"]([^'"]+)['"]/i);
-			orderby = a.match(/orderby=['"]([^'"]+)['"]/i);
-
-			if ( link && link[1] ) t.I('linkto-file').checked = "checked";
-			if ( order && order[1] ) t.I('order-desc').checked = "checked";
-			if ( columns && columns[1] ) t.I('columns').value = ''+columns[1];
-			if ( orderby && orderby[1] ) t.I('orderby').value = orderby[1];
-		} else {
-			jQuery('#insert-gallery').show();
-		}
+		if ( orderby && orderby[1] )
+			$('#orderby').val( orderby[1] );
+		else if ( ! t.is_update && ( val = getUserSetting('galord') ) )
+			$('#orderby').val( val );
 	},
 
 	update : function() {
-		var t = this, ed = t.editor, all = '', s;
+		var t = this, ed = t.editor, args = t.args, div, new_div, new_div_id, sh = $('#shortcode').val() || '[gallery]'; // '[gallery'+t.getSettings()+']';
 
 		if ( ! t.mcemode || ! t.is_update ) {
-			s = '[gallery'+t.getSettings()+']';
-			t.getWin().send_to_editor(s);
+			t.getWin().send_to_editor(sh);
 			return;
 		}
 
-		if (t.el.nodeName != 'IMG') return;
+		div = ed.dom.select('#'+args.div_id);
 
-		all = ed.dom.decode(ed.dom.getAttrib(t.el, 'title'));
-		all = all.replace(/\s*(order|link|columns|orderby)=['"]([^'"]+)['"]/gi, '');
-		all += t.getSettings();
+		if ( div ) {
+			new_div = ed.dom.create( 'div', {}, ed.wpSetGalleryPreview(sh) );
+			new_div = new_div.firstChild;
+			ed.dom.replace( new_div, div );
+		}
 
-		ed.dom.setAttrib(t.el, 'title', all);
 		t.getWin().tb_remove();
 	},
 
 	getSettings : function() {
-		var I = this.I, s = '';
+		var s = '', columns = $('#columns').val(), orderby = $('#orderby').val();
 
-		if ( I('linkto-file').checked ) {
+		if ( $('#linkto-file').prop('checked') ) {
 			s += ' link="file"';
 			setUserSetting('galfile', '1');
+		} else {
+			deleteUserSetting('galfile');
 		}
 
-		if ( I('order-desc').checked ) {
+		if ( $('#order-desc').prop('checked') ) {
 			s += ' order="DESC"';
 			setUserSetting('galdesc', '1');
+		} else {
+			deleteUserSetting('galdesc');
 		}
 
-		if ( I('columns').value != 3 ) {
-			s += ' columns="'+I('columns').value+'"';
-			setUserSetting('galcols', I('columns').value);
+		if ( columns != 3 ) {
+			s += ' columns="'+columns+'"';
+			setUserSetting('galcols', columns);
+		} else {
+			deleteUserSetting('galcols');
 		}
 
-		if ( I('orderby').value != 'menu_order' ) {
-			s += ' orderby="'+I('orderby').value+'"';
-			setUserSetting('galord', I('orderby').value);
+		if ( orderby != 'menu_order' ) {
+			s += ' orderby="'+orderby+'"';
+			setUserSetting('galord', orderby);
+		} else {
+			deleteUserSetting('galord');
 		}
 
 		return s;
 	}
 };
+})(jQuery);
+
Index: wp-includes/js/tinymce/plugins/wpgallery/editor_plugin_src.js
===================================================================
--- wp-includes/js/tinymce/plugins/wpgallery/editor_plugin_src.js	(revision 21546)
+++ wp-includes/js/tinymce/plugins/wpgallery/editor_plugin_src.js	(working copy)
@@ -1,67 +1,176 @@
 
 (function() {
 	tinymce.create('tinymce.plugins.wpGallery', {
+		sh : {i: 0},
 
 		init : function(ed, url) {
-			var t = this;
+			var t = this, target;
 
+			t.ed = ed;
 			t.url = url;
 			t._createButtons();
 
 			// Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('...');
 			ed.addCommand('WP_Gallery', function() {
-				var el = ed.selection.getNode(), post_id, vp = tinymce.DOM.getViewPort(),
-					H = vp.h - 80, W = ( 640 < vp.w ) ? 640 : vp.w;
+				var shortcode, div_id, q_string, post_id, vp = tinymce.DOM.getViewPort(), H = vp.h - 80, W = ( 640 < vp.w ) ? 640 : vp.w;
 
-				if ( el.nodeName != 'IMG' ) return;
-				if ( ed.dom.getAttrib(el, 'class').indexOf('wpGallery') == -1 )	return;
+				if ( !target )
+					return;
 
-				post_id = tinymce.DOM.get('post_ID').value;
-				tb_show('', tinymce.documentBaseURL + 'media-upload.php?post_id='+post_id+'&tab=gallery&TB_iframe=true&width='+W+'&height='+H);
+				div_id = target.id;
+				shortcode = ed.dom.getAttrib( target, 'data-wp-gallery-args' ); // already urlencoded
+				if ( !shortcode || !div_id )
+					return;
 
+				post_id = document.getElementById('post_ID');
+				post_id = post_id ? post_id.value : 0;
+				q_string = 'post_id='+post_id+'&tab=gallery&shortcode='+shortcode+'&div_id='+encodeURIComponent(div_id)+'&TB_iframe=true&width='+W+'&height='+H;
+
+				tb_show('', tinymce.documentBaseURL + 'media-upload.php?'+q_string);
+
 				tinymce.DOM.setStyle( ['TB_overlay','TB_window','TB_load'], 'z-index', '999999' );
+				target = null;
 			});
 
+			ed.addCommand('WP_Gallery_Delete', function() {
+				if ( !target )
+					return;
+
+				ed.dom.remove(target);
+			});
+
 			ed.onMouseDown.add(function(ed, e) {
-				if ( e.target.nodeName == 'IMG' && ed.dom.hasClass(e.target, 'wpGallery') )
-					ed.plugins.wordpress._showButtons(e.target, 'wp_gallerybtns');
+				target = ed.dom.getParent(e.target, 'div.wp-gallery-preview');
+
+				if ( target )
+					ed.plugins.wordpress._showButtons(target, 'wp_gallerybtns');
 			});
 
 			ed.onBeforeSetContent.add(function(ed, o) {
-				o.content = t._do_gallery(o.content);
+				o.content = t._do_gallery(o);
 			});
 
 			ed.onPostProcess.add(function(ed, o) {
-				if (o.get)
-					o.content = t._get_gallery(o.content);
+				if ( ( o.get || o.save ) && o.content.indexOf('data-wp-gallery-args') > -1 ) {
+					o.content = o.content.replace(/<div[^>]+data-wp-gallery-args="([^"]+)"[\s\S]+?<\/div><div class="wp-gallery-end">.?<\/div><\/div>/g, function(a, b){
+						return '<p>'+decodeURIComponent(b)+'</p>';
+					});
+				}
 			});
-		},
 
-		_do_gallery : function(co) {
-			return co.replace(/\[gallery([^\]]*)\]/g, function(a,b){
-				return '<img src="'+tinymce.baseURL+'/plugins/wpgallery/img/t.gif" class="wpGallery mceItem" title="gallery'+tinymce.DOM.encode(b)+'" />';
+			// Chrome doesn't understand :focus in contentEditable, add/remove a css class with JS :(
+			ed.onMouseDown.add(function(ed, e) {
+				ed.dom.removeClass(ed.dom.select('div.wp-gallery-block'), 'focused');
+				if ( ed.dom.hasClass(e.target, 'wp-gallery-block') )
+					ed.dom.addClass(e.target, 'focused');
 			});
+
+			ed.wpSetGalleryPreview = function(content) {
+				return t._do_gallery(content);
+			}
 		},
 
-		_get_gallery : function(co) {
+		_do_gallery : function(args) {
+			var self = this, ed = self.ed, dom = ed.dom, xhr_args, data, content, post_id, sh = self.sh, isNotDirty;
 
-			function getAttr(s, n) {
-				n = new RegExp(n + '=\"([^\"]+)\"', 'g').exec(s);
-				return n ? tinymce.DOM.decode(n[1]) : '';
+			if ( typeof(args) == 'object' ) {
+				content = args.content;
+				if ( args.initial )
+					isNotDirty = true;
+			} else {
+				content = args;
+			}
+
+			if ( content.indexOf('[gallery') == -1 )
+				return content;
+
+			// post_ID is a hidden input field in edit-form-advanced.php
+			post_id = document.getElementById('post_ID');
+			if ( post_id )
+				post_id = post_id.value;
+			else
+				return content;
+
+			xhr_args = {
+				url: ajaxurl,
+				type: 'POST',
+				content_type: 'application/x-www-form-urlencoded',
+				success: function(r) {
+					var shortcode, div_id, new_id;
+
+					div_id = /^wp_gallery_shortcode_\d+/.exec(r);
+					shortcode = div_id && sh[div_id] ? sh[div_id] : '';
+
+					if ( !div_id || !shortcode ) {
+						ed.setProgressState(false);
+						return;
+					}
+
+					div_id = div_id.toString();
+					r = r.replace(div_id, '');
+					// if there are any " even double entity encoded, switching Visual -> Text and back breaks it
+					shortcode = encodeURIComponent( shortcode );
+					div = ed.dom.select('div#'+div_id);
+
+					if ( !div ) {
+						ed.setProgressState(false);
+						return;
+					}
+
+					ed.undoManager.data.pop()
+					new_id = 'wp_gallery_preview_' + div_id.replace(/[^0-9]+/, '');
+					dom.setAttribs( div, {
+						id: new_id,
+						'data-wp-gallery-args': shortcode
+					});
+					dom.addClass( div, 'wp-gallery-preview' ); // mceNonEditable
+					dom.setHTML( div, '<div class="wp-gallery-block"><br></div>'+r+'<div class="wp-gallery-end">\uFEFF</div>' );
+					dom.setAttrib( dom.select('div.wp-gallery-block, div.wp-gallery-preview'), 'contenteditable', false );
+
+					ed.setProgressState(false);
+					ed.execCommand('mceRepaint');
+					ed.undoManager.add();
+
+					if ( isNotDirty )
+						ed.isNotDirty = true;
+				},
+				error: function() {
+					ed.setProgressState(false);
+				}
 			};
 
-			return co.replace(/(?:<p[^>]*>)*(<img[^>]+>)(?:<\/p>)*/g, function(a,im) {
-				var cls = getAttr(im, 'class');
+			data = {
+				action: 'mce-gallery-preview',
+				post_ID: post_id
+			};
 
-				if ( cls.indexOf('wpGallery') != -1 )
-					return '<p>['+tinymce.trim(getAttr(im, 'title'))+']</p>';
+			ed.setProgressState(true);
 
-				return a;
+			return content.replace(/(?:<p>\s*)?(\[gallery[^\]]*\])(?:\s*<\/p>)?/g, function(a, shortcode){
+				var val, div_id, str = '';
+
+				sh.i++;
+				div_id = 'wp_gallery_shortcode_' + sh.i;
+				data['mcediv_id'] = div_id;
+				sh[div_id] = shortcode;
+				data['shortcode'] = shortcode;
+
+				for ( val in data ) {
+					if ( str )
+						str += '&';
+
+					str += val + '=' + encodeURIComponent( data[val] );
+				}
+
+				xhr_args['data'] = str;
+				tinymce.util.XHR.send( xhr_args );
+
+				return '<div id="'+div_id+'">' + shortcode + '</div>';
 			});
 		},
 
 		_createButtons : function() {
-			var t = this, ed = tinyMCE.activeEditor, DOM = tinymce.DOM, editButton, dellButton;
+			var t = this, ed = t.ed, DOM = tinymce.DOM, editButton, dellButton;
 
 			DOM.remove('wp_gallerybtns');
 
@@ -79,9 +188,9 @@
 			});
 
 			tinymce.dom.Event.add(editButton, 'mousedown', function(e) {
-				var ed = tinyMCE.activeEditor;
 				ed.windowManager.bookmark = ed.selection.getBookmark('simple');
 				ed.execCommand("WP_Gallery");
+				ed.dom.events.cancel(e);
 			});
 
 			dellButton = DOM.add('wp_gallerybtns', 'img', {
@@ -93,14 +202,9 @@
 			});
 
 			tinymce.dom.Event.add(dellButton, 'mousedown', function(e) {
-				var ed = tinyMCE.activeEditor, el = ed.selection.getNode();
-
-				if ( el.nodeName == 'IMG' && ed.dom.hasClass(el, 'wpGallery') ) {
-					ed.dom.remove(el);
-
-					ed.execCommand('mceRepaint');
-					return false;
-				}
+				ed.execCommand('WP_Gallery_Delete');
+				ed.execCommand('mceRepaint');
+				ed.dom.events.cancel(e);
 			});
 		},
 
Index: wp-includes/js/tinymce/themes/advanced/skins/wp_theme/content.css
===================================================================
--- wp-includes/js/tinymce/themes/advanced/skins/wp_theme/content.css	(revision 21546)
+++ wp-includes/js/tinymce/themes/advanced/skins/wp_theme/content.css	(working copy)
@@ -141,3 +141,109 @@
 	height: 250px;
 }
 
+/* Gallery preview */
+
+div.wp-gallery-block {
+	height: 100%;
+	width: 100%;
+	position: absolute;
+	background: #fff;
+	opacity: 0.01;
+	filter: alpha(opacity=1);
+	top: 0;
+	left: 0;
+	bottom: 0;
+	right: 0;
+	z-index: 5;
+}
+
+div.wp-gallery-block.focused {
+	background-color: #000;
+	filter: alpha(opacity=25);
+	opacity: 0.25;
+}
+
+div.wp-gallery-preview {
+	margin: 10px auto;
+	position: relative;
+	-ms-user-select: none;
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	user-select: none;
+}
+
+div.wp-gallery-preview .wp-gallery-end {
+	height: 1em;
+	margin-top: -1em;
+}
+
+div.wp-gallery-preview .gallery-icon {
+	margin: 0;
+}
+
+div.wp-gallery-preview .gallery-icon img {
+	display: block;
+	margin: 0 auto;
+	padding: 0;
+	max-width: 90%;
+	height: auto;
+	border: 0;
+}
+
+div.wp-gallery-preview dd.gallery-caption {
+	margin: 0 6%;
+	font-size: 12px;
+}
+
+div.wp-gallery-preview div.gallery {
+	clear: both;
+}
+
+div.wp-gallery-preview div.gallery dl.gallery-item {
+	float: left;
+	margin: 10px 0;
+	padding: 0;
+}
+
+div.wp-gallery-preview div.gallery-columns-1 dl.gallery-item {
+	width: 99%;
+}
+
+div.wp-gallery-preview div.gallery-columns-2 dl.gallery-item {
+	width: 49.5%;
+}
+
+div.wp-gallery-preview div.gallery-columns-3 dl.gallery-item {
+	width: 33%;
+}
+
+div.wp-gallery-preview div.gallery-columns-4 dl.gallery-item {
+	width: 24.75%;
+}
+
+div.wp-gallery-preview div.gallery-columns-5 dl.gallery-item {
+	width: 19.8%;
+}
+
+div.wp-gallery-preview div.gallery-columns-6 dl.gallery-item {
+	width: 16.5%;
+}
+
+div.wp-gallery-preview div.gallery-columns-7 dl.gallery-item {
+	width: 14.2%;
+}
+
+div.wp-gallery-preview div.gallery-columns-8 dl.gallery-item {
+	width: 12.45%;
+}
+
+div.wp-gallery-preview div.gallery-columns-9 dl.gallery-item {
+	width: 11.1%;
+}
+
+div.wp-gallery-preview div.gallery-columns-10 dl.gallery-item {
+	width: 9.99%;
+}
+
+
+
Index: wp-includes/media.php
===================================================================
--- wp-includes/media.php	(revision 21546)
+++ wp-includes/media.php	(working copy)
@@ -780,10 +780,12 @@
 	static $instance = 0;
 	$instance++;
 
-	// Allow plugins/themes to override the default gallery template.
-	$output = apply_filters('post_gallery', '', $attr);
-	if ( $output != '' )
-		return $output;
+	// Allow plugins/themes to override the default gallery template if not previewing.
+	if ( !isset($attr['mce_preview']) ) {
+		$output = apply_filters('post_gallery', '', $attr);
+		if ( $output != '' )
+			return $output;
+	}
 
 	// We're trusting author input, so let's at least make sure it looks like a valid orderby statement
 	if ( isset( $attr['orderby'] ) ) {
@@ -792,20 +794,23 @@
 			unset( $attr['orderby'] );
 	}
 
-	extract(shortcode_atts(array(
+	$attr = shortcode_atts( array(
 		'order'      => 'ASC',
 		'orderby'    => 'menu_order ID',
-		'id'         => $post->ID,
+		'id'         => isset($post) ? $post->ID : 0,
 		'itemtag'    => 'dl',
 		'icontag'    => 'dt',
 		'captiontag' => 'dd',
 		'columns'    => 3,
 		'size'       => 'thumbnail',
 		'include'    => '',
-		'exclude'    => ''
-	), $attr));
+		'exclude'    => '',
+		'mce_preview' => false,
+	), $attr );
 
+	extract( $attr, EXTR_SKIP );
 	$id = intval($id);
+
 	if ( 'RAND' == $order )
 		$orderby = 'none';
 
@@ -817,10 +822,10 @@
 		foreach ( $_attachments as $key => $val ) {
 			$attachments[$val->ID] = $_attachments[$key];
 		}
-	} elseif ( !empty($exclude) ) {
+	} elseif ( !empty($exclude) && $id ) {
 		$exclude = preg_replace( '/[^0-9,]+/', '', $exclude );
 		$attachments = get_children( array('post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
-	} else {
+	} elseif ( $id ) {
 		$attachments = get_children( array('post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
 	}
 
@@ -834,8 +839,15 @@
 		return $output;
 	}
 
-	$itemtag = tag_escape($itemtag);
-	$captiontag = tag_escape($captiontag);
+	if ( $mce_preview ) {
+		$itemtag = 'dl';
+		$icontag = 'dt';
+		$captiontag = 'dd';
+	} else {
+		$itemtag = tag_escape($itemtag);
+		$captiontag = tag_escape($captiontag);
+	}
+
 	$columns = intval($columns);
 	$itemwidth = $columns > 0 ? floor(100/$columns) : 100;
 	$float = is_rtl() ? 'right' : 'left';
@@ -864,33 +876,40 @@
 		</style>
 		<!-- see gallery_shortcode() in wp-includes/media.php -->";
 	$size_class = sanitize_html_class( $size );
-	$gallery_div = "<div id='$selector' class='gallery galleryid-{$id} gallery-columns-{$columns} gallery-size-{$size_class}'>";
-	$output = apply_filters( 'gallery_style', $gallery_style . "\n\t\t" . $gallery_div );
+	$wrapper_id = $mce_preview ? '' : " id='$selector'";
+	$gallery_div = "<div{$wrapper_id} class='gallery galleryid-{$id} gallery-columns-{$columns} gallery-size-{$size_class}'>";
+	$itemclass = 'gallery-item';
+	$clear_break = "<br style='clear: both' />";
 
+	if ( $mce_preview ) {
+		$output = $gallery_div;
+	} else {
+		$output = apply_filters( 'gallery_style', $gallery_style . "\n\t\t" . $gallery_div );
+	}
+
 	$i = 0;
 	foreach ( $attachments as $id => $attachment ) {
 		$link = isset($attr['link']) && 'file' == $attr['link'] ? wp_get_attachment_link($id, $size, false, false) : wp_get_attachment_link($id, $size, true, false);
 
-		$output .= "<{$itemtag} class='gallery-item'>";
-		$output .= "
-			<{$icontag} class='gallery-icon'>
-				$link
-			</{$icontag}>";
+		$output .= "\n<{$itemtag} class='$itemclass'><{$icontag} class='gallery-icon'>$link</{$icontag}>";
+		
 		if ( $captiontag && trim($attachment->post_excerpt) ) {
-			$output .= "
-				<{$captiontag} class='wp-caption-text gallery-caption'>
-				" . wptexturize($attachment->post_excerpt) . "
-				</{$captiontag}>";
+			$output .= "<{$captiontag} class='wp-caption-text gallery-caption'>"
+				. wptexturize($attachment->post_excerpt) .
+				"</{$captiontag}>";
 		}
+
 		$output .= "</{$itemtag}>";
+
 		if ( $columns > 0 && ++$i % $columns == 0 )
-			$output .= '<br style="clear: both" />';
+			$output .= $clear_break;
 	}
 
-	$output .= "
-			<br style='clear: both;' />
-		</div>\n";
+	if ( substr( $output, -strlen($clear_break) ) != $clear_break )
+		$output .= $clear_break;
 
+	$output .= "</div>\n";
+
 	return $output;
 }
 
