Index: /FCKeditor/trunk/_test/manual/fckdomrangeinterator/test1.html
===================================================================
--- /FCKeditor/trunk/_test/manual/fckdomrangeinterator/test1.html	(revision 809)
+++ /FCKeditor/trunk/_test/manual/fckdomrangeinterator/test1.html	(revision 809)
@@ -0,0 +1,96 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>FCKDomRangeInterator</title>
+	<script src="../../../editor/_source/fckscriptloader.js" type="text/javascript"></script>
+	<script src="../_common/manual_test.js" type="text/javascript"></script>
+	<script type="text/javascript">
+
+var FCK = {} ;
+var FCKConfig = { EnterMode : 'p' } ;
+
+FCKScriptLoader.Load( 'FCKDomRangeInterator' ) ;
+
+	</script>
+	<script type="text/javascript">
+
+FCKListsLib.Setup() ;
+
+var targetWindow ;
+
+function InnerLoaded( innerWindow )
+{
+	targetWindow = innerWindow ;
+}
+
+function GetParagraphs()
+{
+	FCKConfig.EnterMode = document.getElementById( 'xEnterMode' ).value ;
+
+	var interator = FCKDomRangeInterator.CreateFromSelection( targetWindow ) ;
+	interator.ForceBrBreak		= document.getElementById( 'xBrBreak' ).checked ;
+	interator.EnforceRealBlocks	= document.getElementById( 'xRealBlocks' ).checked ;
+	
+	var div = targetWindow.document.createElement( 'div' ) ;
+
+	var msg = '' ;
+	var counter = 0 ;
+	
+	var para ;
+	while ( ( para = interator.GetNextParagraph() ) )		// Only one =
+	{
+		div.appendChild( para.cloneNode( true ) ) ;
+		msg += '\n---\n' + div.innerHTML ;
+		div.innerHTML = '' ;
+
+		counter++ ;
+	}
+	
+	msg = 'Number of ranges: ' + counter + msg ;
+	
+	alert( msg ) ;
+}
+
+	</script>
+</head>
+<body>
+	<h1>
+		FCKDomRangeInterator</h1>
+	<p>
+		Enter Mode:
+		<select id="xEnterMode">
+			<option value='p'>p</option>
+			<option value='br'>br</option>
+			<option value='div'>div</option>
+		</select>
+		&nbsp;&nbsp;&nbsp;
+		<input id="xBrBreak" type="checkbox" /> Force &lt;br&gt; break
+		&nbsp;&nbsp;&nbsp;
+		<input id="xRealBlocks" type="checkbox" /> Enforce real blocks
+	</p>
+	<p>
+		<input type="button" value="Get Paragraphs" onclick="GetParagraphs(); return false;" />
+	</p>
+	<iframe src="test1_inner.html" width="100%" height="450" frameborder="1"></iframe>
+</body>
+</html>
Index: /FCKeditor/trunk/_test/manual/fckdomrangeinterator/test1_inner.html
===================================================================
--- /FCKeditor/trunk/_test/manual/fckdomrangeinterator/test1_inner.html	(revision 809)
+++ /FCKeditor/trunk/_test/manual/fckdomrangeinterator/test1_inner.html	(revision 809)
@@ -0,0 +1,154 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>Test Page</title>
+	<script type="text/javascript">
+
+window.onload = function()
+{
+	if ( (/msie/).test( navigator.userAgent.toLowerCase() ) )
+		document.body.contentEditable = true ;
+	else
+		document.designMode = 'on' ;
+
+	parent.InnerLoaded( window ) ;
+}
+
+	</script>
+</head>
+<body>
+	<h1>
+		Test page for FCKeditor
+	</h1>
+	<p>
+		This document contains various markup features commonly used by content editors
+		or "<span lang="fr">r&eacute;dacteurs de contenu</span>" as they are called in <a
+			href="http://en.wikipedia.org/wiki/France" title="Wikipedia article about France">
+			France</a>.<br />
+		It is important that a <acronym title="what you see is what you get">WYSIWYG</acronym>
+		tool has features that are easily available for the editor. If not, there is a risk
+		that content won't receive <strong>proper</strong> markup. Examples of commonly
+		found content are:</p>
+	<ol>
+		<li>Headings</li>
+		<li style="color: Red">Links (with optional title) </li>
+		<li>Lists (like this one)
+			<ul>
+				<li>including nested lists </li>
+			</ul>
+		</li>
+		<li>Tables
+			<ul>
+				<li>caption</li>
+				<li>headers</li>
+				<li>summary</li>
+			</ul>
+		</li>
+		<li>Language information</li>
+		<li>Acronyms and abbreviations</li>
+		<li>Emphasis and strong emphasis </li>
+		<li>Quotes, inline and block </li>
+		<li>Images</li>
+	</ol>
+	<hr />
+	<h2 style="background-color: Silver">
+		Test procedure
+	</h2>
+	This text has no block tag. It should be corrected when working with the enter key
+	set to "p" or "div" tags. The "br" configuration should not make changes instead.
+	<p>
+		In the test we will try to recreate this document using the editor tools. To make
+		sure tables can be inserted <em>properly</em> we re-visit banana import statistics
+		from 1998.
+	</p>
+	<p>
+		This paragraph has and image at the very end of its contents.<img src="http://www.fckeditor.net/images/logotop.gif"
+			alt="" />
+	</p>
+	This text has no block tag.<br />
+	It should be corrected when working with the enter key
+	set to "p" or "div" tags. The <strong>"br" configuration</strong> should not make
+	changes instead.<br />
+	It has three lines separated by BR.
+	<p>
+		In the test we will try to recreate this document using the editor tools. To make
+		sure tables can be inserted <em>properly</em> we re-visit banana import statistics
+		from 1998.
+	</p>
+	<table summary="Sweden was the top importing country by far in 1998.">
+		<caption>
+			Top banana importers 1998 (value of banana imports in millions of US dollars per
+			million people)<br />
+			<br />
+		</caption>
+		<tr>
+			<th scope="col">
+				Country</th>
+			<th scope="col">
+				Millions of US dollars per million people</th>
+		</tr>
+		<tr>
+			<td>
+				Sweden</td>
+			<td>
+				17.12</td>
+		</tr>
+		<tr>
+			<td>
+				United&nbsp;Kingdom</td>
+			<td>
+				8.88</td>
+		</tr>
+		<tr>
+			<td>
+				Germany</td>
+			<td>
+				8.36</td>
+		</tr>
+		<tr>
+			<td>
+				Italy</td>
+			<td>
+				5.96</td>
+		</tr>
+		<tr>
+			<td>
+				United States</td>
+			<td>
+				4.78</td>
+		</tr>
+	</table>
+	<p>
+		For block quotes we will have a look at <a href="http://fawny.org/rhcp.html">what Joe
+			Clark says about redheads</a>:</p>
+	<blockquote cite="http://fawny.org/rhcp.html#me">
+		<p>
+			"Since boyhood I&rsquo;ve always believed, at the deepest level, that redheads are
+			standard-bearers of the grandest and most wondrous human beauty."</p>
+	</blockquote>
+	<p>
+		<img src="http://www.fckeditor.net/images/logotop.gif" alt="" /></p>
+	<p>
+		The above is the FCKeditor logo loaded from the FCKeditor.net web site.</p>
+</body>
+</html>
Index: /FCKeditor/trunk/editor/_source/classes/fckdomrange.js
===================================================================
--- /FCKeditor/trunk/editor/_source/classes/fckdomrange.js	(revision 808)
+++ /FCKeditor/trunk/editor/_source/classes/fckdomrange.js	(revision 809)
@@ -26,4 +26,5 @@
 {
 	this.Window = sourceWindow ;
+	this._Cache = {} ;
 }
 
