Index: /FCKeditor/branches/versions/2.4.x/_dev/browserbugs/opera/textarea.html
===================================================================
--- /FCKeditor/branches/versions/2.4.x/_dev/browserbugs/opera/textarea.html	(revision 213)
+++ /FCKeditor/branches/versions/2.4.x/_dev/browserbugs/opera/textarea.html	(revision 213)
@@ -0,0 +1,229 @@
+﻿<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+	We must be in quirks mode.
+-->
+<html>
+<head>
+	<title>Opera Bug</title>
+	<meta content="noindex, nofollow" name="robots" />
+	<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+	<!--
+		Remove the following <link> and it will magically work with Opera.
+		It doesn't need to point to a valid css.
+	-->
+	<link href="xxx.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+	<table cellspacing="0" cellpadding="0" style="height: 100%; width: 100%">
+		<tbody>
+			<tr>
+				<td>
+					<textarea style="height: 100%; width: 100%;">This textarea must fill the page, having its own scrollbar.
+It works well with IE and Firefox.
+Line 0
+Line 1
+Line 2
+Line 3
+Line 4
+Line 5
+Line 6
+Line 7
+Line 8
+Line 9
+Line 10
+Line 11
+Line 12
+Line 13
+Line 14
+Line 15
+Line 16
+Line 17
+Line 18
+Line 19
+Line 20
+Line 21
+Line 22
+Line 23
+Line 24
+Line 25
+Line 26
+Line 27
+Line 28
+Line 29
+Line 30
+Line 31
+Line 32
+Line 33
+Line 34
+Line 35
+Line 36
+Line 37
+Line 38
+Line 39
+Line 40
+Line 41
+Line 42
+Line 43
+Line 44
+Line 45
+Line 46
+Line 47
+Line 48
+Line 49
+Line 50
+Line 51
+Line 52
+Line 53
+Line 54
+Line 55
+Line 56
+Line 57
+Line 58
+Line 59
+Line 60
+Line 61
+Line 62
+Line 63
+Line 64
+Line 65
+Line 66
+Line 67
+Line 68
+Line 69
+Line 70
+Line 71
+Line 72
+Line 73
+Line 74
+Line 75
+Line 76
+Line 77
+Line 78
+Line 79
+Line 80
+Line 81
+Line 82
+Line 83
+Line 84
+Line 85
+Line 86
+Line 87
+Line 88
+Line 89
+Line 90
+Line 91
+Line 92
+Line 93
+Line 94
+Line 95
+Line 96
+Line 97
+Line 98
+Line 99
+Line 100
+Line 101
+Line 102
+Line 103
+Line 104
+Line 105
+Line 106
+Line 107
+Line 108
+Line 109
+Line 110
+Line 111
+Line 112
+Line 113
+Line 114
+Line 115
+Line 116
+Line 117
+Line 118
+Line 119
+Line 120
+Line 121
+Line 122
+Line 123
+Line 124
+Line 125
+Line 126
+Line 127
+Line 128
+Line 129
+Line 130
+Line 131
+Line 132
+Line 133
+Line 134
+Line 135
+Line 136
+Line 137
+Line 138
+Line 139
+Line 140
+Line 141
+Line 142
+Line 143
+Line 144
+Line 145
+Line 146
+Line 147
+Line 148
+Line 149
+Line 150
+Line 151
+Line 152
+Line 153
+Line 154
+Line 155
+Line 156
+Line 157
+Line 158
+Line 159
+Line 160
+Line 161
+Line 162
+Line 163
+Line 164
+Line 165
+Line 166
+Line 167
+Line 168
+Line 169
+Line 170
+Line 171
+Line 172
+Line 173
+Line 174
+Line 175
+Line 176
+Line 177
+Line 178
+Line 179
+Line 180
+Line 181
+Line 182
+Line 183
+Line 184
+Line 185
+Line 186
+Line 187
+Line 188
+Line 189
+Line 190
+Line 191
+Line 192
+Line 193
+Line 194
+Line 195
+Line 196
+Line 197
+Line 198
+Line 199
+</textarea>
+				</td>
+			</tr>
+		</tbody>
+	</table>
+</body>
+</html>
Index: /FCKeditor/branches/versions/2.4.x/_dev/browserbugs/safari/createContextualFragment.html
===================================================================
--- /FCKeditor/branches/versions/2.4.x/_dev/browserbugs/safari/createContextualFragment.html	(revision 213)
+++ /FCKeditor/branches/versions/2.4.x/_dev/browserbugs/safari/createContextualFragment.html	(revision 213)
@@ -0,0 +1,30 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>Untitled Page</title>
+	<script type="text/javascript">
+
+function InsertHtml()
+{
+	// Get the current selection.
+	var oSel = window.getSelection() ;
+
+	// Get the first available range.
+	var oRange = oSel.getRangeAt(0) ;
+
+	// Create a fragment with the input HTML.
+	var oFragment = oRange.createContextualFragment( '- This is a <b>test</b> -' ) ;
+
+	oRange.insertNode(oFragment) ;
+}
+	</script>
+</head>
+<body>
+	<p>
+		This is some text. Select some text and click the following button to insert HTML on it.
+	</p>
+	<p>
+		<input type="button" value="Insert HTML" onclick="InsertHtml();" />
+	</p>
+</body>
+</html>
Index: /FCKeditor/branches/versions/2.4.x/_dev/browserbugs/safari/hr_undefined.html
===================================================================
--- /FCKeditor/branches/versions/2.4.x/_dev/browserbugs/safari/hr_undefined.html	(revision 213)
+++ /FCKeditor/branches/versions/2.4.x/_dev/browserbugs/safari/hr_undefined.html	(revision 213)
@@ -0,0 +1,23 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>Safari Bugs - HR with id=false</title>
+	<script type="text/javascript">
+
+window.onload = function()
+{
+	document.designMode = 'on' ;
+	
+	// This alert is here just to place the focus in the editable document.
+	alert( 'Click OK to insert the <hr>' ) ;	
+
+	document.execCommand( 'InsertHorizontalRule' ) ;
+	
+	alert( 'The resulting HTML is: \n' + document.body.innerHTML + '\nThe desired HTML is:\n<hr />'  ) ;
+}
+
+	</script>
+</head>
+<body>
+</body>
+</html>
Index: /FCKeditor/branches/versions/2.4.x/_dev/browserbugs/safari/input_hidden.html
===================================================================
--- /FCKeditor/branches/versions/2.4.x/_dev/browserbugs/safari/input_hidden.html	(revision 213)
+++ /FCKeditor/branches/versions/2.4.x/_dev/browserbugs/safari/input_hidden.html	(revision 213)
@@ -0,0 +1,30 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>Safari Bugs - Input type hidden</title>
+	<style type="text/css">
+
+input[type="hidden"], span[title="Test"]
+{
+	display: inline;
+	width:20px;
+	height:20px;
+	border:1px dotted #FF0000 ;
+	background-image: url(http://www.fckeditor.net/fckeditor/editor/css/behaviors/hiddenfield.gif);
+	background-repeat: no-repeat;
+}
+
+input[type="hidden"]:after, span[title="Test"]:after
+{
+	padding-left: 20px;
+	content: "" ;
+}
+
+	</style>
+</head>
+<body>
+	<input type="hidden" />
+	<hr />
+	<span title="Test">&nbsp;</span>
+</body>
+</html>
Index: /FCKeditor/branches/versions/2.4.x/_test/manual/fckeditingarea/test1.html
===================================================================
--- /FCKeditor/branches/versions/2.4.x/_test/manual/fckeditingarea/test1.html	(revision 212)
+++ /FCKeditor/branches/versions/2.4.x/_test/manual/fckeditingarea/test1.html	(revision 213)
@@ -79,6 +79,4 @@
 	var _BehaviorsStyle = '<style type="text/css" _fcktemp="true">' ;
 
-	_BehaviorsStyle += 'INPUT { behavior: url(' + sBasePath + 'editor/css/behaviors/hiddenfield.htc) ; } ' ;
-
 	_BehaviorsStyle += 'TABLE { behavior: url(' + sBasePath + 'editor/css/behaviors/showtableborders.htc) ; }' ;
 
Index: /FCKeditor/branches/versions/2.4.x/_whatsnew.html
===================================================================
--- /FCKeditor/branches/versions/2.4.x/_whatsnew.html	(revision 212)
+++ /FCKeditor/branches/versions/2.4.x/_whatsnew.html	(revision 213)
@@ -93,8 +93,26 @@
 		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/112">#112</a>] The enter
 			key now behaves correctly on lists with Firefox, when the EnterMode is set to 'br'.</li>
-		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/112">#152</a>] Invalid
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/152">#152</a>] Invalid
 			self-closing tags are now being fixed before loading. </li>
 		<li>A few tags were being ignored to the check for required contents (not getting stripped
 			out, as expected). Fixed.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/202">#202</a>] The HR
+			tag will not anymore break the contents loaded in the editor.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/211">#211</a>] Some invalid
+			inputs, like "&lt;p&gt;" where making the caret disappear in Firefox.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/99">#99</a>] The &lt;div&gt;
+			element is now considered a block container if EnterMode=p|br. It acts like a simple
+			block only if EnterMode=div.</li>
+		<li>Hidden fields will now show up as an icon in IE, instead of a normal text field.
+			They are also selectable and draggable, in all browsers.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/213">#213</a>] Styles
+			are now preserved when hitting enter at the end of a paragraph.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/77">#77</a>] If ShiftEnterMode
+			is set to a block tag (p or div), the desired block creation in now enforced, instead
+			of copying the current block (which is still the behavior of the simple enter).</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/209">#209</a>] Links and
+			images URLs will now be correctly preserved with Netscape 7.1.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/165">#165</a>] The enter
+			key now honors the EnterMode settings when outdenting a list item.</li>
 	</ul>
 	<h3>
Index: /FCKeditor/branches/versions/2.4.x/editor/_source/classes/fckdomrange.js
===================================================================
--- /FCKeditor/branches/versions/2.4.x/editor/_source/classes/fckdomrange.js	(revision 212)
+++ /FCKeditor/branches/versions/2.4.x/editor/_source/classes/fckdomrange.js	(revision 213)
@@ -118,4 +118,17 @@
 	},
 
