Index: /CKEditor/branches/features/readonly/_samples/index.html
===================================================================
--- /CKEditor/branches/features/readonly/_samples/index.html	(revision 6749)
+++ /CKEditor/branches/features/readonly/_samples/index.html	(revision 6750)
@@ -77,4 +77,7 @@
 			Configuring CKEditor to produce HTML code that can be used with Adobe Flash.
 		</li>
+		<li><a class="samples" href="readonly.html">ReadOnly mode</a><br />
+			Using the readOnly API to disallow making any change to the editor content.
+		</li>
 	</ul>
 	<h2 class="samples">
Index: /CKEditor/branches/features/readonly/_samples/readonly.html
===================================================================
--- /CKEditor/branches/features/readonly/_samples/readonly.html	(revision 6750)
+++ /CKEditor/branches/features/readonly/_samples/readonly.html	(revision 6750)
@@ -0,0 +1,90 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>Read-only &mdash; CKEditor Sample</title>
+	<meta content="text/html; charset=utf-8" http-equiv="content-type" />
+	<!-- CKReleaser %REMOVE_LINE%
+	<script type="text/javascript" src="../ckeditor.js"></script>
+	CKReleaser %REMOVE_START% -->
+	<script type="text/javascript" src="../ckeditor_source.js"></script>
+	<!-- CKReleaser %REMOVE_END% -->
+	<script src="sample.js" type="text/javascript"></script>
+	<link href="sample.css" rel="stylesheet" type="text/css" />
+	<script type="text/javascript">
+	//<![CDATA[
+
+// The instanceReady event is fired, when an instance of CKEditor has finished
+// its initialization.
+CKEDITOR.on( 'instanceReady', function( ev )
+{
+	// Show the editor name and description in the browser status bar.
+	document.getElementById( 'eMessage' ).innerHTML = '<p>Instance <code>' + ev.editor.name + '<\/code> loaded.<\/p>';
+
+	// Show this sample buttons.
+	 document.getElementById( 'eButtons' ).style.display = 'block';
+});
+
+function toggleReadOnly( isReadOnly )
+{
+	// Get the editor instance that we want to interact with.
+	var oEditor = CKEDITOR.instances.editor1;
+
+	// Change the read-only state of editor.
+	// http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.editor.html#setReadOnly
+	oEditor.setReadOnly( isReadOnly );
+}
+
+	//]]>
+	</script>
+
+</head>
+<body>
+	<h1 class="samples">
+		CKEditor Sample &mdash; Using CKEditor ReadOnly API
+	</h1>
+	<div class="description">
+	<p>
+		This sample shows how to use the
+		<a class="samples" href="http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.editor.html#setReadOnly">set read-only</a>
+		API to put editor into an immutable state.
+	</p>
+	<p>
+		For details on how to create this setup check the source code of this sample page.
+	</p>
+	</div>
+
+	<!-- This <div> holds alert messages to be display in the sample page. -->
+	<div id="alerts">
+		<noscript>
+			<p>
+				<strong>CKEditor requires JavaScript to run</strong>. In a browser with no JavaScript
+				support, like yours, you should still see the contents (HTML data) and you should
+				be able to edit it normally, without a rich editor interface.
+			</p>
+		</noscript>
+	</div>
+	<form action="sample_posteddata.php" method="post">
+		<textarea class="ckeditor" id="editor1" name="editor1" cols="100" rows="10"><p>This is some <strong>sample text</strong>. You are using <a href="http://ckeditor.com/">CKEditor</a>.some</p></textarea>
+		<div id="eMessage">
+		</div>
+		<div id="eButtons" style="display: none">
+			<input onclick="toggleReadOnly( true );" type="button" value="Turn on read-only" />
+			<input onclick="toggleReadOnly();" type="button" value="Turn off read-only" />
+		</div>
+	</form>
+	<div id="footer">
+		<hr />
+		<p>
+			CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+		</p>
+		<p id="copy">
+			Copyright &copy; 2003-2011, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico
+			Knabben. All rights reserved.
+		</p>
+	</div>
+</body>
+</html>
Index: /CKEditor/branches/features/readonly/_source/core/dom/range.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/core/dom/range.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/core/dom/range.js	(revision 6750)
@@ -1871,5 +1871,5 @@
 						}
 						// Range enclosed entirely in an editable element.