@@ -61,5 +62,5 @@
 				while ( eEndNode && !eEndNode.previousSibling )
 					eEndNode = eEndNode.parentNode ;
-				
+
 				eEndNode = eEndNode.previousSibling ;
 			}
@@ -72,4 +73,6 @@
 			this.EndBlockLimit		= oElementPath.BlockLimit ;
 		}
+
+		this._Cache = {} ;
 	},
 
@@ -173,4 +176,9 @@
 	CheckStartOfBlock : function()
 	{
+		var bIsStartOfBlock = this._Cache.IsStartOfBlock ;
+
+		if ( bIsStartOfBlock != undefined )
+			return bIsStartOfBlock ;
+
 		// Create a clone of the current range.
 		var oTestRange = this.Clone() ;
@@ -182,13 +190,18 @@
 		oTestRange.SetStart( oTestRange.StartBlock || oTestRange.StartBlockLimit, 1 ) ;
 
-		var bIsStartOfBlock = oTestRange.CheckIsEmpty() ;
+		bIsStartOfBlock = oTestRange.CheckIsEmpty() ;
 
 		oTestRange.Release() ;
 
-		return bIsStartOfBlock ;
+		return ( this._Cache.IsStartOfBlock = bIsStartOfBlock ) ;
 	},
 
 	CheckEndOfBlock : function( refreshSelection )
 	{
+		var bIsEndOfBlock = this._Cache.IsEndOfBlock ;
+
+		if ( bIsEndOfBlock != undefined )
+			return bIsEndOfBlock ;
+
 		// Create a clone of the current range.
 		var oTestRange = this.Clone() ;
@@ -200,5 +213,5 @@
 		oTestRange.SetEnd( oTestRange.EndBlock || oTestRange.EndBlockLimit, 2 ) ;
 
-		var bIsEndOfBlock = oTestRange.CheckIsCollapsed() ;
+		bIsEndOfBlock = oTestRange.CheckIsCollapsed() ;
 
 		if ( !bIsEndOfBlock )
@@ -232,5 +245,5 @@
 			this.Select() ;
 
-		return bIsEndOfBlock ;
+		return this._Cache.IsEndOfBlock = bIsEndOfBlock ;
 	},
 