+	// Moves to the first editing point inside a element. For example, in a
+	// element tree like "<p><b><i></i></b> Text</p>", the start editing point
+	// is "<p><b><i>^</i></b> Text</p>" (inside <i>).
+	MoveToElementEditStart : function( targetElement )
+	{
+		var child ;
+
+		while ( ( child = targetElement.firstChild ) && child.nodeType == 1 && FCKListsLib.EmptyElements[ child.nodeName.toLowerCase() ] == null )
+			targetElement = child ;
+
+		this.MoveToElementStart( targetElement ) ;
+	},
+
 	InsertNode : function( node )
 	{
@@ -167,6 +180,31 @@
 		oTestRange.SetEnd( oTestRange.EndBlock || oTestRange.EndBlockLimit, 2 ) ;
 
-		var bIsEndOfBlock = oTestRange.CheckIsEmpty( true ) ;
-
+		var bIsEndOfBlock = oTestRange.CheckIsCollapsed() ;
+		
+		if ( !bIsEndOfBlock )
+		{
+			// Inserts the contents of the range in a div tag.
+			var eToolDiv = this.Window.document.createElement( 'div' ) ;
+			oTestRange._Range.cloneContents().AppendTo( eToolDiv ) ;
+			FCKDomTools.TrimNode( eToolDiv, true ) ;
+			
+			// Find out if we are in an empty tree of inline elements, like <b><i><span></span></i></b>
+			bIsEndOfBlock = true ;
+			var eLastChild = eToolDiv ;
+			while ( ( eLastChild = eLastChild.lastChild ) )
+			{
+				// Check the following:
+				//		1. Is there more than one node in the parents children?
+				//		2. Is the node not an element node?
+				//		3. Is it not a inline element.
+				if ( eLastChild.previousSibling || eLastChild.nodeType != 1 || FCKListsLib.InlineChildReqElements[ eLastChild.nodeName.toLowerCase() ] == null )
+				{
+					// So we are not in the end of the range.
+					bIsEndOfBlock = false ;
+					break ;
+				}
+			}
+		}
+		
 		oTestRange.Release() ;
 
Index: /FCKeditor/branches/versions/2.4.x/editor/_source/classes/fckeditingarea.js
===================================================================
--- /FCKeditor/branches/versions/2.4.x/editor/_source/classes/fckeditingarea.js	(revision 212)
+++ /FCKeditor/branches/versions/2.4.x/editor/_source/classes/fckeditingarea.js	(revision 213)
@@ -216,4 +216,6 @@
 		if ( this.Mode == FCK_EDITMODE_WYSIWYG )
 		{
+			// The following check is important to avoid IE entering in a focus loop. Ref:
+			// http://sourceforge.net/tracker/index.php?func=detail&aid=1567060&group_id=75348&atid=543653
 			if ( FCKBrowserInfo.IsIE && this.Document.hasFocus() )
 				return ;
Index: /FCKeditor/branches/versions/2.4.x/editor/_source/classes/fckelementpath.js
===================================================================
--- /FCKeditor/branches/versions/2.4.x/editor/_source/classes/fckelementpath.js	(revision 212)
+++ /FCKeditor/branches/versions/2.4.x/editor/_source/classes/fckelementpath.js	(revision 213)
@@ -42,14 +42,16 @@
 			var sElementName = e.nodeName.toLowerCase() ;
 
-			if ( !eBlockLimit && !eBlock && FCKListsLib.PathBlockElements[ sElementName ] != null )
-				eBlock = e ;
+			if ( !eBlockLimit )
+			{
+				if ( !eBlock && FCKListsLib.PathBlockElements[ sElementName ] != null )
+					eBlock = e ;
 
-			// TODO: Review the Regex and move it to the RegexLib.
-			if ( !eBlockLimit && (/^(?:body|td|th|caption|form)$/).test( sElementName ) )
-				eBlockLimit = e ;
+				if ( FCKListsLib.PathBlockLimitElements[ sElementName ] != null )
+					eBlockLimit = e ;
+			}
 
 			aElements.push( e ) ;
 
-			if ( sElementName == 'BODY' )
+			if ( sElementName == 'body' )
 				break ;
 		}
@@ -62,2 +64,3 @@
 }
 
