Index: wp-admin/admin-ajax.php
===================================================================
--- wp-admin/admin-ajax.php	(revision 21514)
+++ 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 21514)
+++ 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,38 @@
 	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) )
+		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'] = preg_replace('/[^a-z0-9_]+/', '', $_POST['mcediv_id']);
+
+	
+	
+	//var_dump($args);
+
+	
+	echo gallery_shortcode( $args );
+	die;
+
+	// allow only some args?
+	$order = !empty($args['order']) && 'desc' == strtolower($args['order']) ? 'DESC' : 'ASC';
+	$orderby = !empty($args['orderby']) ? preg_replace('/[^a-zA-Z_ ]+/', '', $args['orderby']) : 'menu_order ID';
+	$columns = !empty($args['columns']) ? (int) $args['columns'] : 3;
+	$size = !empty($args['size']) && in_array( $args['size'], array('thumbnail', 'medium', 'large', 'full' ), true ) ? $args['size'] : 'thumbnail';
+	$include = !empty($args['include']) ? preg_replace('/[^0-9,]+/', '', $args['include']) : '';
+	$exclude = !empty($args['exclude']) ? preg_replace('/[^0-9,]+/', '', $args['exclude']) : '';
+	$mce_preview = true;
+	
+	echo gallery_shortcode( compact( 'id', 'order', 'orderby', 'columns', 'size', 'include', 'exclude', 'mce_preview' ) );
+	die;
+}
+
Index: wp-admin/includes/media.php
===================================================================
--- wp-admin/includes/media.php	(revision 21514)
+++ 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>
Index: wp-admin/js/gallery.dev.js
===================================================================
--- wp-admin/js/gallery.dev.js	(revision 21514)
+++ 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,36 +73,37 @@
 /* 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;
 
 		t.setup();
 	},
@@ -113,87 +113,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 = '[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/class-wp-editor.php
===================================================================
--- wp-includes/class-wp-editor.php	(revision 21514)
+++ wp-includes/class-wp-editor.php	(working copy)
@@ -167,7 +167,7 @@
 				self::$baseurl = includes_url('js/tinymce');
 				self::$mce_locale = $mce_locale = ( '' == get_locale() ) ? 'en' : strtolower( substr(get_locale(), 0, 2) ); // only ISO 639-1
 				$no_captions = (bool) apply_filters( 'disable_captions', '' );
-				$plugins = array( 'inlinepopups', 'spellchecker', 'tabfocus', 'paste', 'media', 'fullscreen', 'wordpress', 'wpeditimage', 'wpgallery', 'wplink', 'wpdialogs' );
+				$plugins = array( 'inlinepopups', 'spellchecker', 'tabfocus', 'paste', 'media', 'fullscreen', 'noneditable', 'wordpress', 'wpeditimage', 'wpgallery', 'wplink', 'wpdialogs' );
 				$first_run = true;
 				$ext_plugins = '';
 
Index: wp-includes/css/editor.dev.css
===================================================================
--- wp-includes/css/editor.dev.css	(revision 21514)
+++ wp-includes/css/editor.dev.css	(working copy)
@@ -102,11 +102,12 @@
 	font-size: 12px;
 	line-height: 16px;
 	padding: 0 0 0 8px;
-	overflow: visible;
+	overflow: hidden;
 	height: 20px;
 	border-top: 1px solid #dfdfdf;
 	color: #000;
 	background-color: #f5f5f5;
+	position: relative;
 }
 
 .rtl .wp_themeSkin .mceStatusbar {
@@ -120,6 +121,9 @@
 .wp_themeSkin .mceStatusbar div {
 	float: left;
 	padding: 2px;
+	overflow: hidden;
+    position: absolute;
+    width: 97%;
 }
 
 .rtl .wp_themeSkin .mceStatusbar div {
Index: wp-includes/js/tinymce/plugins/noneditable/editor_plugin.js
===================================================================
--- wp-includes/js/tinymce/plugins/noneditable/editor_plugin.js	(revision 0)
+++ wp-includes/js/tinymce/plugins/noneditable/editor_plugin.js	(working copy)
@@ -0,0 +1 @@
+(function(){var c=tinymce.dom.TreeWalker;var a="contenteditable",d="data-mce-"+a;var e=tinymce.VK;function b(n){var j=n.dom,p=n.selection,r,o="mce_noneditablecaret";r=tinymce.isGecko?"\u200B":"\uFEFF";function m(t){var s;if(t.nodeType===1){s=t.getAttribute(d);if(s&&s!=="inherit"){return s}s=t.contentEditable;if(s!=="inherit"){return s}}return null}function g(s){var t;while(s){t=m(s);if(t){return t==="false"?s:null}s=s.parentNode}}function l(s){while(s){if(s.id===o){return s}s=s.parentNode}}function k(s){var t;if(s){t=new c(s,s);for(s=t.current();s;s=t.next()){if(s.nodeType===3){return s}}}}function f(v,u){var s,t;if(m(v)==="false"){if(j.isBlock(v)){p.select(v);return}}t=j.createRng();if(m(v)==="true"){if(!v.firstChild){v.appendChild(n.getDoc().createTextNode("\u00a0"))}v=v.firstChild;u=true}s=j.create("span",{id:o,"data-mce-bogus":true},r);if(u){v.parentNode.insertBefore(s,v)}else{j.insertAfter(s,v)}t.setStart(s.firstChild,1);t.collapse(true);p.setRng(t);return s}function i(s){var v,t,u;if(s){rng=p.getRng(true);rng.setStartBefore(s);rng.setEndBefore(s);v=k(s);if(v&&v.nodeValue.charAt(0)==r){v=v.deleteData(0,1)}j.remove(s,true);p.setRng(rng)}else{t=l(p.getStart());while((s=j.get(o))&&s!==u){if(t!==s){v=k(s);if(v&&v.nodeValue.charAt(0)==r){v=v.deleteData(0,1)}j.remove(s,true)}u=s}}}function q(){var s,w,u,t,v;function x(B,D){var A,F,E,C,z;A=t.startContainer;F=t.startOffset;if(A.nodeType==3){z=A.nodeValue.length;if((F>0&&F<z)||(D?F==z:F==0)){return}}else{if(F<A.childNodes.length){var G=!D&&F>0?F-1:F;A=A.childNodes[G];if(A.hasChildNodes()){A=A.firstChild}}else{return !D?B:null}}E=new c(A,B);while(C=E[D?"prev":"next"]()){if(C.nodeType===3&&C.nodeValue.length>0){return}else{if(m(C)==="true"){return C}}}return B}i();u=p.isCollapsed();s=g(p.getStart());w=g(p.getEnd());if(s||w){t=p.getRng(true);if(u){s=s||w;var y=p.getStart();if(v=x(s,true)){f(v,true)}else{if(v=x(s,false)){f(v,false)}else{p.select(s)}}}else{t=p.getRng(true);if(s){t.setStartBefore(s)}if(w){t.setEndAfter(w)}p.setRng(t)}}}function h(z,B){var F=B.keyCode,x,C,D,v;function u(H,G){while(H=H[G?"previousSibling":"nextSibling"]){if(H.nodeType!==3||H.nodeValue.length>0){return H}}}function y(G,H){p.select(G);p.collapse(H)}function t(K){var J,I,M,H;function G(O){var N=I;while(N){if(N===O){return}N=N.parentNode}j.remove(O);q()}function L(){var O,P,N=z.schema.getNonEmptyElements();P=new tinymce.dom.TreeWalker(I,z.getBody());while(O=(K?P.prev():P.next())){if(N[O.nodeName.toLowerCase()]){break}if(O.nodeType===3&&tinymce.trim(O.nodeValue).length>0){break}if(m(O)==="false"){G(O);return true}}if(g(O)){return true}return false}if(p.isCollapsed()){J=p.getRng(true);I=J.startContainer;M=J.startOffset;I=l(I)||I;if(H=g(I)){G(H);return false}if(I.nodeType==3&&(K?M>0:M<I.nodeValue.length)){return true}if(I.nodeType==1){I=I.childNodes[M]||I}if(L()){return false}}return true}D=p.getStart();v=p.getEnd();x=g(D)||g(v);if(x&&(F<112||F>124)&&F!=e.DELETE&&F!=e.BACKSPACE){if((tinymce.isMac?B.metaKey:B.ctrlKey)&&(F==67||F==88||F==86)){return}B.preventDefault();if(F==e.LEFT||F==e.RIGHT){var w=F==e.LEFT;if(z.dom.isBlock(x)){var A=w?x.previousSibling:x.nextSibling;var s=new c(A,A);var E=w?s.prev():s.next();y(E,!w)}else{y(x,w)}}}else{if(F==e.LEFT||F==e.RIGHT||F==e.BACKSPACE||F==e.DELETE){C=l(D);if(C){if(F==e.LEFT||F==e.BACKSPACE){x=u(C,true);if(x&&m(x)==="false"){B.preventDefault();if(F==e.LEFT){y(x,true)}else{j.remove(x);return}}else{i(C)}}if(F==e.RIGHT||F==e.DELETE){x=u(C);if(x&&m(x)==="false"){B.preventDefault();if(F==e.RIGHT){y(x,false)}else{j.remove(x);return}}else{i(C)}}}if((F==e.BACKSPACE||F==e.DELETE)&&!t(F==e.BACKSPACE)){B.preventDefault();return false}}}}n.onMouseDown.addToTop(function(s,u){var t=s.selection.getNode();if(m(t)==="false"&&t==u.target){q()}});n.onMouseUp.addToTop(q);n.onKeyDown.addToTop(h);n.onKeyUp.addToTop(q)}tinymce.create("tinymce.plugins.NonEditablePlugin",{init:function(i,k){var h,g,j;function f(m,n){var o=j.length,p=n.content,l=tinymce.trim(g);if(n.format=="raw"){return}while(o--){p=p.replace(j[o],function(s){var r=arguments,q=r[r.length-2];if(q>0&&p.charAt(q-1)=='"'){return s}return'<span class="'+l+'" data-mce-content="'+m.dom.encode(r[0])+'">'+m.dom.encode(typeof(r[1])==="string"?r[1]:r[0])+"</span>"})}n.content=p}h=" "+tinymce.trim(i.getParam("noneditable_editable_class","mceEditable"))+" ";g=" "+tinymce.trim(i.getParam("noneditable_noneditable_class","mceNonEditable"))+" ";j=i.getParam("noneditable_regexp");if(j&&!j.length){j=[j]}i.onPreInit.add(function(){b(i);if(j){i.selection.onBeforeSetContent.add(f);i.onBeforeSetContent.add(f)}i.parser.addAttributeFilter("class",function(l){var m=l.length,n,o;while(m--){o=l[m];n=" "+o.attr("class")+" ";if(n.indexOf(h)!==-1){o.attr(d,"true")}else{if(n.indexOf(g)!==-1){o.attr(d,"false")}}}});i.serializer.addAttributeFilter(d,function(l,m){var n=l.length,o;while(n--){o=l[n];if(j&&o.attr("data-mce-content")){o.name="#text";o.type=3;o.raw=true;o.value=o.attr("data-mce-content")}else{o.attr(a,null);o.attr(d,null)}}});i.parser.addAttributeFilter(a,function(l,m){var n=l.length,o;while(n--){o=l[n];o.attr(d,o.attr(a));o.attr(a,null)}})})},getInfo:function(){return{longname:"Non editable elements",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/noneditable",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("noneditable",tinymce.plugins.NonEditablePlugin)})();
\ No newline at end of file
Index: wp-includes/js/tinymce/plugins/noneditable/editor_plugin.js
===================================================================
--- wp-includes/js/tinymce/plugins/noneditable/editor_plugin.js	(revision 0)
+++ wp-includes/js/tinymce/plugins/noneditable/editor_plugin.js	(working copy)

Property changes on: wp-includes/js/tinymce/plugins/noneditable/editor_plugin.js
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: wp-includes/js/tinymce/plugins/noneditable/editor_plugin_src.js
===================================================================
--- wp-includes/js/tinymce/plugins/noneditable/editor_plugin_src.js	(revision 0)
+++ wp-includes/js/tinymce/plugins/noneditable/editor_plugin_src.js	(working copy)
@@ -0,0 +1,540 @@
+/**
+ * editor_plugin_src.js
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under LGPL License.
+ *
+ * License: http://tinymce.moxiecode.com/license
+ * Contributing: http://tinymce.moxiecode.com/contributing
+ */
+
+(function() {
+	var TreeWalker = tinymce.dom.TreeWalker;
+	var externalName = 'contenteditable', internalName = 'data-mce-' + externalName;
+	var VK = tinymce.VK;
+
+	function handleContentEditableSelection(ed) {
+		var dom = ed.dom, selection = ed.selection, invisibleChar, caretContainerId = 'mce_noneditablecaret';
+
+		// Setup invisible character use zero width space on Gecko since it doesn't change the height of the container
+		invisibleChar = '\uFEFF';
+
+		// Returns the content editable state of a node "true/false" or null
+		function getContentEditable(node) {
+			var contentEditable;
+
+			// Ignore non elements
+			if (node.nodeType === 1) {
+				// Check for fake content editable
+				contentEditable = node.getAttribute(internalName);
+				if (contentEditable && contentEditable !== "inherit") {
+					return contentEditable;
+				}
+
+				// Check for real content editable
+				contentEditable = node.contentEditable;
+				if (contentEditable !== "inherit") {
+					return contentEditable;
+				}
+			}
+
+			return null;
+		};
+
+		// Returns the noneditable parent or null if there is a editable before it or if it wasn't found
+		function getNonEditableParent(node) {
+			var state;
+
+			while (node) {
+				state = getContentEditable(node);
+				if (state) {
+					return state  === "false" ? node : null;
+				}
+
+				node = node.parentNode;
+			}
+		};
+
+		// Get caret container parent for the specified node
+		function getParentCaretContainer(node) {
+			while (node) {
+				if (node.id === caretContainerId) {
+					return node;
+				}
+
+				node = node.parentNode;
+			}
+		};
+
+		// Finds the first text node in the specified node
+		function findFirstTextNode(node) {
+			var walker;
+
+			if (node) {
+				walker = new TreeWalker(node, node);
+
+				for (node = walker.current(); node; node = walker.next()) {
+					if (node.nodeType === 3) {
+						return node;
+					}
+				}
+			}
+		};
+
+		// Insert caret container before/after target or expand selection to include block
+		function insertCaretContainerOrExpandToBlock(target, before) {
+			var caretContainer, rng;
+
+			// Select block
+			if (getContentEditable(target) === "false") {
+				if (dom.isBlock(target)) {
+					selection.select(target);
+					return;
+				}
+			}
+
+			rng = dom.createRng();
+
+			if (getContentEditable(target) === "true") {
+				if (!target.firstChild) {
+					target.appendChild(ed.getDoc().createTextNode('\u00a0'));
+				}
+
+				target = target.firstChild;
+				before = true;
+			}
+
+			//caretContainer = dom.create('span', {id: caretContainerId, 'data-mce-bogus': true, style:'border: 1px solid red'}, invisibleChar);
+			caretContainer = dom.create('span', {id: caretContainerId, 'data-mce-bogus': true}, invisibleChar);
+
+			if (before) {
+				target.parentNode.insertBefore(caretContainer, target);
+			} else {
+				dom.insertAfter(caretContainer, target);
+			}
+
+			rng.setStart(caretContainer.firstChild, 1);
+			rng.collapse(true);
+			selection.setRng(rng);
+
+			return caretContainer;
+		};
+
+		// Removes any caret container except the one we might be in
+		function removeCaretContainer(caretContainer) {
+			var child, currentCaretContainer, lastContainer;
+
+			if (caretContainer) {
+					rng = selection.getRng(true);
+					rng.setStartBefore(caretContainer);
+					rng.setEndBefore(caretContainer);
+
+					child = findFirstTextNode(caretContainer);
+					if (child && child.nodeValue.charAt(0) == invisibleChar) {
+						child = child.deleteData(0, 1);
+					}
+
+					dom.remove(caretContainer, true);
+
+					selection.setRng(rng);
+			} else {
+				currentCaretContainer = getParentCaretContainer(selection.getStart());
+				while ((caretContainer = dom.get(caretContainerId)) && caretContainer !== lastContainer) {
+					if (currentCaretContainer !== caretContainer) {
+						child = findFirstTextNode(caretContainer);
+						if (child && child.nodeValue.charAt(0) == invisibleChar) {
+							child = child.deleteData(0, 1);
+						}
+
+						dom.remove(caretContainer, true);
+					}
+
+					lastContainer = caretContainer;
+				}
+			}
+		};
+
+		// Modifies the selection to include contentEditable false elements or insert caret containers
+		function moveSelection() {
+			var nonEditableStart, nonEditableEnd, isCollapsed, rng, element;
+
+			// Checks if there is any contents to the left/right side of caret returns the noneditable element or any editable element if it finds one inside
+			function hasSideContent(element, left) {
+				var container, offset, walker, node, len;
+
+				container = rng.startContainer;
+				offset = rng.startOffset;
+
+				// If endpoint is in middle of text node then expand to beginning/end of element
+				if (container.nodeType == 3) {
+					len = container.nodeValue.length;
+					if ((offset > 0 && offset < len) || (left ? offset == len : offset == 0)) {
+						return;
+					}
+				} else {
+					// Can we resolve the node by index
+					if (offset < container.childNodes.length) {
+						// Browser represents caret position as the offset at the start of an element. When moving right
+						// this is the element we are moving into so we consider our container to be child node at offset-1
+						var pos = !left && offset > 0 ? offset-1 : offset;
+						container = container.childNodes[pos];
+						if (container.hasChildNodes()) {
+							container = container.firstChild;
+						}
+					} else {
+						// If not then the caret is at the last position in it's container and the caret container should be inserted after the noneditable element
+						return !left ? element : null;
+					}
+				}
+
+				// Walk left/right to look for contents
+				walker = new TreeWalker(container, element);
+				while (node = walker[left ? 'prev' : 'next']()) {
+					if (node.nodeType === 3 && node.nodeValue.length > 0) {
+						return;
+					} else if (getContentEditable(node) === "true") {
+						// Found contentEditable=true element return this one to we can move the caret inside it
+						return node;
+					}
+				}
+
+				return element;
+			};
+
+			// Remove any existing caret containers
+			removeCaretContainer();
+
+			// Get noneditable start/end elements
+			isCollapsed = selection.isCollapsed();
+			nonEditableStart = getNonEditableParent(selection.getStart());
+			nonEditableEnd = getNonEditableParent(selection.getEnd());
+
+			// Is any fo the range endpoints noneditable
+			if (nonEditableStart || nonEditableEnd) {
+				rng = selection.getRng(true);
+
+				// If it's a caret selection then look left/right to see if we need to move the caret out side or expand
+				if (isCollapsed) {
+					nonEditableStart = nonEditableStart || nonEditableEnd;
+					var start = selection.getStart();
+					if (element = hasSideContent(nonEditableStart, true)) {
+						// We have no contents to the left of the caret then insert a caret container before the noneditable element
+						insertCaretContainerOrExpandToBlock(element, true);
+					} else if (element = hasSideContent(nonEditableStart, false)) {
+						// We have no contents to the right of the caret then insert a caret container after the noneditable element
+						insertCaretContainerOrExpandToBlock(element, false);
+					} else {
+						// We are in the middle of a noneditable so expand to select it
+						selection.select(nonEditableStart);
+					}
+				} else {
+					rng = selection.getRng(true);
+
+					// Expand selection to include start non editable element
+					if (nonEditableStart) {
+						rng.setStartBefore(nonEditableStart);
+					}
+
+					// Expand selection to include end non editable element
+					if (nonEditableEnd) {
+						rng.setEndAfter(nonEditableEnd);
+					}
+
+					selection.setRng(rng);
+				}
+			}
+		};
+
+		function handleKey(ed, e) {
+			var keyCode = e.keyCode, nonEditableParent, caretContainer, startElement, endElement;
+
+			function getNonEmptyTextNodeSibling(node, prev) {
+				while (node = node[prev ? 'previousSibling' : 'nextSibling']) {
+					if (node.nodeType !== 3 || node.nodeValue.length > 0) {
+						return node;
+					}
+				}
+			};
+
+			function positionCaretOnElement(element, start) {
+				selection.select(element);
+				selection.collapse(start);
+			}
+
+			function canDelete(backspace) {
+				var rng, container, offset, nonEditableParent;
+
+				function removeNodeIfNotParent(node) {
+					var parent = container;
+
+					while (parent) {
+						if (parent === node) {
+							return;
+						}
+
+						parent = parent.parentNode;
+					}
+
+					dom.remove(node);
+					moveSelection();
+				}
+
+				function isNextPrevTreeNodeNonEditable() {
+					var node, walker, nonEmptyElements = ed.schema.getNonEmptyElements();
+
+					walker = new tinymce.dom.TreeWalker(container, ed.getBody());
+					while (node = (backspace ? walker.prev() : walker.next())) {
+						// Found IMG/INPUT etc
+						if (nonEmptyElements[node.nodeName.toLowerCase()]) {
+							break;
+						}
+
+						// Found text node with contents
+						if (node.nodeType === 3 && tinymce.trim(node.nodeValue).length > 0) {
+							break;
+						}
+
+						// Found non editable node
+						if (getContentEditable(node) === "false") {
+							removeNodeIfNotParent(node);
+							return true;
+						}
+					}
+
+					// Check if the content node is within a non editable parent
+					if (getNonEditableParent(node)) {
+						return true;
+					}
+
+					return false;
+				}
+
+				if (selection.isCollapsed()) {
+					rng = selection.getRng(true);
+					container = rng.startContainer;
+					offset = rng.startOffset;
+					container = getParentCaretContainer(container) || container;
+
+					// Is in noneditable parent
+					if (nonEditableParent = getNonEditableParent(container)) {
+						removeNodeIfNotParent(nonEditableParent);
+						return false;
+					}
+
+					// Check if the caret is in the middle of a text node
+					if (container.nodeType == 3 && (backspace ? offset > 0 : offset < container.nodeValue.length)) {
+						return true;
+					}
+
+					// Resolve container index
+					if (container.nodeType == 1) {
+						container = container.childNodes[offset] || container;
+					}
+
+					// Check if previous or next tree node is non editable then block the event
+					if (isNextPrevTreeNodeNonEditable()) {
+						return false;
+					}
+				}
+
+				return true;
+			}
+
+			startElement = selection.getStart()
+			endElement = selection.getEnd();
+
+			// Disable all key presses in contentEditable=false except delete or backspace
+			nonEditableParent = getNonEditableParent(startElement) || getNonEditableParent(endElement);
+			if (nonEditableParent && (keyCode < 112 || keyCode > 124) && keyCode != VK.DELETE && keyCode != VK.BACKSPACE) {
+				// Is Ctrl+c, Ctrl+v or Ctrl+x then use default browser behavior
+				if ((tinymce.isMac ? e.metaKey : e.ctrlKey) && (keyCode == 67 || keyCode == 88 || keyCode == 86)) {
+					return;
+				}
+
+				e.preventDefault();
+
+				// Arrow left/right select the element and collapse left/right
+				if (keyCode == VK.LEFT || keyCode == VK.RIGHT) {
+					var left = keyCode == VK.LEFT;
+					// If a block element find previous or next element to position the caret
+					if (ed.dom.isBlock(nonEditableParent)) {
+						var targetElement = left ? nonEditableParent.previousSibling : nonEditableParent.nextSibling;
+						var walker = new TreeWalker(targetElement, targetElement);
+						var caretElement = left ? walker.prev() : walker.next();
+						positionCaretOnElement(caretElement, !left);
+					} else {
+						positionCaretOnElement(nonEditableParent, left);
+					}
+				}
+			} else {
+				// Is arrow left/right, backspace or delete
+				if (keyCode == VK.LEFT || keyCode == VK.RIGHT || keyCode == VK.BACKSPACE || keyCode == VK.DELETE) {
+					caretContainer = getParentCaretContainer(startElement);
+					if (caretContainer) {
+						// Arrow left or backspace
+						if (keyCode == VK.LEFT || keyCode == VK.BACKSPACE) {
+							nonEditableParent = getNonEmptyTextNodeSibling(caretContainer, true);
+
+							if (nonEditableParent && getContentEditable(nonEditableParent) === "false") {
+								e.preventDefault();
+
+								if (keyCode == VK.LEFT) {
+									positionCaretOnElement(nonEditableParent, true);
+								} else {
+									dom.remove(nonEditableParent);
+									return;
+								}
+							} else {
+								removeCaretContainer(caretContainer);
+							}
+						}
+
+						// Arrow right or delete
+						if (keyCode == VK.RIGHT || keyCode == VK.DELETE) {
+							nonEditableParent = getNonEmptyTextNodeSibling(caretContainer);
+
+							if (nonEditableParent && getContentEditable(nonEditableParent) === "false") {
+								e.preventDefault();
+
+								if (keyCode == VK.RIGHT) {
+									positionCaretOnElement(nonEditableParent, false);
+								} else {
+									dom.remove(nonEditableParent);
+									return;
+								}
+							} else {
+								removeCaretContainer(caretContainer);
+							}
+						}
+					}
+
+					if ((keyCode == VK.BACKSPACE || keyCode == VK.DELETE) && !canDelete(keyCode == VK.BACKSPACE)) {
+						e.preventDefault();
+						return false;
+					}
+				}
+			}
+		};
+
+		ed.onMouseDown.addToTop(function(ed, e) {
+			var node = ed.selection.getNode();
+
+			if (getContentEditable(node) === "false" && node == e.target) {
+				// Expand selection on mouse down we can't block the default event since it's used for drag/drop
+				moveSelection();
+			}
+		});
+
+		ed.onMouseUp.addToTop(moveSelection);
+		ed.onKeyDown.addToTop(handleKey);
+		ed.onKeyUp.addToTop(moveSelection);
+	};
+
+	tinymce.create('tinymce.plugins.NonEditablePlugin', {
+		init : function(ed, url) {
+			var editClass, nonEditClass, nonEditableRegExps;
+
+			// Converts configured regexps to noneditable span items
+			function convertRegExpsToNonEditable(ed, args) {
+				var i = nonEditableRegExps.length, content = args.content, cls = tinymce.trim(nonEditClass);
+
+				// Don't replace the variables when raw is used for example on undo/redo
+				if (args.format == "raw") {
+					return;
+				}
+
+				while (i--) {
+					content = content.replace(nonEditableRegExps[i], function(match) {
+						var args = arguments, index = args[args.length - 2];
+
+						// Is value inside an attribute then don't replace
+						if (index > 0 && content.charAt(index - 1) == '"') {
+							return match;
+						}
+
+						return '<span class="' + cls + '" data-mce-content="' + ed.dom.encode(args[0]) + '">' + ed.dom.encode(typeof(args[1]) === "string" ? args[1] : args[0]) + '</span>';
+					});
+				}
+
+				args.content = content;
+			};
+			
+			editClass = " " + tinymce.trim(ed.getParam("noneditable_editable_class", "mceEditable")) + " ";
+			nonEditClass = " " + tinymce.trim(ed.getParam("noneditable_noneditable_class", "mceNonEditable")) + " ";
+
+			// Setup noneditable regexps array
+			nonEditableRegExps = ed.getParam("noneditable_regexp");
+			if (nonEditableRegExps && !nonEditableRegExps.length) {
+				nonEditableRegExps = [nonEditableRegExps];
+			}
+
+			ed.onPreInit.add(function() {
+				handleContentEditableSelection(ed);
+
+				if (nonEditableRegExps) {
+					ed.selection.onBeforeSetContent.add(convertRegExpsToNonEditable);
+					ed.onBeforeSetContent.add(convertRegExpsToNonEditable);
+				}
+
+				// Apply contentEditable true/false on elements with the noneditable/editable classes
+				ed.parser.addAttributeFilter('class', function(nodes) {
+					var i = nodes.length, className, node;
+
+					while (i--) {
+						node = nodes[i];
+						className = " " + node.attr("class") + " ";
+
+						if (className.indexOf(editClass) !== -1) {
+							node.attr(internalName, "true");
+						} else if (className.indexOf(nonEditClass) !== -1) {
+							node.attr(internalName, "false");
+						}
+					}
+				});
+
+				// Remove internal name
+				ed.serializer.addAttributeFilter(internalName, function(nodes, name) {
+					var i = nodes.length, node;
+
+					while (i--) {
+						node = nodes[i];
+
+						if (nonEditableRegExps && node.attr('data-mce-content')) {
+							node.name = "#text";
+							node.type = 3;
+							node.raw = true;
+							node.value = node.attr('data-mce-content');
+						} else {
+							node.attr(externalName, null);
+							node.attr(internalName, null);
+						}
+					}
+				});
+
+				// Convert external name into internal name
+				ed.parser.addAttributeFilter(externalName, function(nodes, name) {
+					var i = nodes.length, node;
+
+					while (i--) {
+						node = nodes[i];
+						node.attr(internalName, node.attr(externalName));
+						node.attr(externalName, null);
+					}
+				});
+			});
+		},
+
+		getInfo : function() {
+			return {
+				longname : 'Non editable elements',
+				author : 'Moxiecode Systems AB',
+				authorurl : 'http://tinymce.moxiecode.com',
+				infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/noneditable',
+				version : tinymce.majorVersion + "." + tinymce.minorVersion
+			};
+		}
+	});
+
+	// Register plugin
+	tinymce.PluginManager.add('noneditable', tinymce.plugins.NonEditablePlugin);
+})();
Index: wp-includes/js/tinymce/plugins/noneditable/editor_plugin_src.js
===================================================================
--- wp-includes/js/tinymce/plugins/noneditable/editor_plugin_src.js	(revision 0)
+++ wp-includes/js/tinymce/plugins/noneditable/editor_plugin_src.js	(working copy)