-						else if ( node.is( 'body' )
+						else if ( node.is( 'html' )
 							|| node.getAttribute( 'contentEditable' ) == 'true'
 							&& ( node.contains( anotherEnd ) || node.equals( anotherEnd ) ) )
Index: /CKEditor/branches/features/readonly/_source/core/editor.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/core/editor.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/core/editor.js	(revision 6750)
@@ -160,4 +160,14 @@
 		 */
 		editor.tabIndex = editor.config.tabIndex || editor.element.getAttribute( 'tabindex' ) || 0;
+
+		/**
+		 * Immutable field indicate the read-only state of this editor.
+		 * @name CKEDITOR.editor.prototype.readOnly
+		 * @see CKEDITOR.editor.prototype.setReadOnly
+		 * @type Boolean
+		 * @default CKEDITOR.config.readOnly
+		 * @since 3.6
+		 */
+		editor.readOnly = !!( editor.config.readOnly || editor.element.getAttribute( 'disabled' ) );
 
 		// Fire the "configLoaded" event.
@@ -395,5 +405,5 @@
 	};
 
-	function updateCommandsMode()
+	function updateCommands()
 	{
 		var command,
@@ -404,5 +414,6 @@
 		{
 			command = commands[ name ];
-			command[ command.startDisabled ? 'disable' : command.modes[ mode ] ? 'enable' : 'disable' ]();
+			command[ command.startDisabled ? 'disable' :
+					 this.readOnly && !command.readOnly ? 'disable' : command.modes[ mode ] ? 'enable' : 'disable' ]();
 		}
 	}
@@ -492,5 +503,5 @@
 			CKEDITOR.fire( 'instanceCreated', null, this );
 
-			this.on( 'mode', updateCommandsMode, null, null, 1 );
+			this.on( 'mode', updateCommands, null, null, 1 );
 
 			initConfig( this, instanceConfig );
@@ -712,4 +723,20 @@
 
 			!internal && this.fire( 'afterSetData', eventData );
+		},
+
+		/**
+		 * Turn editor into read-only mode or restore it from read-only mode.
+		 * @param enable {Boolean}
+		 * @since 3.6
+		 * <strong>Note:</strong> current editing block will be reloaded.
+		 */
+		setReadOnly : function( enable )
+		{
+			if ( this.readOnly != enable )
+			{
+				this.readOnly = !!enable;
+				// Reload current mode, then fire the event on editor.
+				this.fire( 'readOnly' );
+			}
 		},
 
@@ -842,4 +869,15 @@
 
 /**
+ * Whether to start the editor in read-only mode, otherwise it depends on if "disabled" attribute is presented on the host &lt;textarea&gt;.
+ * @name CKEDITOR.config.readOnly
+ * @see CKEDITOR.editor.setReadOnly
+ * @type Boolean
+ * @default false
+ * @since 3.6
+ * @example
+ * config.readOnly = true;
+ */
+
+/**
  * Fired when a CKEDITOR instance is created, but still before initializing it.
  * To interact with a fully initialized instance, use the
@@ -984,2 +1022,9 @@
  * @param {Object} element The element to insert.
  */