@@ -432,5 +445,5 @@
 				oRange.setStartAfter( targetElement ) ;
 		}
-		
+
 		if ( !noInfoUpdate )
 			this._UpdateElementInfo() ;
@@ -530,5 +543,5 @@
 			case 'list_contents' :
 				var boundarySet = FCKListsLib.BlockBoundaries ;
-				if ( unit == 'list_contents' )
+				if ( unit == 'list_contents' || FCKConfig.EnterMode == 'br' )
 					boundarySet = FCKListsLib.ListBoundaries ;
 
@@ -547,11 +560,11 @@
 					// We must look for the left boundary, relative to the range
 					// start, which is limited by a block element.
-					while ( oNode 
-							&& ( oNode.nodeType != 1 
+					while ( oNode
+							&& ( oNode.nodeType != 1
 								|| ( oNode != this.StartBlockLimit
 									&& !boundarySet[ oNode.nodeName.toLowerCase() ] ) ) )
 					{
 						this._Range.setStartBefore( oNode ) ;
-						
+
 						if ( oNode == oNode.parentNode.firstChild && boundarySet[ oNode.parentNode.nodeName.toLowerCase() ] )
 							break ;
@@ -571,7 +584,7 @@
 					// We must look for the right boundary, relative to the range
 					// end, which is limited by a block element.
-					while ( oNode 
-							&& ( oNode.nodeType != 1 
-								|| ( oNode != this.StartBlockLimit 
+					while ( oNode
+							&& ( oNode.nodeType != 1
+								|| ( oNode != this.StartBlockLimit
 									&& !boundarySet[ oNode.nodeName.toLowerCase() ] ) ) )
 					{
@@ -583,8 +596,8 @@
 						oNode = FCKDomTools.GetNextSourceNode( oNode, true ) ;
 					}
-					
+
 					// In EnterMode='br', the end <br> boundary element must
 					// be included in the expanded range.
-					if ( oNode && oNode.nodeName.toLowerCase() == 'br' ) 
+					if ( oNode && oNode.nodeName.toLowerCase() == 'br' )
 						this._Range.setEndAfter( oNode ) ;
 				}
@@ -598,4 +611,24 @@
 	},
 
+	/**
+	 * Split the block element for the current range. It deletes the contents
+	 * of the range and splits the block in the collapsed position, resulting
+	 * in two sucessive blocks. The range is then positioned in the middle of
+	 * them.
+	 *
+	 * It returns and object with the following properties:
+	 *		- PreviousBlock	: a reference to the block element that preceeds
+	 *		  the range after the split.
+	 *		- NextBlock : a reference to the block element that preceeds the
+	 *		  range after the split.
+	 *		- WasStartOfBlock : a boolean indicating that the range was
+	 *		  originaly at the start of the block.
+	 *		- WasEndOfBlock : a boolean indicating that the range was originaly
+	 *		  at the end of the block.
+	 *
+	 * If the range was originaly at the start of the block, no split will happen
+	 * and the PreviousBlock value will be null. The same is valid for the
+	 * NextBlock value if the range was at the end of the block.
+	 */
 	SplitBlock : function()
 	{
@@ -603,5 +636,5 @@
 			this.MoveToSelection() ;
 
-		// The selection boundaries must be in the same "block limit" element.
+		// The range boundaries must be in the same "block limit" element.
 		if ( this.StartBlockLimit == this.EndBlockLimit )
 		{
@@ -622,8 +655,9 @@
 			}
 
+			// Get the range position.
 			var bIsStartOfBlock	= ( eStartBlock != null && this.CheckStartOfBlock() ) ;
 			var bIsEndOfBlock	= ( eEndBlock != null && this.CheckEndOfBlock() ) ;
 
-			// Delete the current selection.
+			// Delete the current contents.
 			if ( !this.CheckIsEmpty() )
 				this.DeleteContents() ;
@@ -720,4 +754,5 @@
 		this.EndBlockLimit = null ;
 		this._Range = null ;
+		this._Cache = null ;
 	},
 
@@ -727,4 +762,5 @@
 	},
 
+	// TODO : Remove this one, in favor of FCKDomRangeInterator.GetNextParagraph.
 	GetParagraphs : function( forceBreakBr )
 	{
@@ -737,5 +773,5 @@
 		else
 			range.Expand( 'block_contents' ) ;
-	
+
 		var currentNode	= range.StartNode || range.StartContainer ;
 		var lastNode	= range.EndNode || range.EndContainer.lastChild || range.EndContainer ;
@@ -744,6 +780,6 @@
 		if ( forceBreakBr )
 			boundarySet = FCKListsLib.ListBoundaries ;
-		
-		// Let's reuse this range 
+
+		// Let's reuse this range
 		range = null ;
 
@@ -753,11 +789,11 @@
 			// so the range must be appended to the list.
 			var closeRange = false ;
-			
+
 			var continueFromSibling = false ;
-			
+
 			// includeNode indicates that the current node is good to be part
 			// of the range.
 			var includeNode = ( currentNode.nodeType != 1 ) ;
-			
+
 			// If it is an element node, let's check if it can be part of the
 			// range.
@@ -765,5 +801,5 @@
 			{
 				var nodeName = currentNode.nodeName.toLowerCase() ;
-				
+
 				if ( boundarySet[ nodeName ] )
 				{
@@ -772,5 +808,5 @@
 					if ( nodeName == 'br' )
 						includeNode = true ;
-				
+
 					closeRange = true ;
 				}
@@ -793,5 +829,5 @@
 					includeNode = false ;
 			}
-			
+
 			// The current node is good to be part of the range and we are
 			// starting a new range, initialize it first.
@@ -801,5 +837,5 @@
 				range.SetStart( currentNode, 3, true ) ;
 			}
-				
+
 			// If we are in an element boundary, let's check if it is time
 			// to close the range, otherwise we include the parent within it.
@@ -811,17 +847,17 @@
 					if ( boundarySet[ parentNode.nodeName.toLowerCase() ] )
 					{
-						closeRange = true ;		
+						closeRange = true ;
 						break ;
 					}
-					
+
 					currentNode = parentNode ;
 					continueFromSibling = true ;
 				}
 			}
-			
+
 			// Now finally include the node.
 			if ( includeNode )
 				range.SetEnd( currentNode, 4, true ) ;
-			
+
 			// We have found a block boundary. Let's add the range to the list,
 			// and prepare it for the next one.
@@ -832,9 +868,9 @@
 				range = null ;
 			}
