Index: wp-includes/js/tinymce/plugins/wordpress/editor_plugin_src.js
===================================================================
--- wp-includes/js/tinymce/plugins/wordpress/editor_plugin_src.js	(revision 21913)
+++ wp-includes/js/tinymce/plugins/wordpress/editor_plugin_src.js	(working copy)
@@ -7,13 +7,19 @@
 
 	tinymce.create('tinymce.plugins.WordPress', {
 		mceTout : 0,
+		previews : {i: 0},
+		reg_previews : [],
 
 		init : function(ed, url) {
-			var t = this, tbId = ed.getParam('wordpress_adv_toolbar', 'toolbar2'), last = 0, moreHTML, nextpageHTML, closeOnClick, mod_key;
+			var t = this, tbId = ed.getParam('wordpress_adv_toolbar', 'toolbar2'), last = 0, moreHTML, nextpageHTML, closeOnClick, mod_key,
+			_step_2, each = tinymce.each;
+
 			moreHTML = '<img src="' + url + '/img/trans.gif" class="mceWPmore mceItemNoResize" title="'+ed.getLang('wordpress.wp_more_alt')+'" />';
 			nextpageHTML = '<img src="' + url + '/img/trans.gif" class="mceWPnextpage mceItemNoResize" title="'+ed.getLang('wordpress.wp_page_alt')+'" />';
 
-			if ( getUserSetting('hidetb', '0') == '1' )
+			t.ed = ed;
+
+			if ( typeof(getUserSetting) == 'function' && getUserSetting('hidetb', '0') == '1' )
 				ed.settings.wordpress_adv_hidden = 0;
 
 			// Hides the specified toolbar and resizes the iframe
@@ -251,9 +257,6 @@
 			// Add custom shortcuts
 			mod_key = 'alt+shift';
 
-		//	if ( tinymce.isGecko ) // disable for mow, too many shortcuts conflicts
-		//		mod_key = 'ctrl+alt';
-
 			ed.addShortcut(mod_key + '+c', 'justifycenter_desc', 'JustifyCenter');
 			ed.addShortcut(mod_key + '+r', 'justifyright_desc', 'JustifyRight');
 			ed.addShortcut(mod_key + '+l', 'justifyleft_desc', 'JustifyLeft');
@@ -313,6 +316,137 @@
 			// close popups when clicking on the background
 			tinymce.dom.Event.remove(document.body, 'click', closeOnClick);
 			tinymce.dom.Event.add(document.body, 'click', closeOnClick);
+
+
+			/* testing */
+			ed.onPreInit.add( function(ed){
+				ed.schema.addValidElements('div[*]'); // so we can set contenteditable=false
+
+				// add custom jQuery event so plugins can do:
+				// jQuery(document).on( 'wp_add_mce_previews', function(e, ed){ ed.wpPreviewRegister(args) } );
+				if ( typeof(jQuery) != 'undefined' )
+					jQuery(document).trigger( 'wp_add_mce_previews', ed );
+			});
+
+			// runs on paste and on inserting nodes/html (on send_to_editor)
+			ed.onInit.add(function(ed) {
+				ed.selection.onSetContent.add(function(sel, o) {
+					var node;
+
+					if ( o.context && t.reg_previews.length ) {
+						node = sel.getNode();
+
+						if ( node.innerHTML )
+							node.innerHTML = ed.wpPreviewAdd(node.innerHTML);
+					}
+				});
+			});
+
+			// runs every time content is loaded in the editor
+			ed.onBeforeSetContent.add(function(ed, o) {
+				if ( o.content )
+					o.content = ed.wpPreviewAdd(o.content);
+			});
+
+			ed.onPostProcess.add(function(ed, o) {
+				if ( ( o.get || o.save ) && o.content.indexOf('data-wp-preview="') > -1 ) {
+					o.content = o.content.replace(/(<div[^>]+data-wp-preview="([^"]+)"[^>]*>)[\s\S]+?<\/div><div data-wp-preview-end[^<]+<\/div><\/div>/g, function(a, b, c){
+						var previews = t.previews, str = '<p>'+ decodeURIComponent(c) +'</p>', div_id = b.replace(/.+id="([^"]+)".+/, '$1');
+
+						if ( previews[div_id] && previews[div_id].cleanup_callback )
+							str = previews[div_id].cleanup_callback.call( t, { ed: ed, original: str } );
+
+						return str;
+					});
+				}
+			});
+
+			_step_2 = function() {
+				var _previews = {};
+
+				// go through the added previews and fire callbacks
+				each(t.previews, function(args, div_id){
+					var node = typeof(args) == 'object' && div_id != 'i' ? ed.dom.select('#'+div_id) : null, wrap;
+
+					if ( !node || !node.length )
+						return;
+
+					// reset the previews references
+					_previews[div_id] = args;
+					wrap = ed.dom.select('.wp-preview', node[0]);
+
+					if ( args.node_callback ) { // use the inner wrapper as node in the callback
+						args.node_callback.call( t, { ed: ed, node: wrap[0], div_id: div_id } );
+					}
+					if ( args.onmousedown ) {
+						ed.dom.events.add( node, 'mousedown', args.onmousedown );
+					}
+					if ( args.onmouseup ) {
+						ed.dom.events.add( node, 'mouseup', args.onmouseup );
+					}
+					if ( args.onclick ) {
+						ed.dom.events.add( node, 'click', args.onclick );
+					}
+				});
+
+				_previews.i = t.previews.i;
+				t.previews = _previews;
+			}
+
+			// register all previews
+			ed.wpPreviewRegister = function(args) {
+				t.reg_previews.push(args);
+			};
+
+			/*
+			args = {
+				preview_regexp: /\[gallery[^\]]*\]/,
+				str_callback: function(obj){ console.log('str_callback'); console.log(obj); return obj.original+' 123 ' },
+				node_callback: function(obj){ console.log('node_callback'); console.log(obj) },
+				cleanup_callback: function(obj){ console.log('cleanup_callback'); console.log(obj); return obj.original },
+				onmousedown: function(e){ console.log('onmousedown'); console.log(e) },
+				onmouseup: function(e){ console.log('onmouseup'); console.log(e) },
+				onclick: function(e){ console.log('onclick'); console.log(e) }
+			}
+			*/
+			ed.wpPreviewAdd = function(content) {
+				var previews = t.previews;
+
+				if ( t.reg_previews.length ) {
+					each( t.reg_previews, function(args){
+						if ( !args.preview_regexp )
+							return;
+
+						var regex = new RegExp( '(?:<p>\\s*)?(' + args.preview_regexp.source + ')(?:\\s*</p>)?', 'g' );
+
+						content = content.replace(regex, function(a, orig_str){
+							var html, div_id, new_str;
+	
+							previews.i++;
+							div_id = 'wp_mce_preview_' + previews.i;
+							// ed, self or this?
+							new_str = args.str_callback.call( t, { ed: ed, original: orig_str, div_id: div_id } );
+							previews[div_id] = args;
+	
+							html = '<div id="'+ div_id +'" data-wp-preview="'+ encodeURIComponent(orig_str) +'" class="wp-preview-wrap" contenteditable="false">' +
+								'<div class="wp-preview-blocker"><br></div>' +
+								'<div class="wp-preview">'+ new_str +'</div>' + // add inner wrapper so the preview node(s) can be appended there without disturbing the blocker and end divs?
+								'<div data-wp-preview-end="1">\uFEFF</div></div>';
+	
+							return html;
+						});
+					});
+				}
+				
+				if ( t.step2timeout )
+					clearTimeout(t.step2timeout);
+				// run the callback after the node has been created in the editor
+				t.step2timeout = setTimeout( function(){
+					_step_2();
+				}, 200 );
+
+				return content;
+			};
 		},
 
 		getInfo : function() {
@@ -418,17 +552,18 @@
 
 			// Replace images with morebreak
 			ed.onPostProcess.add(function(ed, o) {
-				if (o.get)
+				if ( o.get ) {
 					o.content = o.content.replace(/<img[^>]+>/g, function(im) {
-						if (im.indexOf('class="mceWPmore') !== -1) {
-							var m, moretext = (m = im.match(/alt="(.*?)"/)) ? m[1] : '';
+						if ( im.indexOf('class="mceWPmore') !== -1 ) {
+							var m, moretext = ( m = im.match(/alt="(.*?)"/) ) ? m[1] : '';
 							im = '<!--more'+moretext+'-->';
 						}
-						if (im.indexOf('class="mceWPnextpage') !== -1)
+						if ( im.indexOf('class="mceWPnextpage') !== -1 )
 							im = '<!--nextpage-->';
 
 						return im;
 					});
+				}
 			});
 
 			// Set active buttons if user selected pagebreak or more break
Index: wp-includes/js/tinymce/plugins/wpgallery/editor_plugin_src.js
===================================================================
--- wp-includes/js/tinymce/plugins/wpgallery/editor_plugin_src.js	(revision 21913)
+++ wp-includes/js/tinymce/plugins/wpgallery/editor_plugin_src.js	(working copy)
@@ -26,7 +26,7 @@
 				if ( e.target.nodeName == 'IMG' && ed.dom.hasClass(e.target, 'wpGallery') )
 					ed.plugins.wordpress._showButtons(e.target, 'wp_gallerybtns');
 			});