+
+/**
+ * Event fired once editor's {@link CKEDITOR.editor.prototype.readOnly} state has changed.
+ * @name CKEDITOR.editor#readOnly
+ * @event
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
Index: /CKEditor/branches/features/readonly/_source/plugins/a11yhelp/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/a11yhelp/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/a11yhelp/plugin.js	(revision 6750)
@@ -38,4 +38,5 @@
 					},
 					modes : { wysiwyg:1, source:1 },
+					readOnly : 1,
 					canUndo : false
 				});
Index: /CKEditor/branches/features/readonly/_source/plugins/about/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/about/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/about/plugin.js	(revision 6750)
@@ -12,4 +12,5 @@
 		command.modes = { wysiwyg:1, source:1 };
 		command.canUndo = false;
+		command.readOnly = 1;
 
 		editor.ui.addButton( 'About',
Index: /CKEditor/branches/features/readonly/_source/plugins/basicstyles/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/basicstyles/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/basicstyles/plugin.js	(revision 6750)
@@ -18,5 +18,5 @@
 			editor.attachStyleStateChange( style, function( state )
 				{
-					editor.getCommand( commandName ).setState( state );
+					!editor.readOnly && editor.getCommand( commandName ).setState( state );
 				});
 
Index: /CKEditor/branches/features/readonly/_source/plugins/bidi/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/bidi/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/bidi/plugin.js	(revision 6750)
@@ -23,4 +23,8 @@
 		var editor = evt.editor,
 			path = evt.data.path;
+
+		if ( editor.readOnly )
+			return;
+
 		var useComputedState = editor.config.useComputedState,
 			selectedElement;
Index: /CKEditor/branches/features/readonly/_source/plugins/blockquote/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/blockquote/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/blockquote/plugin.js	(revision 6750)
@@ -26,6 +26,9 @@
 	function onSelectionChange( evt )
 	{
-		var editor = evt.editor,
-			command = editor.getCommand( 'blockquote' );
+		var editor = evt.editor;
+		if ( editor.readOnly )
+			return;
+
+		var command = editor.getCommand( 'blockquote' );
 		command.state = getState( editor, evt.data.path );
 		command.fire( 'state' );
Index: /CKEditor/branches/features/readonly/_source/plugins/button/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/button/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/button/plugin.js	(revision 6750)
@@ -150,8 +150,10 @@
 				{
 					var mode = editor.mode;
+
 					// Restore saved button state.
-					this.setState( this.modes[ mode ] ?
-						modeStates[ mode ] != undefined ? modeStates[ mode ] :
-							CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED );
+					var state = this.modes[ mode ] ? modeStates[ mode ] != undefined ? modeStates[ mode ] :
+							CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED;
+
+					this.setState( editor.readOnly && !this.readOnly ? CKEDITOR.TRISTATE_DISABLED : state );
 				}, this);
 		}
Index: /CKEditor/branches/features/readonly/_source/plugins/clipboard/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/clipboard/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/clipboard/plugin.js	(revision 6750)
@@ -294,5 +294,7 @@
 		CKEDITOR.env.ie && ( depressBeforeEvent = 1 );
 
-		var retval = editor.document.$.queryCommandEnabled( command ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED;
+		var retval = CKEDITOR.TRISTATE_OFF;
+		try { retval = editor.document.$.queryCommandEnabled( command ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED; }catch( er ){}
+
 		depressBeforeEvent = 0;
 		return retval;
Index: /CKEditor/branches/features/readonly/_source/plugins/editingblock/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/editingblock/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/editingblock/plugin.js	(revision 6750)
@@ -114,4 +114,9 @@
 				});
 
+			// Force reload the mode to refresh all command states.
+			editor.on( 'readOnly', function() {
+				this.setMode( this.mode || this.config.startupMode, 1 );
+			});
+
 			editor.on( 'destroy', function ()
 			{
@@ -152,5 +157,5 @@
 	 * CKEDITOR.instances.editor1.setMode( 'source' );
 	 */