-			
+
 			// Stop processing if this is the last one.
 			if ( currentNode == lastNode )
 				break ;
-			
+
 			currentNode = FCKDomTools.GetNextSourceNode( currentNode, continueFromSibling ) ;
 		}
Index: /FCKeditor/trunk/editor/_source/classes/fckdomrangeinterator.js
===================================================================
--- /FCKeditor/trunk/editor/_source/classes/fckdomrangeinterator.js	(revision 809)
+++ /FCKeditor/trunk/editor/_source/classes/fckdomrangeinterator.js	(revision 809)
@@ -0,0 +1,271 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This class can be used to interate through nodes inside a range.
+ *
+ * During interation, the provided range can become invalid, due to document
+ * mutations, so CreateBookmark() used to restore it after processing, if
+ * needed.
+ */
+
+var FCKDomRangeInterator = function( range )
+{
+	/**
+	 * The FCKDomRange object that marks the interation boundaries.
+	 */
+	this.Range = range ;
+
+	/**
+	 * Indicates that <br> elements must be used as paragraph boundaries.
+	 */
+	this.ForceBrBreak = false ;
+	
+	/**
+	 * Guarantees that the interator will always return "real" block elements.
+	 * If "false", elements like <li>, <th> and <td> are returned. If "true", a
+	 * dedicated block element block element will be created inside those
+	 * elements to hold the selected content.
+	 */
+	this.EnforceRealBlocks = false ;
+}
+
+FCKDomRangeInterator.CreateFromSelection = function( targetWindow )
+{
+	var range = new FCKDomRange( targetWindow ) ;
+	range.MoveToSelection() ;
+	return new FCKDomRangeInterator( range ) ;
+}
+
+FCKDomRangeInterator.prototype =
+{
+	/**
+	 * Get the next paragraph element. It automatically breaks the document
+	 * when necessary to generate block elements for the paragraphs.
+	 */
+	GetNextParagraph : function()
+	{
+		var block ;
+		var range ;
+		var isLast ;
+
+		var boundarySet = this.ForceBrBreak ? FCKListsLib.ListBoundaries : FCKListsLib.BlockBoundaries ;
+
+		// This is the first interaction. Let's initialize it.
+		if ( !this._LastNode )
+		{
+			var range = this.Range.Clone() ;
+			range.Expand( this.ForceBrBreak ? 'list_contents' : 'block_contents' ) ;
+
+			this._NextNode = range.StartNode ;
+			this._LastNode = range.EndNode ;
+
+			// Let's reuse this variable.
+			range = null ;
+		}
+
+		var currentNode = this._NextNode ;
+		var lastNode = this._LastNode ;
+
+		while ( currentNode )
+		{
+			// closeRange indicates that a paragraph boundary has been found,
+			// so the range can be closed.
+			var closeRange = false ;
+
+			// includeNode indicates that the current node is good to be part
+			// of the range. By default, any non-element node is ok for it.
+			var includeNode = ( currentNode.nodeType != 1 ) ;
+
+			var continueFromSibling = false ;
+
+			// If it is an element node, let's check if it can be part of the
+			// range.
+			if ( !includeNode )
+			{
+				var nodeName = currentNode.nodeName.toLowerCase() ;
+
+				if ( boundarySet[ nodeName ] )
+				{
+					// <br> boundaries must be part of the range. It will
+					// happen only if ForceBrBreak.
+					if ( nodeName == 'br' )
+						includeNode = true ;
+					else if ( !range && currentNode.childNodes.length == 0 && nodeName != 'hr' )
+					{
+						// If we have found an empty block, and haven't started
+						// the range yet, it means we must return this block.
+						block = currentNode ;
+						break ;
+					}
+
+					closeRange = true ;
+				}
+				else
+				{
+					// If we have child nodes, let's check them.
+					if ( currentNode.firstChild )
+					{
+						// If we don't have a range yet, let's start it.
+						if ( !range )
+						{
+							range = new FCKDomRange( this.Range.Window ) ;
+							range.SetStart( currentNode, 3, true ) ;
+						}
+
+						currentNode = currentNode.firstChild ;
+						continue ;
+					}
+					includeNode = true ;
+				}
+			}
+			else if ( currentNode.nodeType == 3 )
+			{
+				// Ignore normal whitespaces (i.e. not including &nbsp; or
+				// other unicode whitespaces) before/after a block node.
+				if ( /^[\r\n\t ]+$/.test( currentNode.nodeValue ) )
+					includeNode = false ;
+			}
+
+			// The current node is good to be part of the range and we are
+			// starting a new range, initialize it first.
+			if ( includeNode && !range )
+			{
+				range = new FCKDomRange( this.Range.Window ) ;
+				range.SetStart( currentNode, 3, true ) ;
+			}
+
+			// The last node has been found.		
+			isLast = ( currentNode == lastNode ) ;
+
+			// If we are in an element boundary, let's check if it is time
+			// to close the range, otherwise we include the parent within it.
+			if ( range && !closeRange )
+			{
+				var parentNode = currentNode.parentNode ;
+				while ( currentNode == parentNode.lastChild && !isLast )
+				{
+					if ( boundarySet[ parentNode.nodeName.toLowerCase() ] )
+					{
+						closeRange = true ;
+						break ;
+					}
+
+					currentNode = parentNode ;
+					continueFromSibling = true ;
+				}
+			}
+
+			// Now finally include the node.
+			if ( includeNode )
+				range.SetEnd( currentNode, 4, true ) ;
+
+			// We have found a block boundary. Let's close the range and move out of the
+			// loop.
+			if ( ( closeRange && range ) || isLast )
+			{
+				if ( range )
+					range._UpdateElementInfo() ;
+
+				break ;
+			}
+
+			currentNode = FCKDomTools.GetNextSourceNode( currentNode, continueFromSibling ) ;
+		}
+
+		// Now, based on the processed range, look for (or create) the block to be returned.
+		if ( !block )
+		{
+			// If no range has been found, this is the end.
+			if ( !range )
+			{
+				this._NextNode = null ;
+				return null ;
+			}
+
+			block = range.StartBlock ;
+
+			if ( !block
+				&& !this.EnforceRealBlocks
+				&& range.StartBlockLimit.nodeName.IEquals( 'DIV', 'TH', 'TD' )
+				&& range.CheckStartOfBlock()
+				&& range.CheckEndOfBlock() )
+			{
+				block = range.StartBlockLimit ;
+			}
+			else if ( !block || ( this.EnforceRealBlocks && block.nodeName.toLowerCase() == 'li' ) )
+			{
+				// Create the fixed block.
+				block = this.Range.Window.document.createElement( FCKConfig.EnterMode == 'p' ? 'p' : 'div' ) ;
+
+				// Move the contents of the temporary range to the fixed block.
+				range.ExtractContents().AppendTo( block ) ;
+				FCKDomTools.TrimNode( block ) ;
+
+				// Insert the fixed block into the DOM.
+				range.InsertNode( block ) ;
+				
+				// When fixing a block, we can safely remove any remaining <br>
+				// before of it.
+				var previousSibling = block.previousSibling ;
+				if ( previousSibling && previousSibling.nodeType == 1 && previousSibling.nodeName.toLowerCase() == 'br' )
+					previousSibling.parentNode.removeChild( previousSibling ) ;
+			}
+			else if ( block.nodeName.toLowerCase() != 'li' )
+			{
+				// If the range doesn't includes the entire contents of the
+				// block, we must split it, isolating the range in a dedicated
+				// block.
+				if ( !range.CheckStartOfBlock() || !range.CheckEndOfBlock() )
+				{
+					// The resulting block will be a clone of the current one.
+					block = block.cloneNode( false ) ;
+
+					// Extract the range contents, moving it to the new block.
+					range.ExtractContents().AppendTo( block ) ;
+					FCKDomTools.TrimNode( block ) ;
+
+					// Split the block. At this point, the range will be in the
+					// right position for our intents.
+					range.SplitBlock() ;
+
+					// Insert the new block into the DOM.
+					range.InsertNode( block ) ;
+				}
+			}
+			else if ( !isLast )
+			{
+				// LIs are returned as is, with all their children (due to the
+				// nested lists). But, the next node is the node right after
+				// the current range, which could be an <li> child (nested
+				// lists) or the next sibling <li>.
+				
+				this._NextNode = FCKDomTools.GetNextSourceNode( range.EndNode, true ) ;
+				return block ;
+			}
+		}
+
+		// Get a reference for the next element. This is important because the
+		// above block can be removed or changed, so we can rely on it for the
+		// next interation.
+		this._NextNode = isLast ? null : FCKDomTools.GetNextSourceNode( block, true ) ;
+
+		return block ;
+	}
+} ;
Index: /FCKeditor/trunk/editor/_source/fckscriptloader.js
===================================================================
--- /FCKeditor/trunk/editor/_source/fckscriptloader.js	(revision 808)
+++ /FCKeditor/trunk/editor/_source/fckscriptloader.js	(revision 809)
@@ -98,4 +98,5 @@
 FCKScriptLoader.AddScript( 'FCKDocumentFragment', 'classes/'	, ['FCKDomTools'], FCK_SPECIFIC ) ;
 FCKScriptLoader.AddScript( 'FCKDomRange'		, 'classes/'	, ['FCKBrowserInfo','FCKJSCoreExtensions','FCKW3CRange','FCKElementPath','FCKDomTools','FCKTools','FCKDocumentFragment'], FCK_GENERIC_SPECIFIC ) ;