-
+/*
 			ed.onBeforeSetContent.add(function(ed, o) {
 				o.content = t._do_gallery(o.content);
 			});
@@ -35,6 +35,7 @@
 				if (o.get)
 					o.content = t._get_gallery(o.content);
 			});
+*/
 		},
 
 		_do_gallery : function(co) {
Index: wp-includes/js/tinymce/themes/advanced/skins/wp_theme/content.css
===================================================================
--- wp-includes/js/tinymce/themes/advanced/skins/wp_theme/content.css	(revision 21913)
+++ wp-includes/js/tinymce/themes/advanced/skins/wp_theme/content.css	(working copy)
@@ -141,3 +141,109 @@
 	height: 250px;
 }
 
+/* Previews */
+
+div.wp-preview-blocker {
+	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-preview-blocker.focused {
+	background-color: #000;
+	filter: alpha(opacity=25);
+	opacity: 0.25;
+}
+
+div.wp-preview-wrap {
+	margin: 10px auto;
+	position: relative;
+	-ms-user-select: none;
+	-moz-user-select: none; /* doesn't work */
+	-webkit-user-select: none;
+	user-select: none;
+}
+
+div.wp-preview-wrap div[data-wp-preview-end] {
+	height: 1em;
+	margin-top: -1em;
+}
+
+div.wp-preview-wrap .gallery-icon {
+	margin: 0;
+}
+
+div.wp-preview-wrap .gallery-icon img {
+	display: block;
+	margin: 0 auto;
+	padding: 0;
+	max-width: 90%;
+	height: auto;
+	border: 0;
+}
+
+div.wp-preview-wrap dd.gallery-caption {
+	margin: 0 6%;
+	font-size: 12px;
+}
+
+div.wp-preview-wrap div.gallery {
+	clear: both;
+}
+
+div.wp-preview-wrap div.gallery dl.gallery-item {
+	float: left;
+	margin: 10px 0;
+	padding: 0;
+}
+
+div.wp-preview-wrap div.gallery-columns-1 dl.gallery-item {
+	width: 99%;
+}
+
+div.wp-preview-wrap div.gallery-columns-2 dl.gallery-item {
+	width: 49.5%;
+}
+
+div.wp-preview-wrap div.gallery-columns-3 dl.gallery-item {
+	width: 33%;
+}
+
+div.wp-preview-wrap div.gallery-columns-4 dl.gallery-item {
+	width: 24.75%;
+}
+
+div.wp-preview-wrap div.gallery-columns-5 dl.gallery-item {
+	width: 19.8%;
+}
+
+div.wp-preview-wrap div.gallery-columns-6 dl.gallery-item {
+	width: 16.5%;
+}
+
+div.wp-preview-wrap div.gallery-columns-7 dl.gallery-item {
+	width: 14.2%;
+}
+
+div.wp-preview-wrap div.gallery-columns-8 dl.gallery-item {
+	width: 12.45%;
+}
+
+div.wp-preview-wrap div.gallery-columns-9 dl.gallery-item {
+	width: 11.1%;
+}
+
+div.wp-preview-wrap div.gallery-columns-10 dl.gallery-item {
+	width: 9.99%;
+}
+
+
+