-	CKEDITOR.editor.prototype.setMode = function( mode )
+	CKEDITOR.editor.prototype.setMode = function( mode, forceReload )
 	{
 		this.fire( 'beforeSetMode', { newMode : mode } );
@@ -163,5 +168,5 @@
 		if ( this.mode )
 		{
-			if ( mode == this.mode )
+			if ( !forceReload && mode == this.mode )
 				return;
 
Index: /CKEditor/branches/features/readonly/_source/plugins/elementspath/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/elementspath/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/elementspath/plugin.js	(revision 6750)
@@ -16,4 +16,5 @@
 		{
 			editorFocus : false,
+			readOnly : 1,
 			exec : function( editor )
 			{
Index: /CKEditor/branches/features/readonly/_source/plugins/enterkey/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/enterkey/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/enterkey/plugin.js	(revision 6750)
@@ -12,7 +12,19 @@
 		init : function( editor )
 		{
-			var specialKeys = editor.specialKeys;
-			specialKeys[ 13 ] = enter;
-			specialKeys[ CKEDITOR.SHIFT + 13 ] = shiftEnter;
+			editor.addCommand( 'enter', {
+				modes : { wysiwyg:1 },
+				editorFocus : false,
+				exec : enter
+			});
+
+			editor.addCommand( 'shiftEnter', {
+				modes : { wysiwyg:1 },
+				editorFocus : false,
+				exec : shiftEnter
+			});
+
+			var keystrokes = editor.keystrokeHandler.keystrokes;
+			keystrokes[ 13 ] = 'enter';
+			keystrokes[ CKEDITOR.SHIFT + 13 ] = 'shiftEnter';
 		}
 	});
Index: /CKEditor/branches/features/readonly/_source/plugins/find/dialogs/find.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/find/dialogs/find.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/find/dialogs/find.js	(revision 6750)
@@ -855,4 +855,6 @@
 
 				this.selectPage( startupPage );
+
+				this[ ( startupPage == 'find' && this._.editor.readOnly? 'hide' : 'show' ) + 'Page' ]( 'replace');
 			},
 			onHide : function()
Index: /CKEditor/branches/features/readonly/_source/plugins/find/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/find/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/find/plugin.js	(revision 6750)
@@ -16,4 +16,5 @@
 		var findCommand = editor.addCommand( 'find', new CKEDITOR.dialogCommand( 'find' ) );
 		findCommand.canUndo = false;
+		findCommand.readOnly = 1;
 
 		editor.ui.addButton( 'Replace',
Index: /CKEditor/branches/features/readonly/_source/plugins/indent/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/indent/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/indent/plugin.js	(revision 6750)
@@ -16,4 +16,7 @@
 	function onSelectionChange( evt )
 	{
+		if ( evt.editor.readOnly )
+			return;
+
 		var editor = evt.editor,
 			elementPath = evt.data.path,
Index: /CKEditor/branches/features/readonly/_source/plugins/justify/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/justify/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/justify/plugin.js	(revision 6750)
@@ -50,4 +50,7 @@
 	function onSelectionChange( evt )
 	{
+		if ( evt.editor.readOnly )
+			return;
+
 		var command = evt.editor.getCommand( this.name );
 		command.state = getState.call( this, evt.editor, evt.data.path );
Index: /CKEditor/branches/features/readonly/_source/plugins/link/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/link/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/link/plugin.js	(revision 6750)
@@ -55,4 +55,7 @@
 		 editor.on( 'selectionChange', function( evt )
 			{
+				if ( editor.readOnly )
+					return;
+
 				/*
 				 * Despite our initial hope, document.queryCommandEnabled() does not work
Index: /CKEditor/branches/features/readonly/_source/plugins/list/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/list/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/list/plugin.js	(revision 6750)
@@ -219,4 +219,7 @@
 	function onSelectionChange( evt )
 	{
+		if ( evt.editor.readOnly )
+			return;
+
 		var path = evt.data.path,
 			blockLimit = path.blockLimit,
Index: /CKEditor/branches/features/readonly/_source/plugins/maximize/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/maximize/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/maximize/plugin.js	(revision 6750)
@@ -86,5 +86,5 @@
 		{
 			var one = all[ i ];
-			if ( one.mode == 'wysiwyg' )
+			if ( one.mode == 'wysiwyg' && !one.readOnly )
 			{
 				var body = one.document.getBody();
@@ -156,4 +156,5 @@
 				{
 					modes : { wysiwyg : 1, source : 1 },
+					readOnly : 1,
 					editorFocus : false,
 					exec : function()
Index: /CKEditor/branches/features/readonly/_source/plugins/menu/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/menu/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/menu/plugin.js	(revision 6750)
@@ -98,7 +98,7 @@
 							var item = this.editor.getMenuItem( itemName );
 
-							if ( item )
+							if ( item && ( !item.command || this.editor.getCommand( item.command ).state ) )
 							{
-								item.state = listenerItems[ itemName ];
+								item.state =  listenerItems[ itemName ];
 								this.add( item );
 							}
Index: /CKEditor/branches/features/readonly/_source/plugins/preview/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/preview/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/preview/plugin.js	(revision 6750)
@@ -14,4 +14,5 @@
 		modes : { wysiwyg:1, source:1 },
 		canUndo : false,
+		readOnly : 1,
 		exec : function( editor )
 		{
Index: /CKEditor/branches/features/readonly/_source/plugins/print/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/print/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/print/plugin.js	(revision 6750)
@@ -38,4 +38,5 @@
 	},
 	canUndo : false,
+	readOnly : 1,
 	modes : { wysiwyg : !( CKEDITOR.env.opera ) }		// It is imposible to print the inner document in Opera.
 };
Index: /CKEditor/branches/features/readonly/_source/plugins/richcombo/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/richcombo/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/richcombo/plugin.js	(revision 6750)
@@ -131,5 +131,6 @@
 			editor.on( 'mode', function()
 				{
-					this.setState( this.modes[ editor.mode ] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED );
+					var state = this.modes[ editor.mode ] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED;
+					this.setState( editor.readOnly && !this.readOnly ? CKEDITOR.TRISTATE_DISABLED : state  );
 					this.setValue( '' );
 				},
Index: /CKEditor/branches/features/readonly/_source/plugins/save/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/save/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/save/plugin.js	(revision 6750)
@@ -13,4 +13,5 @@
 	{
 		modes : { wysiwyg:1, source:1 },
+		readOnly : 1,
 
 		exec : function( editor )
Index: /CKEditor/branches/features/readonly/_source/plugins/selection/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/selection/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/selection/plugin.js	(revision 6750)
@@ -93,4 +93,5 @@
 	{
 		modes : { wysiwyg : 1, source : 1 },
+		readOnly : CKEDITOR.env.ie || CKEDITOR.env.webkit,
 		exec : function( editor )
 		{
Index: /CKEditor/branches/features/readonly/_source/plugins/showblocks/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/showblocks/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/showblocks/plugin.js	(revision 6750)
@@ -90,4 +90,5 @@
 	var commandDefinition =
 	{
+		readOnly : 1,
 		preserveState : true,
 		editorFocus : false,
Index: /CKEditor/branches/features/readonly/_source/plugins/showborders/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/showborders/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/showborders/plugin.js	(revision 6750)
@@ -41,4 +41,5 @@
 		preserveState : true,
 		editorFocus : false,
+		readOnly: 1,
 
 		exec : function ( editor )
Index: /CKEditor/branches/features/readonly/_source/plugins/sourcearea/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/sourcearea/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/sourcearea/plugin.js	(revision 6750)
@@ -41,4 +41,6 @@
 							textarea.addClass( 'cke_source' );
 							textarea.addClass( 'cke_enable_context_menu' );
+
+							editor.readOnly && textarea.setAttribute( 'disabled', true );
 
 							var styles =
@@ -182,5 +184,5 @@
 			modes : { wysiwyg:1, source:1 },
 			editorFocus : false,
-
+			readOnly : 1,
 			exec : function( editor )
 			{
Index: /CKEditor/branches/features/readonly/_source/plugins/toolbar/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/toolbar/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/toolbar/plugin.js	(revision 6750)
@@ -37,4 +37,5 @@
 		{
 			modes : { wysiwyg : 1, source : 1 },
+			readOnly : 1,
 
 			exec : function( editor )
@@ -327,4 +328,5 @@
 							editor.addCommand( 'toolbarCollapse',
 								{
+									readOnly : 1,
 									exec : function( editor )
 									{
Index: /CKEditor/branches/features/readonly/_source/plugins/undo/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/undo/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/undo/plugin.js	(revision 6750)
@@ -91,5 +91,5 @@
 			editor.on( 'mode', function()
 				{
-					undoManager.enabled = editor.mode == 'wysiwyg';
+					undoManager.enabled = editor.readOnly ? false : editor.mode == 'wysiwyg';
 					undoManager.onChange();
 				});
Index: /CKEditor/branches/features/readonly/_source/plugins/wysiwygarea/plugin.js
===================================================================
--- /CKEditor/branches/features/readonly/_source/plugins/wysiwygarea/plugin.js	(revision 6749)
+++ /CKEditor/branches/features/readonly/_source/plugins/wysiwygarea/plugin.js	(revision 6750)
@@ -599,4 +599,6 @@
 						body.spellcheck = !editor.config.disableNativeSpellChecker;
 
+						var editable = !editor.readOnly;
+
 						if ( CKEDITOR.env.ie )
 						{
@@ -607,5 +609,5 @@
 							// taking the editing focus at startup. (#141 / #523)
 							body.disabled = true;
-							body.contentEditable = true;
+							body.contentEditable = editable;
 							body.removeAttribute( 'disabled' );
 						}
@@ -619,18 +621,18 @@
 								if ( CKEDITOR.env.gecko && CKEDITOR.env.version >= 10900
 										|| CKEDITOR.env.opera )
-									domDocument.$.body.contentEditable = true;
+									domDocument.$.body.contentEditable = editable;
 								else if ( CKEDITOR.env.webkit )
-									domDocument.$.body.parentNode.contentEditable = true;
+									domDocument.$.body.parentNode.contentEditable = editable;
 								else
-									domDocument.$.designMode = 'on';
+									domDocument.$.designMode = editable? 'off' : 'on';
 							}, 0 );
 						}
 
-						CKEDITOR.env.gecko && CKEDITOR.tools.setTimeout( activateEditing, 0, null, editor );
+						editable && CKEDITOR.env.gecko && CKEDITOR.tools.setTimeout( activateEditing, 0, null, editor );
 
 						domWindow	= editor.window	= new CKEDITOR.dom.window( domWindow );
 						domDocument	= editor.document	= new CKEDITOR.dom.document( domDocument );
 
-						domDocument.on( 'dblclick', function( evt )
+						editable && domDocument.on( 'dblclick', function( evt )
 						{
 							var element = evt.data.getTarget(),
@@ -713,6 +715,6 @@
 						// IE standard compliant in editing frame doesn't focus the editor when
 						// clicking outside actual content, manually apply the focus. (#1659)
-						if ( CKEDITOR.env.ie
-							&& domDocument.$.compatMode == 'CSS1Compat'
+						if ( editable &&
+								CKEDITOR.env.ie && domDocument.$.compatMode == 'CSS1Compat'
 								|| CKEDITOR.env.gecko
 								|| CKEDITOR.env.opera )
@@ -745,5 +747,5 @@
 								var doc = editor.document;
 
-								if ( CKEDITOR.env.gecko && CKEDITOR.env.version >= 10900 )
+								if ( editable && CKEDITOR.env.gecko && CKEDITOR.env.version >= 10900 )
 									blinkCursor();
 								else if ( CKEDITOR.env.opera )
@@ -763,6 +765,7 @@
 
 						var keystrokeHandler = editor.keystrokeHandler;
-						if ( keystrokeHandler )
-							keystrokeHandler.attach( domDocument );
+						// Prevent backspace from navigating off the page.
+						keystrokeHandler.blockedKeystrokes[ 8 ] = !editable;
+						keystrokeHandler.attach( domDocument );
 
 						if ( CKEDITOR.env.ie )
@@ -771,5 +774,5 @@
 							// Override keystrokes which should have deletion behavior
 							//  on control types in IE . (#4047)
-							domDocument.on( 'keydown', function( evt )
+							editable && domDocument.on( 'keydown', function( evt )
 							{
 								var keyCode = evt.data.getKeystroke();
