Index: wp-admin/js/editor.js
===================================================================
--- wp-admin/js/editor.js	(revision 21966)
+++ wp-admin/js/editor.js	(working copy)
@@ -49,10 +49,8 @@
 			if ( ed && ed.isHidden() )
 				return false;
 
-			if ( ed ) {
-				txtarea_el.style.height = ed.getContentAreaContainer().offsetHeight + 20 + 'px';
+			if ( ed )
 				ed.hide();
-			}
 
 			dom.removeClass(wrap_id, 'tmce-active');
 			dom.addClass(wrap_id, 'html-active');
Index: wp-includes/class-wp-editor.php
===================================================================
--- wp-includes/class-wp-editor.php	(revision 21966)
+++ wp-includes/class-wp-editor.php	(working copy)
@@ -28,11 +28,14 @@
 	private function __construct() {}
 
 	public static function parse_settings($editor_id, $settings) {
+		if ( isset( $settings['textarea_rows'] ) && ! isset( $settings['editor_height'] ) ) 
+			$settings['editor_height'] = $settings['textarea_rows'] * 18; // Convert rows="" to pixels. 
+
 		$set = wp_parse_args( $settings,  array(
 			'wpautop' => true, // use wpautop?
 			'media_buttons' => true, // show insert/upload button(s)
 			'textarea_name' => $editor_id, // set the textarea name to something different, square brackets [] can be used here
-			'textarea_rows' => get_option('default_post_edit_rows', 10), // rows="..."
+			'editor_height' => '', // editor height in px (replaces textarea rows)
 			'tabindex' => '',
 			'tabfocus_elements' => ':prev,:next', // the previous and next element ID to move the focus to when pressing the Tab key in TinyMCE
 			'editor_css' => '', // intended for extra styles for both visual and Text editors buttons, needs to include the <style> tags, can use "scoped".
@@ -52,6 +55,26 @@
 		if ( self::$this_quicktags )
 			self::$has_quicktags = true;
 
+		if ( 'content' === $editor_id && self::$has_tinymce ) {
+			// A cookie (set when a user resizes the editor) overrides the height.
+			$cookie = (int) get_user_setting( $editor_id . '_ed_size' );
+
+			// Upgrade an old TinyMCE cookie if it is still around, and the new one isn't.
+			if ( ! $cookie && isset( $_COOKIE['TinyMCE_' . $editor_id . '_size'] ) ) {
+				parse_str( $_COOKIE['TinyMCE_' . $editor_id . '_size'], $cookie );
+ 				$cookie = $cookie['ch'];
+			}
+
+			if ( $cookie )
+				$set['editor_height'] = $cookie;
+			else
+				$set['editor_height'] = 360; // 360px is about 20 textarea rows. the old default val for the main editor
+		}
+
+		// 50px is the minimum height for TinyMCE and all things reasonable. 
+		if ( $set['editor_height'] < 50 ) 
+			$set['editor_height'] = 50; 
+
 		return $set;
 	}
 
@@ -67,7 +90,7 @@
 		$set = self::parse_settings($editor_id, $settings);
 		$editor_class = ' class="' . trim( $set['editor_class'] . ' wp-editor-area' ) . '"';
 		$tabindex = $set['tabindex'] ? ' tabindex="' . (int) $set['tabindex'] . '"' : '';
-		$rows = ' rows="' . (int) $set['textarea_rows'] . '"';
+		$editor_height = $set['editor_height'] ? ' style="height: ' . $set['editor_height'] . 'px;"' : '';
 		$switch_class = 'html-active';
 		$toolbar = $buttons = '';
 
@@ -116,7 +139,7 @@
 			echo "</div>\n";
 		}
 
-		$the_editor = apply_filters('the_editor', '<div id="wp-' . $editor_id . '-editor-container" class="wp-editor-container"><textarea' . $editor_class . $rows . $tabindex . ' cols="40" name="' . $set['textarea_name'] . '" id="' . $editor_id . '">%s</textarea></div>');
+		$the_editor = apply_filters('the_editor', '<div id="wp-' . $editor_id . '-editor-container" class="wp-editor-container"><textarea' . $editor_class . $editor_height . $tabindex . ' cols="40" name="' . $set['textarea_name'] . '" id="' . $editor_id . '">%s</textarea></div>');
 		$content = apply_filters('the_editor_content', $content);
 
 		printf($the_editor, $content);
@@ -403,6 +426,8 @@
 				'body_class' => $body_class
 			);
 