+
Index: /FCKeditor/branches/versions/2.4.x/editor/_source/classes/fckenterkey.js
===================================================================
--- /FCKeditor/branches/versions/2.4.x/editor/_source/classes/fckenterkey.js	(revision 212)
+++ /FCKeditor/branches/versions/2.4.x/editor/_source/classes/fckenterkey.js	(revision 213)
@@ -57,6 +57,8 @@
 	var oEnterKey = this._EnterKey ;
 
+	/* @Packager.RemoveLine
 	try
 	{
+	@Packager.RemoveLine */
 		switch ( keystrokeValue )
 		{
@@ -76,4 +78,5 @@
 				return oEnterKey.DoDelete() ;
 		}
+	/* @Packager.RemoveLine
 	}
 	catch (e)
@@ -82,4 +85,5 @@
 		// ahead with the browser default behavior.
 	}
+	@Packager.RemoveLine */
 
 	return false ;
@@ -176,6 +180,6 @@
 	if ( !previous && currentBlock.nodeName.IEquals( 'LI' ) && currentBlock.parentNode.parentNode.nodeName.IEquals( 'LI' ) )
 	{
-		previous = currentBlock.parentNode.parentNode ;
-		currentBlock = FCKListHandler.OutdentListItem( currentBlock ) ;
+		this._OutdentWithSelection( currentBlock, range ) ;
+		return true ;
 	}
 
@@ -193,8 +197,11 @@
 	if ( previous && currentBlock )
 	{
-		// If we are in a LI, and the previous block is not an LI, we must
+		// If we are in a LI, and the previous block is not an LI, we must outdent it.
 		if ( currentBlock.nodeName.IEquals( 'LI' ) && !previous.nodeName.IEquals( 'LI' ) )
-			currentBlock = FCKListHandler.OutdentListItem( currentBlock ) ;
-
+		{
+			this._OutdentWithSelection( currentBlock, range ) ;
+			return true ;
+		}
+		
 		// Take a reference to the parent for post processing cleanup.
 		var oCurrentParent = currentBlock.parentNode ;
@@ -277,5 +284,5 @@
 	// Get the current selection.
 	var oRange = range || new FCKDomRange( this.Window ) ;
-	
+
 	// If we don't have a range, move it to the selection.
 	if ( !range )
@@ -330,5 +337,5 @@
 
 				// Move the selection to the new block.
-				oRange.MoveToElementStart( eStartBlock ) ;
+				oRange.MoveToElementEditStart( eStartBlock ) ;
 			}
 			else
