Index: src/wp-admin/js/editor-expand.js
===================================================================
--- src/wp-admin/js/editor-expand.js	(revision 29185)
+++ src/wp-admin/js/editor-expand.js	(working copy)
@@ -122,9 +122,18 @@
 			}, 200 );
 		} );
 
-		editor.on( 'keyup', function() {
-			var offset = getCursorOffset(),
+		// Make sure the cursor is always visible.
+		// This is not only necessary to keep the cursor between the toolbars,
+		// but also to scroll the window when the cursor moves out of the viewport to a wpview.
+		// Setting a buffer > 0 will prevent the browser default.
+		// Some browsers will scroll to the middle,
+		// others to the top/bottom of the *window* when moving the cursor out of the viewport.
+		editor.on( 'keyup', function( event ) {
+			var VK = tinymce.util.VK,
+				key = event.keyCode,
+				offset = getCursorOffset(),
 				windowHeight = $window.height(),
+				buffer = 10,
 				cursorTop, cursorBottom, editorTop, editorBottom;
 
 			if ( ! offset ) {
@@ -133,11 +142,15 @@
 
 			cursorTop = offset.top + editor.getContentAreaContainer().getElementsByTagName( 'iframe' )[0].getBoundingClientRect().top;
 			cursorBottom = cursorTop + offset.height;
+			cursorTop = cursorTop - buffer;
+			cursorBottom = cursorBottom + buffer;
 			editorTop = $adminBar.outerHeight() + $tools.outerHeight() + $visualTop.outerHeight();
-			editorBottom = $window.height() - $bottom.outerHeight();
+			editorBottom = windowHeight - $bottom.outerHeight();
 
-			if ( cursorTop < editorTop || cursorBottom > editorBottom ) {
-				window.scrollTo( window.pageXOffset, cursorTop + window.pageYOffset - windowHeight / 2 );
+			if ( cursorTop < editorTop && ( key === VK.UP || key === VK.LEFT ) ) {
+				window.scrollTo( window.pageXOffset, cursorTop + window.pageYOffset - editorTop );
+			} else if ( cursorBottom > editorBottom ) {
+				window.scrollTo( window.pageXOffset, cursorBottom + window.pageYOffset - editorBottom );
 			}
 		} );
 
@@ -145,7 +158,7 @@
 			var selection = editor.selection,
 				node = selection.getNode(),
 				range = selection.getRng(),
-				view, clone, right, offset;
+				view, clone, offset;
 
 			if ( tinymce.Env.ie && tinymce.Env.ie < 9 ) {
 				return;
@@ -159,7 +172,6 @@
 				if ( clone.startContainer.length > 1 ) {
 					if ( clone.startContainer.length > clone.endOffset ) {
 						clone.setEnd( clone.startContainer, clone.endOffset + 1 );
-						right = true;
 					} else {
 						clone.setStart( clone.startContainer, clone.endOffset - 1 );
 					}
@@ -175,7 +187,7 @@
 			}
 
 			if ( ! offset.height ) {
-				return false;
+				return;
 			}
 
 			return offset;