Property changes on: wp-includes/js/tinymce/plugins/noneditable/editor_plugin_src.js
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: wp-includes/js/tinymce/plugins/wpgallery/editor_plugin_src.js
===================================================================
--- wp-includes/js/tinymce/plugins/wpgallery/editor_plugin_src.js	(revision 21514)
+++ wp-includes/js/tinymce/plugins/wpgallery/editor_plugin_src.js	(working copy)
@@ -1,65 +1,156 @@
 
 (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;
+				div_id = target.id;
+				shortcode = ed.dom.getAttrib( target, 'data-wp-gallery-args' ); // already urlencoded
+				if ( !shortcode || !div_id )
+					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);
+				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' );
 			});
 
 			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);
 			});
 
-			ed.onPostProcess.add(function(ed, o) {
-				if (o.get)
-					o.content = t._get_gallery(o.content);
+			ed.onInit.add(function(ed){
+				// replace the gallery preview dom nodes in the dom copy that is being serialized
+				ed.serializer.onPreProcess.add(function(ed, o) {
+					if ( o.get && o.save )
+						t._remove_gallery_preview();
+				});
 			});
-		},
 
-		_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)+'" />';
-			});
+			ed.wpSetGalleryPreview = function(content) {
+				return t._do_gallery(content);
+			}
 		},
 