+			$mceInit['theme_advanced_resizing_use_cookie'] = 'content' !== $editor_id;
+
 			if ( $first_run )
 				$mceInit = array_merge(self::$first_init, $mceInit);
 
@@ -553,13 +578,28 @@
 ?>
 
 	<script type="text/javascript">
+		var wpActiveEditor;
+
 		(function(){
-			var init, ed, qt, first_init, mce = <?php echo wp_default_editor() == 'tinymce' ? 'true' : 'false'; ?>;
+			var init, ed, qt, first_init, DOM, el, i, mce = <?php
 
+			if ( ( self::$has_tinymce && wp_default_editor() == 'tinymce' ) || !self::$has_quicktags )
+				echo 'true';
+			else
+				echo 'false';
+
+			?>;
+
 			if ( typeof(tinymce) == 'object' ) {
+				DOM = tinymce.DOM;
 				// mark wp_theme/ui.css as loaded
-				tinymce.DOM.files[tinymce.baseURI.getURI() + '/themes/advanced/skins/wp_theme/ui.css'] = true;
+				DOM.files[tinymce.baseURI.getURI() + '/themes/advanced/skins/wp_theme/ui.css'] = true;
 
+				DOM.events.add( DOM.select('.wp-editor-wrap'), 'mousedown', function(e){
+					if ( this.id )
+						wpActiveEditor = this.id.slice(3, -5);
+				});
+
 				for ( ed in tinyMCEPreInit.mceInit ) {
 					if ( first_init ) {
 						init = tinyMCEPreInit.mceInit[ed] = tinymce.extend( {}, first_init, tinyMCEPreInit.mceInit[ed] );
@@ -570,6 +610,12 @@
 					if ( mce )
 						try { tinymce.init(init); } catch(e){}
 				}
+			} else {
+				el = document.getElementsByClassName('wp-editor-wrap');
+				for ( i in el ) {
+					if ( typeof(el[i]) == 'object' )
+						el[i].onmousedown = function(){ wpActiveEditor = this.id.slice(3, -5); }
+				}
 			}
 
 			if ( typeof(QTags) == 'function' ) {
@@ -578,30 +624,45 @@
 				}
 			}
 		})();
+		<?php
 
-		var wpActiveEditor;
-
-		jQuery('.wp-editor-wrap').mousedown(function(e){
-			wpActiveEditor = this.id.slice(3, -5);
-		});
-
-<?php
-
 		if ( self::$ext_plugins )
 			echo self::$ext_plugins . "\n";
 
 		if ( ! $compressed && $tmce_on ) {
-?>
-		(function(){var t=tinyMCEPreInit,sl=tinymce.ScriptLoader,ln=t.ref.language,th=t.ref.theme,pl=t.ref.plugins;sl.markDone(t.base+'/langs/'+ln+'.js');sl.markDone(t.base+'/themes/'+th+'/langs/'+ln+'.js');sl.markDone(t.base+'/themes/'+th+'/langs/'+ln+'_dlg.js');sl.markDone(t.base+'/themes/advanced/skins/wp_theme/ui.css');tinymce.each(pl.split(','),function(n){if(n&&n.charAt(0)!='-'){sl.markDone(t.base+'/plugins/'+n+'/langs/'+ln+'.js');sl.markDone(t.base+'/plugins/'+n+'/langs/'+ln+'_dlg.js');}});})();
-<?php
+			?>
+			(function(){var t=tinyMCEPreInit,sl=tinymce.ScriptLoader,ln=t.ref.language,th=t.ref.theme,pl=t.ref.plugins;sl.markDone(t.base+'/langs/'+ln+'.js');sl.markDone(t.base+'/themes/'+th+'/langs/'+ln+'.js');sl.markDone(t.base+'/themes/'+th+'/langs/'+ln+'_dlg.js');sl.markDone(t.base+'/themes/advanced/skins/wp_theme/ui.css');tinymce.each(pl.split(','),function(n){if(n&&n.charAt(0)!='-'){sl.markDone(t.base+'/plugins/'+n+'/langs/'+ln+'.js');sl.markDone(t.base+'/plugins/'+n+'/langs/'+ln+'_dlg.js');}});})();
+			<?php
 		}
 