@@ -342,15 +349,20 @@
 					if ( bIsStartOfBlock && sStartBlockTag == 'LI' )
 					{
-						var eOutdented = FCKListHandler.OutdentListItem( eStartBlock ) ;
-						oRange.MoveToElementStart( eOutdented ) ;
+						this._OutdentWithSelection( eStartBlock, oRange ) ;
+						oRange.Release() ;
+						return true ;
 					}
 					else
 					{
-						// If is a header tag, create a new block element.
-						if ( (/^H[1-6]$/).test( sStartBlockTag ) )
+						// If is a header tag, or we are in a Shift+Enter (#77),
+						// create a new block element.
+						if ( (/^H[1-6]$/).test( sStartBlockTag ) || this._HasShift )
 							eNewBlock = this.Window.document.createElement( blockTag ) ;
 						// Otherwise, duplicate the current block.
 						else
+						{
 							eNewBlock = eStartBlock.cloneNode(false) ;
+							this._RecreateEndingTree( eStartBlock, eNewBlock ) ;
+						}
 
 						if ( FCKBrowserInfo.IsGeckoLike )
@@ -384,8 +396,6 @@
 					{
 						// In Gecko, the last child node must be a bogus <br>.
-						var eLastChild = FCKDomTools.GetLastChild( eNewBlock ) ;
-
-						if ( !eLastChild || eLastChild.nodeName.toLowerCase() != 'br' || eLastChild.getAttribute( 'type', 2 ) != '_moz' )
-							eNewBlock.appendChild( FCKTools.CreateBogusBR( this.Window.document ) ) ;
+						this._AppendBogusBr( eStartBlock ) ;
+						this._AppendBogusBr( eNewBlock ) ;
 					}
 				}
@@ -396,5 +406,5 @@
 
 					// Move the selection to the new block.
-					oRange.MoveToElementStart( eNewBlock ) ;
+					oRange.MoveToElementEditStart( eNewBlock ) ;
 
 					if ( FCKBrowserInfo.IsGecko )
@@ -406,5 +416,5 @@
 		{
 			// Move the selection to the end block.
-			oRange.MoveToElementStart( eEndBlock ) ;
+			oRange.MoveToElementEditStart( eEndBlock ) ;
 		}
 
@@ -471,10 +481,5 @@
 			// If we are at the end of a block, we must be sure the bogus node is available in that block.
 			if ( bIsEndOfBlock && FCKBrowserInfo.IsGecko )
-			{
-				var eLastBr = FCKDomTools.GetLastChild( eBr.parentNode, 'BR' ) ;
-
-				if ( eLastBr && eLastBr.getAttribute( 'type', 2 ) != '_moz' )
-					eBr.parentNode.appendChild( FCKTools.CreateBogusBR( this.Window.document ) ) ;
-			}
+				this._AppendBogusBr( eBr.parentNode ) ;
 
 			if ( FCKBrowserInfo.IsIE )
@@ -522,2 +527,35 @@
 	range.MoveToBookmark( oBookmark ) ;
 }
+
+// Appends a bogus <br> at the end of the element, if not yet available.
+FCKEnterKey.prototype._AppendBogusBr = function( element )
+{
+	var eLastChild = element.getElementsByTagName('br') ;
+
+	if ( eLastChild )
+		eLastChild = eLastChild[ eLastChild.legth - 1 ] ;
+
+	if ( !eLastChild || eLastChild.getAttribute( 'type', 2 ) != '_moz' )
+		element.appendChild( FCKTools.CreateBogusBR( this.Window.document ) ) ;
+}
+
+// Recreate the elements tree at the end of the source block, at the beginning
+// of the target block. Eg.: 
+//	If source = <p><u>Some</u> sample <b><i>text</i></b></p> then target = <p><b><i></i></b></p>
+//	If source = <p><u>Some</u> sample text</p> then target = <p></p>
+FCKEnterKey.prototype._RecreateEndingTree = function( source, target )
+{
+	while ( ( source = source.lastChild ) && source.nodeType == 1 && FCKListsLib.InlineChildReqElements[ source.nodeName.toLowerCase() ] != null )
+		target = target.insertBefore( source.cloneNode( false ), target.firstChild ) ;
+}
+
+// Outdents a LI, maintaining the seletion defined on a range.
+FCKEnterKey.prototype._OutdentWithSelection = function( li, range )
+{
+	var oBookmark = range.CreateBookmark() ;
+
+	FCKListHandler.OutdentListItem( li ) ;
+	
+	range.MoveToBookmark( oBookmark ) ;
+	range.Select() ;
+}
Index: /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fck.js
===================================================================
--- /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fck.js	(revision 212)
+++ /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fck.js	(revision 213)
@@ -89,4 +89,7 @@
 		this.EditingArea = new FCKEditingArea( document.getElementById( 'xEditingArea' ) ) ;
 		this.EditingArea.FFSpellChecker = false ;
+		
+		// Final setup of the lists lib.
+		FCKListsLib.Setup() ;
 
 		// Set the editor's startup contents