-		_get_gallery : function(co) {
+		_do_gallery : function(content) {
+			var self = this, ed = self.ed, dom = ed.dom, args, data, post_id, sh = self.sh;
 
-			function getAttr(s, n) {
-				n = new RegExp(n + '=\"([^\"]+)\"', 'g').exec(s);
-				return n ? tinymce.DOM.decode(n[1]) : '';
+			if ( !content.match(/\[gallery[^\]]*\]/) )
+				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;
+
+			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;
+					}
+
+					new_id = 'wp_gallery_preview_' + div_id.replace(/[^0-9]+/, '');
+					dom.setAttrib( div, 'id', new_id );
+					dom.setAttrib( div, 'data-wp-gallery-args', shortcode );
+					dom.addClass( div, 'wp-gallery-preview mceNonEditable' );
+					dom.setHTML( div, r );
+
+					ed.setProgressState(false);
+					ed.execCommand('mceRepaint');
+				},
+				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] );
+				}
+
+				args['data'] = str;
+				tinymce.util.XHR.send( args );
+
+				return '<div id="'+div_id+'">' + shortcode + '</div>';
 			});
 		},
 
+		_remove_gallery_preview : function() {
+			var ed = this.ed, dom = ed.dom, divs;
+
+			divs = ed.dom.select('div.wp-gallery-preview');
+			if ( !divs )
+				return;
+
+			tinymce.each( divs, function(el){
+				var p, args = dom.getAttrib( el, 'data-wp-gallery-args' );
+
+				args = args ? ' ' + decodeURIComponent(args) : '';
+				p = dom.create( 'p', {}, args );
+				dom.replace( p, el );
+			});
+		},
+
 		_createButtons : function() {
 			var t = this, ed = tinyMCE.activeEditor, DOM = tinymce.DOM, editButton, dellButton;
 
Index: wp-includes/js/tinymce/themes/advanced/skins/wp_theme/content.css
===================================================================
--- wp-includes/js/tinymce/themes/advanced/skins/wp_theme/content.css	(revision 21514)
+++ wp-includes/js/tinymce/themes/advanced/skins/wp_theme/content.css	(working copy)
@@ -147,3 +147,56 @@
 	height: 250px;
 }
 
