Index: _source/plugins/pagebreak/plugin.js
===================================================================
--- _source/plugins/pagebreak/plugin.js	(revision 3308)
+++ _source/plugins/pagebreak/plugin.js	Sat Nov 21 21:59:46 CST 2009
@@ -80,17 +80,35 @@
 		// Creates the fake image used for this element.
 		breakObject = editor.createFakeElement( breakObject, 'cke_pagebreak', 'div' );
 
-		var ranges = editor.getSelection().getRanges();
+		var ranges = editor.getSelection().getRanges(),
+			lastRangeIndex = ranges.length - 1,
+			range;
 
-		for ( var range, i = 0 ; i < ranges.length ; i++ )
+		for ( var i = lastRangeIndex ; i >= 0 ; i-- )
 		{
 			range = ranges[ i ];
 
-			if ( i > 0 )
+			if ( i < lastRangeIndex )
 				breakObject = breakObject.clone( true );
 
-			range.splitBlock( 'p' );
+			// Make sure it's inserted under body, split elements
+			// when necessary. (#4696)
+			var current;
+			while ( ( current = range.getCommonAncestor( false, true ) ) && !current.is( 'body' ) )
+				range.splitBlock();
 			range.insertNode( breakObject );
+
+			// Place cursor at the next editable position.
+			if( i == lastRangeIndex )
+			{
+				var next = breakObject.getNextSourceNode( true );
+				if ( next && next.type == CKEDITOR.NODE_ELEMENT )
+					range.moveToElementEditStart( next );
+				else
+					range.collapse();
+
+				range.select( true );
-		}
-	}
+			}
+		}
+	}
 };
Index: _source/core/dom/elementpath.js
===================================================================
--- _source/core/dom/elementpath.js	(revision 3565)
+++ _source/core/dom/elementpath.js	Sat Nov 21 18:16:26 CST 2009
@@ -9,7 +9,7 @@
 	var pathBlockElements = { address:1,blockquote:1,dl:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,p:1,pre:1,li:1,dt:1,de:1 };
 
 	// Elements that may be considered the "Block limit" in an element path.
-	var pathBlockLimitElements = { body:1,div:1,table:1,tbody:1,tr:1,td:1,th:1,caption:1,form:1 };
+	var pathBlockLimitElements = { body:1,div:1,table:1,tbody:1,tr:1,td:1,th:1,caption:1,form:1,ul:1,ol:1,dl:1 };
 
 	// Check if an element contains any block element.
 	var checkHasBlock = function( element )
Index: _source/core/dom/range.js
===================================================================
--- _source/core/dom/range.js	(revision 4475)
+++ _source/core/dom/range.js	Sat Nov 21 22:10:16 CST 2009
@@ -1405,6 +1405,15 @@
 			return fixedBlock;
 		},
 
+		/**
+		 * Remove the contents of the range, and split the then occupied
+		 * block into two, while setup the new position between them.
+		 * Note: If the range is not currently within a block, the result will
+		 *  depend on the {@param blockTag }
+		 *  1. Establish one new block element of the specified tag name before split;
+		 *  2. Just split up the surrounding blockLimit element unless it's already inside <body>.
+		 * @param {String} blockTag The tag name
+		 */
 		splitBlock : function( blockTag )
 		{
 			var startPath	= new CKEDITOR.dom.elementPath( this.startContainer ),
@@ -1413,13 +1422,17 @@
 			var startBlockLimit	= startPath.blockLimit,
 				endBlockLimit	= endPath.blockLimit;
 
-			var startBlock	= startPath.block,
-				endBlock	= endPath.block;
+			var startBlock	= startPath.block || !blockTag && startBlockLimit,
+				endBlock	= endPath.block || !blockTag && endBlockLimit;
 
 			var elementPath = null;
+
 			// Do nothing if the boundaries are in different block limits.
-			if ( !startBlockLimit.equals( endBlockLimit ) )
+			if ( blockTag && !startBlockLimit.equals( endBlockLimit ) )
 				return null;
+			// Don't split <body>.
+			else if( !blockTag && ( startBlock.is( 'body' ) || endBlock.is( 'body' ) ) )
+				return null;
 
 			// Get or fix current blocks.
 			if ( blockTag != 'br' )
@@ -1473,11 +1486,15 @@
 
 					// In Gecko, the last child node must be a bogus <br>.
 					// Note: bogus <br> added under <ul> or <ol> would cause
-					// lists to be incorrectly rendered.
-					if ( !CKEDITOR.env.ie && !startBlock.is( 'ul', 'ol') )
-						startBlock.appendBogus() ;
+					// lists to be incorrectly rendered, and <br> under <tr>
+					// or <tbody> will bring inconsistency output among browsers.
+					if ( !CKEDITOR.env.ie )
+					{
+						var dtd = CKEDITOR.dtd[ startBlock.getName() ];
+						dtd[ 'br' ] && startBlock.appendBogus() ;
-				}
-			}
+					}
+				}
+			}
 
 			return {
 				previousBlock : startBlock,
Index: _source/core/htmlparser/fragment.js
===================================================================
--- _source/core/htmlparser/fragment.js	(revision 4373)
+++ _source/core/htmlparser/fragment.js	Sat Nov 21 22:10:16 CST 2009
@@ -345,7 +345,7 @@
 
 			checkPending();
 
-			if ( fixForBody && !currentNode.type )
+			if ( fixForBody && CKEDITOR.tools.trim( text ) && !currentNode.type )
 				this.onTagOpen( fixForBody, {} );
 
 			// Shrinking consequential spaces into one single for all elements
