Index: /CKEditor/branches/versions/3.3.x/CHANGES.html
===================================================================
--- /CKEditor/branches/versions/3.3.x/CHANGES.html	(revision 5390)
+++ /CKEditor/branches/versions/3.3.x/CHANGES.html	(revision 5391)
@@ -42,4 +42,5 @@
 		<li><a href="http://dev.fckeditor.net/ticket/4968">#4968</a> : Config entry 'contentsLangDirection' now has a default value 'ui' which inherit language direction from editor's (UI) language.</li>
 		<li><a href="http://dev.fckeditor.net/ticket/635">#635</a> : Open properties dialog when double clicking on objects.</li>
+		<li><a href="http://dev.fckeditor.net/ticket/3593">#3593</a> : Apply contentEditable="true" instead of designMode="on" to allow creating uneditable content elements in all browsers.</li>
 	</ul>
 	<p>
Index: /CKEditor/branches/versions/3.3.x/_source/plugins/wysiwygarea/plugin.js
===================================================================
--- /CKEditor/branches/versions/3.3.x/_source/plugins/wysiwygarea/plugin.js	(revision 5390)
+++ /CKEditor/branches/versions/3.3.x/_source/plugins/wysiwygarea/plugin.js	(revision 5391)
@@ -376,28 +376,39 @@
 						else
 						{
-							// Gecko need a key event to 'wake up' the editing
-							// ability when document is empty.(#3864)
-							if ( CKEDITOR.env.gecko && !body.childNodes.length )
-							{
-								setTimeout( function()
-								{
-									restoreDirty( editor );
-
-									// Simulating keyboard character input by dispatching a keydown of white-space text.
-									var keyEventSimulate = domDocument.$.createEvent( "KeyEvents" );
-									keyEventSimulate.initKeyEvent( 'keypress', true, true, domWindow.$, false,
-										false, false, false, 0, 32 );
-									domDocument.$.dispatchEvent( keyEventSimulate );
-
-									// Restore the original document status by placing the cursor before a bogus br created (#5021).
-									domDocument.createElement( 'br', { attributes: { '_moz_editor_bogus_node' : 'TRUE', '_moz_dirty' : "" } } )
-										.replace( domDocument.getBody().getFirst() );
-									var nativeRange = new CKEDITOR.dom.range( domDocument );
-									nativeRange.setStartAt( new CKEDITOR.dom.element( body ) , CKEDITOR.POSITION_AFTER_START );
-									nativeRange.select();
-								}, 0 );
-							}
-
-							domDocument.designMode = 'on';
+							// Avoid opening design mode in a frame window thread,
+							// which will cause host page scrolling.(#4397)
+							setTimeout( function()
+							{
+								// Prefer 'contentEditable' instead of 'designMode'. (#3593)
+								if ( CKEDITOR.env.gecko && CKEDITOR.env.version >= 10900 )
+									domDocument.$.body.contentEditable = true;
+								else if ( CKEDITOR.env.webkit || CKEDITOR.env.opera )
+									domDocument.$.body.parentNode.contentEditable = true;
+								else
+									domDocument.$.designMode = 'on';
+							}, 0 );
+						}
+
+						// Gecko need a key event to 'wake up' the editing
+						// ability when document is empty.(#3864)
+						if ( CKEDITOR.env.gecko && !body.childNodes.length )
+						{
+							setTimeout( function()
+							{
+								restoreDirty( editor );
+
+								// Simulating keyboard character input by dispatching a keydown of white-space text.
+								var keyEventSimulate = domDocument.$.createEvent( "KeyEvents" );
+								keyEventSimulate.initKeyEvent( 'keypress', true, true, domWindow.$, false,
+									false, false, false, 0, 32 );
+								domDocument.$.dispatchEvent( keyEventSimulate );
+
+								// Restore the original document status by placing the cursor before a bogus br created (#5021).
+								domDocument.createElement( 'br', { attributes: { '_moz_editor_bogus_node' : 'TRUE', '_moz_dirty' : "" } } )
+									.replace( domDocument.getBody().getFirst() );
+								var nativeRange = new CKEDITOR.dom.range( domDocument );
+								nativeRange.setStartAt( new CKEDITOR.dom.element( body ) , CKEDITOR.POSITION_AFTER_START );
+								nativeRange.select();
+							}, 0 );
 						}
 
@@ -450,5 +461,6 @@
 						// clicking outside actual content, manually apply the focus. (#1659)
 						if ( CKEDITOR.env.ie
-							&& domDocument.$.compatMode == 'CSS1Compat' )
+							&& domDocument.$.compatMode == 'CSS1Compat'
+								|| CKEDITOR.env.gecko )
 						{
 							var htmlElement = domDocument.getDocumentElement();
@@ -459,5 +471,8 @@
 								// the focus.
 								if ( evt.data.getTarget().equals( htmlElement ) )
-									ieFocusGrabber.focus();
+								{
+									CKEDITOR.env.gecko && blinkCursor();
+									focusGrabber.focus();
+								}
 							} );
 						}
@@ -778,16 +793,25 @@
 				});
 
+			// Switch on design mode for a short while and close it after then.
+			function blinkCursor()
+			{
+				editor.document.$.designMode = 'on';
+				setTimeout( function ()
+				{
+					editor.document.$.designMode = 'off';
+				}, 50 );
+			}
 
 			// Create an invisible element to grab focus.
-			if ( CKEDITOR.env.ie )
+			if ( CKEDITOR.env.gecko || CKEDITOR.env.ie )
 			{
-				var ieFocusGrabber;
+				var focusGrabber;
 				editor.on( 'uiReady', function()
 				{
-					ieFocusGrabber = editor.container.append( CKEDITOR.dom.element.createFromHtml(
+					focusGrabber = editor.container.append( CKEDITOR.dom.element.createFromHtml(
 						// Use 'span' instead of anything else to fly under the screen-reader radar. (#5049)
 						'<span tabindex="-1" style="position:absolute; left:-10000" role="presentation"></span>' ) );
 
-					ieFocusGrabber.on( 'focus', function()
+					focusGrabber.on( 'focus', function()
 						{
 							editor.focus();
@@ -796,5 +820,5 @@
 				editor.on( 'destroy', function()
 				{
-					ieFocusGrabber.clearCustomData();
+					focusGrabber.clearCustomData();
 				} );
 			}