-		if ( !is_admin() )
+		if ( !is_admin() ) {
 			echo 'var ajaxurl = "' . admin_url( 'admin-ajax.php', 'relative' ) . '";';
-?>
-	</script>
-<?php
+		} else {
+			?>
+			(function($){
+				if ( typeof($) == 'undefiend' || !$.browser.webkit )
+					return;
+				// convert textarea height from px to rows
+				var txt = $('textarea#content'), height = txt.css('height');
+				
+				if ( !height ) // not the main editor or no height in inline css
+					return;
 
+				txt.css('height', '').attr('rows', ( parseInt(height, 10) - 20 ) / 18);
+
+
+
+console.log( 'rows in jQuery = '+ txt.attr('rows') );
+console.log( 'css height in jQuery = '+ txt[0].style.height );
+				
+			})(jQuery)
+			<?php
+		}
+
+		?>
+		</script>
+		<?php
+
 		if ( in_array('wplink', self::$plugins, true) || in_array('link', self::$qt_buttons, true) )
 			self::wp_link_dialog();
 
Index: wp-includes/css/editor.css
===================================================================
--- wp-includes/css/editor.css	(revision 21966)
+++ wp-includes/css/editor.css	(working copy)
@@ -1024,6 +1024,7 @@
 	line-height: 150%;
 	border: 0 none;
 	outline: none;
+	display: block;
 	resize: vertical;
 	-moz-box-sizing: border-box;
 	-webkit-box-sizing: border-box;
Index: wp-includes/js/tinymce/plugins/wordpress/editor_plugin_src.js
===================================================================
--- wp-includes/js/tinymce/plugins/wordpress/editor_plugin_src.js	(revision 21966)
+++ wp-includes/js/tinymce/plugins/wordpress/editor_plugin_src.js	(working copy)
@@ -3,7 +3,7 @@
  */
 
 (function() {
-	var DOM = tinymce.DOM;
+	var DOM = tinymce.DOM, win = window;
 
 	tinymce.create('tinymce.plugins.WordPress', {
 		mceTout : 0,
@@ -234,6 +234,63 @@
 				}
 			});
 
+			// resize TinyMCE to match the textarea height when switching Text -> Visual
+			ed.onLoadContent.add( function(ed, o) {
+				var height, tb_height, ifr_height, txt = ed.getElement(),
+					ed_toolbar = DOM.select('#'+ed.id + '_tbl tr.mceFirst');
+
+				if ( txt && txt.style && txt.style.height )
+					height = parseInt( txt.style.height, 10 );
+				else if ( txt && ed.dom.getAttrib(txt, 'rows') )
+					height = ( ed.dom.getAttrib(txt, 'rows') * 18 ) + 20;
+
+				if ( ed_toolbar && ed_toolbar[0] )
+					tb_height = ed_toolbar[0].clientHeight;
+
+				if ( height && tb_height ) {
+					ifr_height = height - tb_height + 13; // compensate for the 10px padding in the textarea
+
+					DOM.setStyle( DOM.get(ed.id + '_tbl'), 'height', '' );
+					DOM.setStyle( DOM.get(ed.id + '_ifr'), 'height', ifr_height );
+					if ( win.setUserSetting )
+						win.setUserSetting( ed.id + '_ed_size', height );
+				}
+			});
+
+			// resize the textarea to match TinyMCE's height when switching Visual -> Text
+			ed.onSaveContent.add( function(ed, o) {
+				var height = DOM.get(ed.id+'_tbl').clientHeight, txt = ed.getElement();
+
+				if ( height && height > 84 ) {
+					height -= 34;
+
+					if ( tinymce.isWebKit ) {
+						DOM.setStyle( txt, 'height', '' );
+						DOM.setAttrib( txt, 'rows', ( height - 20 ) / 18 );
+					} else {
+						DOM.setStyle( txt, 'height', height );
+					}
+
+					if ( win.setUserSetting )
+						win.setUserSetting( ed.id + '_ed_size', height );
+				}
+			});
+
+			// save on uoload
+			DOM.bind(win, 'unload', function(e){
+				var height = document.getElementById('wp-'+ed.id+'-editor-container').clientHeight;
+
+				if ( document.getElementById(ed.id).clientHeight )
+					height -= 35;
+				else
+					height -= 34;
+
+				if ( !win.setUserSetting || height < 50 )
+					return;
+
+				win.setUserSetting( ed.id + '_ed_size', height );
+			});
+
 			/* disable for now
 			ed.onBeforeSetContent.add(function(ed, o) {
 				o.content = t._setEmbed(o.content);