@@ -263,8 +266,8 @@
 	{
 		// <A> href
-		html = html.replace( FCKRegexLib.ProtectUrlsA	, '$1$4$2$3$5$2 _fcksavedurl=$2$3$5$2' ) ;
+		html = html.replace( FCKRegexLib.ProtectUrlsA	, '$& _fcksavedurl=$1' ) ;
 
 		// <IMG> src
-		html = html.replace( FCKRegexLib.ProtectUrlsImg	, '$1$4$2$3$5$2 _fcksavedurl=$2$3$5$2' ) ;
+		html = html.replace( FCKRegexLib.ProtectUrlsImg	, '$& _fcksavedurl=$1' ) ;
 
 		return html ;
@@ -294,8 +297,8 @@
 		// IE doesn't support <abbr> and it breaks it. Let's protect it.
 		if ( FCKBrowserInfo.IsIE )
-			sTags += '|ABBR' ;
-
-		var oRegex = new RegExp( '<(' + sTags + ')([ \>])', 'gi' ) ;
-		html = html.replace( oRegex, '<FCK:$1$2' ) ;
+			sTags += '|ABBR|HR' ;
+
+		var oRegex = new RegExp( '<(' + sTags + ')(?!\w|:)', 'gi' ) ;
+		html = html.replace( oRegex, '<FCK:$1' ) ;
 
 		oRegex = new RegExp( '<\/(' + sTags + ')>', 'gi' ) ;
@@ -644,4 +647,10 @@
 	if ( FCK._ForceResetIsDirty )
 		FCK.ResetIsDirty() ;
+	
+	// This is a tricky thing for IE. In some cases, even if the cursor is
+	// blinking in the editing, the keystroke handler doesn't catch keyboard
+	// events. We must activate the editing area to make it work. (#142).
+	if ( FCKBrowserInfo.IsIE && FCK.HasFocus )
+		FCK.EditorDocument.body.setActive() ;
 
 	FCK.OnAfterSetHTML() ;
Index: /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fck_contextmenu.js
===================================================================
--- /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fck_contextmenu.js	(revision 212)
+++ /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fck_contextmenu.js	(revision 213)
@@ -203,5 +203,5 @@
 			AddItems : function( menu, tag, tagName )
 			{
-				if ( tagName == 'INPUT' && tag.type == 'hidden' )
+				if ( tagName == 'IMG' && tag.getAttribute( '_fckinputhidden' ) )
 				{
 					menu.AddSeparator() ;
Index: /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fck_ie.js
===================================================================
--- /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fck_ie.js	(revision 212)
+++ /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fck_ie.js	(revision 213)
@@ -36,7 +36,5 @@
 		// The behaviors should be pointed using the FullBasePath to avoid security
 		// errors when using a differente BaseHref.
-		sStyle =
-			'<style type="text/css" _fcktemp="true">' +
-			'INPUT { behavior: url(' + sBasePath + 'css/behaviors/hiddenfield.htc) ; }' ;
+		sStyle = '<style type="text/css" _fcktemp="true">' ;
 
 		if ( FCKConfig.ShowBorders )
@@ -44,5 +42,5 @@
 
 		// Disable resize handlers.
-		sStyle += 'INPUT,TEXTAREA,SELECT,.FCK__Anchor,.FCK__PageBreak' ;
+		sStyle += 'INPUT,TEXTAREA,SELECT,.FCK__Anchor,.FCK__PageBreak,.FCK__InputHidden' ;
 
 		if ( FCKConfig.DisableObjectResizing )
@@ -245,5 +243,5 @@
 		FCK._PasteIsRunning = true ;
 
-		FCK.GetClipboardHTML() ;
+		FCK.ExecuteNamedCommand( 'Paste' ) ;
 
 		// Removes the semaphore.
Index: /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fckdocumentprocessor.js
===================================================================
--- /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fckdocumentprocessor.js	(revision 212)
+++ /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fckdocumentprocessor.js	(revision 213)
@@ -197,2 +197,47 @@
 	return e ;
 }
+
+// HR Processor.
+// This is a IE only (tricky) thing. We protect all HR tags before loading them
+// (see FCK.ProtectTags). Here we put the HRs back.
+if ( FCKBrowserInfo.IsIE )
+{
+	FCKDocumentProcessor.AppendNew().ProcessDocument = function( document )
+	{
+		var aHRs = document.getElementsByTagName( 'HR' ) ;
+
+		var eHR ;
+		var i = aHRs.length - 1 ;
+		while ( i >= 0 && ( eHR = aHRs[i--] ) )
+		{
+			// Create the replacement HR.
+			var newHR = document.createElement( 'hr' ) ;
+			newHR.mergeAttributes( eHR, true ) ;
+			
+			// We must insert the new one after it. insertBefore will not work in all cases.
+			FCKDomTools.InsertAfterNode( eHR, newHR ) ;
+
+			eHR.parentNode.removeChild( eHR ) ;
+		}
+	}
+}
+
+// INPUT:hidden Processor.
+FCKDocumentProcessor.AppendNew().ProcessDocument = function( document )
+{
+	var aInputs = document.getElementsByTagName( 'INPUT' ) ;
+
+	var oInput ;
+	var i = aInputs.length - 1 ;
+	while ( i >= 0 && ( oInput = aInputs[i--] ) )
+	{
+		if ( oInput.type == 'hidden' )
+		{
+			var oImg = FCKDocumentProcessor_CreateFakeImage( 'FCK__InputHidden', oInput.cloneNode(true) ) ;
+			oImg.setAttribute( '_fckinputhidden', 'true', 0 ) ;
+
+			oInput.parentNode.insertBefore( oImg, oInput ) ;
+			oInput.parentNode.removeChild( oInput ) ;
+		}
+	}
+}
Index: /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fcklisthandler.js
===================================================================
--- /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fcklisthandler.js	(revision 212)
+++ /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fcklisthandler.js	(revision 213)
@@ -99,9 +99,19 @@
 				}
 
-				var eBlock = oDocument.createElement( 'p' ) ;	// TODO: Get from configuration.
+				var eBlock = oDocument.createElement( FCKConfig.EnterMode == 'p' ? 'p' : 'div' ) ;
 				FCKDomTools.MoveChildren( eParent.removeChild( listItem ), eBlock ) ;
 				FCKDomTools.InsertAfterNode( eParent, eBlock ) ;
 
-				listItem = eBlock ;
+				if ( FCKConfig.EnterMode == 'br' )
+				{
+					// We need the bogus to make it work properly. In Gecko, we
+					// need it before the new block, on IE, after it.
+					if ( FCKBrowserInfo.IsGecko )
+						eBlock.parentNode.insertBefore( FCKTools.CreateBogusBR( oDocument ), eBlock ) ;
+					else
+						FCKDomTools.InsertAfterNode( eBlock, FCKTools.CreateBogusBR( oDocument ) ) ;
+
+					FCKDomTools.RemoveNode( eBlock, true ) ;
+				}
 			}
 