+/* Gallery preview */
+
+div.wp-gallery-preview {
+	margin: 10px auto;
+	-ms-user-select: none;
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	user-select: none;
+}
+
+div.wp-gallery-preview .gallery-icon {
+	text-align: center;
+}
+
+div.wp-gallery-preview .gallery-icon img {
+	margin: 0;
+	padding: 0;
+	max-width: 90%;
+	height: auto;
+}
+
+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: 98%;
+}
+
+div.wp-gallery-preview div.gallery-columns-2 dl.gallery-item {
+	width: 49%;
+}
+
+div.wp-gallery-preview div.gallery-columns-3 dl.gallery-item {
+	width: 32%;
+}
+
+div.wp-gallery-preview div.gallery-columns-4 dl.gallery-item {
+	width: 24%;
+}
+
+div.wp-gallery-preview div.gallery-columns-5 dl.gallery-item {
+	width: 19%;
+}
+
+
+
Index: wp-includes/media.php
===================================================================
--- wp-includes/media.php	(revision 21514)
+++ 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,32 +876,35 @@
 		</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';
 
+	if ( $mce_preview ) {
+		$output = $mce_preview . $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 .= "<br style='clear: both' />";
 	}
 
-	$output .= "
-			<br style='clear: both;' />
-		</div>\n";
+	$output .= "<br style='clear: both;' /></div>\n";
 
 	return $output;
 }