+FCKScriptLoader.AddScript( 'FCKDomRangeInterator', 'classes/'	, ['FCKDomRange','FCKListsLib'], FCK_GENERIC ) ;
 FCKScriptLoader.AddScript( 'FCKElementPath'		, 'classes/'	, ['FCKListsLib'], FCK_GENERIC ) ;
 FCKScriptLoader.AddScript( 'FCKEnterKey'		, 'classes/'	, ['FCKDomRange','FCKDomTools','FCKTools','FCKKeystrokeHandler','FCKListHandler'], FCK_GENERIC ) ;
Index: /FCKeditor/trunk/editor/_source/internals/fcklistslib.js
===================================================================
--- /FCKeditor/trunk/editor/_source/internals/fcklistslib.js	(revision 808)
+++ /FCKeditor/trunk/editor/_source/internals/fcklistslib.js	(revision 809)
@@ -57,5 +57,5 @@
 	// Elements used to separate block contents.
 	BlockBoundaries : { p:1,div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,address:1,pre:1,ol:1,ul:1,li:1,dt:1,de:1,table:1,thead:1,tbody:1,tfoot:1,tr:1,th:1,td:1,caption:1,col:1,colgroup:1,blockquote:1,body:1 },
-	ListBoundaries : { p:1,div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,address:1,pre:1,ol:1,ul:1,li:1,dt:1,de:1,table:1,thead:1,tbody:1,tfoot:1,tr:1,th:1,td:1,caption:1,col:1,colgroup:1,blockquote:1,br:1,body:1 },
+	ListBoundaries  : { p:1,div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,address:1,pre:1,ol:1,ul:1,li:1,dt:1,de:1,table:1,thead:1,tbody:1,tfoot:1,tr:1,th:1,td:1,caption:1,col:1,colgroup:1,blockquote:1,body:1,br:1 },
 
 	// Final setup of FCKListsLib once the editor is loaded (at FCK.StartEditor).