@@ -109,6 +119,4 @@
 				FCKDomTools.RemoveNode( eParent, true ) ;
 		}
-
-		return listItem ;
 	},
 
Index: /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fcklistslib.js
===================================================================
--- /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fcklistslib.js	(revision 212)
+++ /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fcklistslib.js	(revision 213)
@@ -29,11 +29,8 @@
 {
 	// We are not handling <ins> and <del> as block elements, for now.
-	BlockElements : { address:1,blockquote:1,div:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,noscript:1,ol:1,p:1,pre:1,script:1,table:1,ul:1 },
+	BlockElements : { address:1,blockquote:1,center:1,div:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,noscript:1,ol:1,p:1,pre:1,script:1,table:1,ul:1 },
 
 	// Block elements that may be filled with &nbsp; if empty.
 	NonEmptyBlockElements : { p:1,div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,address:1,pre:1,ol:1,ul:1,li:1,td:1,th:1 },
-
-	// Elements that may be considered the "Block boundary" in an element path.
-	PathBlockElements : { address:1,blockquote:1,div:1,dl:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,p:1,pre:1,ol:1,ul:1,li:1,dt:1,de:1 },
 
 	// Inline elements which MUST have child nodes.
@@ -41,4 +38,23 @@
 
 	// Elements marked as empty "Empty" in the XHTML DTD.
-	EmptyElements : { base:1,meta:1,link:1,hr:1,br:1,param:1,img:1,area:1,input:1 }
+	EmptyElements : { base:1,meta:1,link:1,hr:1,br:1,param:1,img:1,area:1,input:1 },
+	
+	// Elements that may be considered the "Block boundary" in an element path.
+	PathBlockElements : { address:1,blockquote:1,dl:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,p:1,pre:1,ol:1,ul:1,li:1,dt:1,de:1 },
+	
+	// Elements that may be considered the "Block limit" in an element path.
+	PathBlockLimitElements : { body:1,td:1,th:1,caption:1,form:1 },
+
+	// Final setup of FCKListsLib once the editor is loaded (at FCK.StartEditor). 
+	// TODO: For v3, there should be a generic way to register to the editor
+	// startup event, so this function would not be needed to be defined here, not
+	// even be called at FCK.StartEditor.
+	Setup : function()
+	{
+		// <div> is considered a block element only if EnterMode=div, otherwise it is a block limit.
+		if ( FCKConfig.EnterMode == 'div' )
+			this.PathBlockElements.div = 1 ;
+		else
+			this.PathBlockLimitElements.div = 1 ;
+	}
 } ;
Index: /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fckregexlib.js
===================================================================
--- /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fckregexlib.js	(revision 212)
+++ /FCKeditor/branches/versions/2.4.x/editor/_source/internals/fckregexlib.js	(revision 213)
@@ -59,5 +59,6 @@
 SpaceNoClose	: /\/>/g ,
 
-EmptyParagraph	: /^<(p|div)>\s*<\/\1>$/i ,
+// Empty elements may be <p></p> or even a simple opening <p> (see #211).
+EmptyParagraph	: /^<([^ >]+)[^>]*>\s*(<\/\1>)?$/i ,
 
 TagBody			: /></ ,
@@ -75,6 +76,6 @@
 // them. We have to do all in one, otherwhise we will have problems with URLs
 // like "thumbnail.php?src=someimage.jpg" (SF-BUG 1554141).
-ProtectUrlsImg	: /(?:(<img(?=\s).*?\ssrc=)("|')(.*?)\2)|(?:(<img\s.*?src=)([^"'][^ >]+))/gi ,
-ProtectUrlsA	: /(?:(<a(?=\s).*?\shref=)("|')(.*?)\2)|(?:(<a\s.*?href=)([^"'][^ >]+))/gi ,
+ProtectUrlsImg	: /<img(?=\s).*?\ssrc=((?:("|').*?\2)|(?:[^"'][^ >]+))/gi ,
+ProtectUrlsA	: /<a(?=\s).*?\shref=((?:("|').*?\2)|(?:[^"'][^ >]+))/gi ,
 
 Html4DocType	: /HTML 4\.0 Transitional/i ,
Index: Keditor/branches/versions/2.4.x/editor/css/behaviors/hiddenfield.htc
===================================================================
--- /FCKeditor/branches/versions/2.4.x/editor/css/behaviors/hiddenfield.htc	(revision 212)
+++ 	(revision )
@@ -1,30 +1,0 @@
-<public:component lightweight="true">
-
-<public:attach event="oncontentready" onevent="ShowField()" />
-<public:attach event="ondoubleclick" onevent="EditField()" />
-
-<script language="javascript">
-
-var bIsHiddenField = this.type == 'hidden' ;
-
-function ShowField()
-{
-	if ( bIsHiddenField ) 
-	{
-		this.runtimeStyle.width				= '20px' ;
-		this.runtimeStyle.height			= '20px' ;
-		this.runtimeStyle.border			= '1px dotted #FF0000' ;
-		this.runtimeStyle.backgroundImage	= 'url(css/behaviors/hiddenfield.gif)' ;
-		this.runtimeStyle.fontSize			= '99px' ;
-	}
-}
-
-function EditField()
-{
-	if ( bIsHiddenField ) 
-		alert( this.outerHTML ) ;
-}
-
-</script>
-
-</public:component>
Index: /FCKeditor/branches/versions/2.4.x/editor/css/fck_internal.css
===================================================================
--- /FCKeditor/branches/versions/2.4.x/editor/css/fck_internal.css	(revision 212)
+++ /FCKeditor/branches/versions/2.4.x/editor/css/fck_internal.css	(revision 213)
@@ -26,5 +26,5 @@
 html
 {
-	min-height:100%;
+	min-height: 100%;
 }
 
@@ -70,5 +70,5 @@
 	background-image: url(images/fck_anchor.gif);
 	background-repeat: no-repeat;
-	padding-left:18px;
+	padding-left: 18px;
 }
 
@@ -81,5 +81,5 @@
 	background-image: url(images/fck_anchor.gif);
 	background-repeat: no-repeat;
-	padding-left:18px;
+	padding-left: 18px;
 }
 
@@ -100,17 +100,12 @@
 }
 
-input[type="hidden"]
+/* Hidden fields */
+.FCK__InputHidden
 {
-	display: inline;
-	width:20px;
-	height:20px;
-	border:1px dotted #FF0000 ;
-	background-image: url(behaviors/hiddenfield.gif);
+	width: 19px;
+	height: 18px;
+	background-image: url(images/fck_hiddenfield.gif);
 	background-repeat: no-repeat;
+	vertical-align: text-bottom;
+	background-position: center center;
 }
-
-input[type="hidden"]:after
-{
-	padding-left: 20px;
-	content: "" ;
-}
Index: /FCKeditor/branches/versions/2.4.x/editor/dialog/fck_hiddenfield.html
===================================================================
--- /FCKeditor/branches/versions/2.4.x/editor/dialog/fck_hiddenfield.html	(revision 212)
+++ /FCKeditor/branches/versions/2.4.x/editor/dialog/fck_hiddenfield.html	(revision 213)
@@ -22,18 +22,29 @@
  * Hidden Field dialog window.
 -->
-<html>
-	<head>
-		<title>Hidden Field Properties</title>
-		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-		<meta content="noindex, nofollow" name="robots">
-		<script src="common/fck_dialog_common.js" type="text/javascript"></script>
-		<script type="text/javascript">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>Hidden Field Properties</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta content="noindex, nofollow" name="robots" />
+	<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+	<script type="text/javascript">
 
 var oEditor = window.parent.InnerDialogLoaded() ;
+var FCK = oEditor.FCK ;
 
 // Gets the document DOM
-var oDOM = oEditor.FCK.EditorDocument ;
+var oDOM = FCK.EditorDocument ;
 
-var oActiveEl = oEditor.FCKSelection.GetSelectedElement() ;
+// Get the selected flash embed (if available).
+var oFakeImage = FCK.Selection.GetSelectedElement() ;
+var oActiveEl ;
+
+if ( oFakeImage )
+{
+	if ( oFakeImage.tagName == 'IMG' && oFakeImage.getAttribute('_fckinputhidden') )
+		oActiveEl = FCK.GetRealElement( oFakeImage ) ;
+	else
+		oFakeImage = null ;
+}
 
 window.onload = function()
@@ -42,11 +53,9 @@
 	oEditor.FCKLanguageManager.TranslatePage(document) ;
 
-	if ( oActiveEl && oActiveEl.tagName == 'INPUT' && oActiveEl.type == 'hidden' )
+	if ( oActiveEl )
 	{
 		GetE('txtName').value		= oActiveEl.name ;
 		GetE('txtValue').value		= oActiveEl.value ;
 	}
-	else
-		oActiveEl = null ;
 
 	window.parent.SetOkButton( true ) ;
@@ -58,7 +67,8 @@
 	if ( !oActiveEl )
 	{
-		oActiveEl = oEditor.FCK.EditorDocument.createElement( 'INPUT' ) ;
+		oActiveEl = FCK.EditorDocument.createElement( 'INPUT' ) ;
 		oActiveEl.type = 'hidden' ;
-		oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ;
+
+		oFakeImage = null ;
 	}
 
@@ -66,30 +76,41 @@
 	SetAttribute( oActiveEl, 'value', GetE('txtValue').value ) ;
 
+	if ( !oFakeImage )
+	{
+		oFakeImage	= oEditor.FCKDocumentProcessor_CreateFakeImage( 'FCK__InputHidden', oActiveEl ) ;
+		oFakeImage.setAttribute( '_fckinputhidden', 'true', 0 ) ;
+		oFakeImage	= FCK.InsertElementAndGetIt( oFakeImage ) ;
+	}
+	else
+		oEditor.FCKUndo.SaveUndoStep() ;
+
+	oEditor.FCKFlashProcessor.RefreshView( oFakeImage, oActiveEl ) ;
+
 	return true ;
 }
 
-		</script>
-	</head>
-	<body style="OVERFLOW: hidden" scroll="no">
-		<table height="100%" width="100%">
-			<tr>
-				<td align="center">
-					<table border="0" class="inhoud" cellpadding="0" cellspacing="0" width="80%">
-						<tr>
-							<td>
-								<span fckLang="DlgHiddenName">Name</span><br>
-								<input type="text" size="20" id="txtName" style="WIDTH: 100%">
-							</td>
-						</tr>
-						<tr>
-							<td>
-								<span fckLang="DlgHiddenValue">Value</span><br>
-								<input type="text" size="30" id="txtValue" style="WIDTH: 100%">
-							</td>
-						</tr>
-					</table>
-				</td>
-			</tr>
-		</table>
-	</body>
+	</script>
+</head>
+<body style="overflow: hidden" scroll="no">
+	<table height="100%" width="100%">
+		<tr>
+			<td align="center">
+				<table border="0" class="inhoud" cellpadding="0" cellspacing="0" width="80%">
+					<tr>
+						<td>
+							<span fcklang="DlgHiddenName">Name</span><br />
+							<input type="text" size="20" id="txtName" style="width: 100%" />
+						</td>
+					</tr>
+					<tr>
+						<td>
+							<span fcklang="DlgHiddenValue">Value</span><br />
+							<input type="text" size="30" id="txtValue" style="width: 100%" />
+						</td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+	</table>
+</body>
 </html>
Index: /FCKeditor/branches/versions/2.4.x/editor/dialog/fck_link/fck_link.js
===================================================================
--- /FCKeditor/branches/versions/2.4.x/editor/dialog/fck_link/fck_link.js	(revision 212)
+++ /FCKeditor/branches/versions/2.4.x/editor/dialog/fck_link/fck_link.js	(revision 213)
@@ -26,5 +26,5 @@
 var FCKLang		= oEditor.FCKLang ;
 var FCKConfig	= oEditor.FCKConfig ;
-var FCKRegexLib			= oEditor.FCKRegexLib ;
+var FCKRegexLib	= oEditor.FCKRegexLib ;
 
 //#### Dialog Tabs
@@ -56,26 +56,18 @@
 var oRegex = new Object() ;
 
-oRegex.UriProtocol = new RegExp('') ;
-oRegex.UriProtocol.compile( '^(((http|https|ftp|news):\/\/)|mailto:)', 'gi' ) ;
-
-oRegex.UrlOnChangeProtocol = new RegExp('') ;
-oRegex.UrlOnChangeProtocol.compile( '^(http|https|ftp|news)://(?=.)', 'gi' ) ;
-
-oRegex.UrlOnChangeTestOther = new RegExp('') ;
-//oRegex.UrlOnChangeTestOther.compile( '^(javascript:|#|/)', 'gi' ) ;
-oRegex.UrlOnChangeTestOther.compile( '^((javascript:)|[#/\.])', 'gi' ) ;
-
-oRegex.ReserveTarget = new RegExp('') ;
-oRegex.ReserveTarget.compile( '^_(blank|self|top|parent)$', 'i' ) ;
-
-oRegex.PopupUri = new RegExp('') ;
-oRegex.PopupUri.compile( "^javascript:void\\(\\s*window.open\\(\\s*'([^']+)'\\s*,\\s*(?:'([^']*)'|null)\\s*,\\s*'([^']*)'\\s*\\)\\s*\\)\\s*$" ) ;
-
-// Accesible popups
-oRegex.OnClickPopup = new RegExp('') ;
-oRegex.OnClickPopup.compile( "^\\s*onClick=\"\\s*window.open\\(\\s*this\\.href\\s*,\\s*(?:'([^']*)'|null)\\s*,\\s*'([^']*)'\\s*\\)\\s*;\\s*return\\s*false;*\\s*\"$" ) ;
-
-oRegex.PopupFeatures = new RegExp('') ;
-oRegex.PopupFeatures.compile( '(?:^|,)([^=]+)=(\\d+|yes|no)', 'gi' ) ;
+oRegex.UriProtocol = /^(((http|https|ftp|news):\/\/)|mailto:)/gi ;
+
+oRegex.UrlOnChangeProtocol = /^(http|https|ftp|news):\/\/(?=.)/gi ;
+
+oRegex.UrlOnChangeTestOther = /^((javascript:)|[#\/\.])/gi ;
+
+oRegex.ReserveTarget = /^_(blank|self|top|parent)$/i ;
+
+oRegex.PopupUri = /^javascript:void\(\s*window.open\(\s*'([^']+)'\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*\)\s*$/ ;
+
+// Accessible popups
+oRegex.OnClickPopup = /^\s*on[cC]lick="\s*window.open\(\s*this\.href\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*;\s*return\s*false;*\s*"$/ ;
+
+oRegex.PopupFeatures = /(?:^|,)([^=]+)=(\d+|yes|no)/gi ;
 
 //#### Parser Functions
@@ -230,5 +222,5 @@
 	// Accesible popups, the popup data is in the onclick attribute
 	if ( !oPopupMatch ) {
-		var onclick = oLink.getAttribute( 'onClick_fckprotectedatt' ) ;
+		var onclick = oLink.getAttribute( 'onclick_fckprotectedatt' ) ;
 		oPopupMatch = oRegex.OnClickPopup.exec( onclick ) ;
 		if( oPopupMatch )
@@ -554,5 +546,5 @@
 	if( GetE('cmbTarget').value == 'popup' )
 	{
-		SetAttribute( oLink, 'onClick_fckprotectedatt', " onClick=\"" + BuildOnClickPopup() + "\"") ;
+		SetAttribute( oLink, 'onclick_fckprotectedatt', " onclick=\"" + BuildOnClickPopup() + "\"") ;
 	}
 	else
@@ -560,7 +552,7 @@
 		// Check if the previous onclick was for a popup:
 		// In that case remove the onclick handler.
-		var onclick = oLink.getAttribute( 'onClick_fckprotectedatt' ) ;
+		var onclick = oLink.getAttribute( 'onclick_fckprotectedatt' ) ;
 		if( oRegex.OnClickPopup.test( onclick ) )
-			SetAttribute( oLink, 'onClick_fckprotectedatt', '' ) ;
+			SetAttribute( oLink, 'onclick_fckprotectedatt', '' ) ;
 	}
 