@@ -65,6 +65,6 @@
 	Setup : function()
 	{
-		// <div> is considered a block element only if EnterMode=div, otherwise it is a block limit.
-		if ( FCKConfig.EnterMode == 'div' )
+		// <div> is not considered a block element if EnterMode=p, it is a block limit in this case.
+		if ( FCKConfig.EnterMode != 'p' )
 		{
 			this.PathBlockElements.div = 1 ;
@@ -73,7 +73,4 @@
 		else
 			this.PathBlockLimitElements.div = 1 ;
-		
-		if ( FCKConfig.EnterMode == 'br' )
-			this.BlockBoundaries.br = 1 ;
 	}
 } ;
Index: /FCKeditor/trunk/editor/fckeditor.html
===================================================================
--- /FCKeditor/trunk/editor/fckeditor.html	(revision 808)
+++ /FCKeditor/trunk/editor/fckeditor.html	(revision 809)
@@ -96,4 +96,5 @@
 LoadScript( '_source/classes/fckw3crange.js' ) ;
 LoadScript( '_source/classes/fckdomrange_' + sSuffix + '.js' ) ;
+LoadScript( '_source/classes/fckdomrangeinterator.js' ) ;
 LoadScript( '_source/classes/fckenterkey.js' ) ;
 
Index: /FCKeditor/trunk/fckpackager.xml
===================================================================
--- /FCKeditor/trunk/fckpackager.xml	(revision 808)
+++ /FCKeditor/trunk/fckpackager.xml	(revision 809)
@@ -104,4 +104,5 @@
 		<File path="editor/_source/classes/fckdomrange.js" />
 		<File path="editor/_source/classes/fckdomrange_ie.js" />
+		<File path="editor/_source/classes/fckdomrangeinterator.js" />
 		<File path="editor/_source/classes/fckdocumentfragment_ie.js" />
 		<File path="editor/_source/classes/fckw3crange.js" />
@@ -196,4 +197,5 @@
 		<File path="editor/_source/classes/fckdomrange.js" />
 		<File path="editor/_source/classes/fckdomrange_gecko.js" />
+		<File path="editor/_source/classes/fckdomrangeinterator.js" />
 		<File path="editor/_source/classes/fckdocumentfragment_gecko.js" />
 		<File path="editor/_source/classes/fckw3crange.js" />
