Index: CKEditor/branches/versions/3.6.x/CHANGES.html
===================================================================
--- CKEditor/branches/versions/3.6.x/CHANGES.html	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/CHANGES.html	(revision 6772)
@@ -43,4 +43,5 @@
 		<li><a href="http://dev.ckeditor.com/ticket/5647">#5647</a> : Usability enhancements to the keyboard navigation on the toolbar. Not TAB is used to jump among toolbar groups, while the arrow can be used to cycle withing the group. The new <a href="http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html#.toolbarGroupCycling">toolbarGroupCycling</a> setting can be used to change the arrow keys behavior.</li>
 		<li><a href="http://dev.ckeditor.com/ticket/5647">#5647</a> : Accessibility enhancements to the structure of the toolbar.</li>
+		<li><a href="http://dev.ckeditor.com/ticket/1376">#1376</a> : It's now possible to put the editor in "read-only" state, so users are not able to make changes to the contents. Check out the new <a href="http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.editor.html#setReadOnly">CKEDITOR.editor::setReadOnly method</a>, the <a href="http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.editor.html#readOnly">CKEDITOR.editor::readOnly property</a>, the <a href="http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.editor.html#event:readOnly">CKEDITOR.editor::readOnly event</a> and the <a href="http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html#.readOnly">readOnly setting</a>.</li>
 		<li><a href="http://dev.ckeditor.com/ticket/6589">#6589</a> : Automatically use a "onDialogEvent" function in the iframeDialog contents if no callback is used on creation.</li>
 		<li><a href="http://dev.ckeditor.com/ticket/5745">#5745</a> : Allow to pass extra configuration options for iframeDialog.</li>
Index: CKEditor/branches/versions/3.6.x/_samples/index.html
===================================================================
--- CKEditor/branches/versions/3.6.x/_samples/index.html	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_samples/index.html	(revision 6772)
@@ -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/versions/3.6.x/_samples/readonly.html
===================================================================
--- CKEditor/branches/versions/3.6.x/_samples/readonly.html	(revision 6772)
+++ CKEditor/branches/versions/3.6.x/_samples/readonly.html	(revision 6772)
@@ -0,0 +1,95 @@
+﻿<!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[
+
+var editor;
+
+// The instanceReady event is fired, when an instance of CKEditor has finished
+// its initialization.
+CKEDITOR.on( 'instanceReady', function( ev )
+	{
+		editor = ev.editor;
+
+		// Show this "on" button.
+		document.getElementById( 'readOnlyOn' ).style.display = '';
+
+		// Event fired when the readOnly property changes.
+		editor.on( 'readOnly', function()
+			{
+				document.getElementById( 'readOnlyOn' ).style.display = this.readOnly ? 'none' : '';
+				document.getElementById( 'readOnlyOff' ).style.display = this.readOnly ? '' : 'none';
+			});
+	});
+
+function toggleReadOnly( makeEditable )
+{
+	// Change the read-only state of the editor.
+	// http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.editor.html#setReadOnly
+	editor.setReadOnly( makeEditable );
+}
+
+	//]]>
+	</script>
+
+</head>
+<body>
+	<h1 class="samples">
+		CKEditor Sample &mdash; Using CKEditor Read-Only 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 read-only state, so user's are not able to change its contents.
+	</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">
+		<p>
+			<textarea class="ckeditor" id="editor1" name="editor1" cols="100" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>
+		</p>
+		<p>
+			<input id="readOnlyOn" onclick="toggleReadOnly();" type="button" value="Make it read-only" style="display:none" />
+			<input id="readOnlyOff" onclick="toggleReadOnly( true );" type="button" value="Make it editable again" style="display:none" />
+		</p>
+	</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/versions/3.6.x/_source/core/dom/range.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/core/dom/range.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/core/dom/range.js	(revision 6772)
@@ -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/versions/3.6.x/_source/core/editor.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/core/editor.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/core/editor.js	(revision 6772)
@@ -160,4 +160,13 @@
 		 */
 		editor.tabIndex = editor.config.tabIndex || editor.element.getAttribute( 'tabindex' ) || 0;
+
+		/**
+		 * Indicates the read-only state of this editor. This is a read-only property.
+		 * @name CKEDITOR.editor.prototype.readOnly
+		 * @type Boolean
+		 * @since 3.6
+		 * @see CKEDITOR.editor.prototype.setReadOnly
+		 */
+		editor.readOnly = !!( editor.config.readOnly || editor.element.getAttribute( 'disabled' ) );
 
 		// Fire the "configLoaded" event.
@@ -395,5 +404,5 @@
 	};
 
-	function updateCommandsMode()
+	function updateCommands()
 	{
 		var command,
@@ -401,8 +410,12 @@
 			mode = this.mode;
 
+		if ( !mode )
+			return;
+
 		for ( var name in commands )
 		{
 			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 +505,6 @@
 			CKEDITOR.fire( 'instanceCreated', null, this );
 
-			this.on( 'mode', updateCommandsMode, null, null, 1 );
+			this.on( 'mode', updateCommands, null, null, 1 );
+			this.on( 'readOnly', updateCommands, null, null, 1 );
 
 			initConfig( this, instanceConfig );
@@ -712,4 +726,26 @@
 
 			!internal && this.fire( 'afterSetData', eventData );
+		},
+
+		/**
+		 * Puts or restores the editor into read-only state. When in read-only,
+		 * the user is not able to change the editor contents, but still use
+		 * some editor features. This function sets the readOnly property of
+		 * the editor, firing the "readOnly" event.<br><br>
+		 * <strong>Note:</strong> the current editing area will be reloaded.
+		 * @param {Boolean} [makeEditable] Indicates that the editor must be
+		 *		restored from read-only mode, making it editable.
+		 * @since 3.6
+		 */
+		setReadOnly : function( makeEditable )
+		{
+			if ( this.readOnly != !makeEditable )
+			{
+				this.readOnly = !makeEditable;
+				
+				// Fire the readOnly event so the editor features can update
+				// their state accordingly.
+				this.fire( 'readOnly' );
+			}
 		},
 
@@ -842,4 +878,16 @@
 
 /**
+ * If "true", makes the editor start in read-only state. Otherwise, it'll check
+ * if the linked &lt;textarea&gt; has the "disabled" attribute.
+ * @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 +1032,9 @@
  * @param {Object} element The element to insert.
  */
+
+/**
+ * Event fired after {@link CKEDITOR.editor.prototype.readOnly} property changes.
+ * @name CKEDITOR.editor#readOnly
+ * @event
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
Index: CKEditor/branches/versions/3.6.x/_source/plugins/a11yhelp/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/a11yhelp/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/a11yhelp/plugin.js	(revision 6772)
@@ -38,4 +38,5 @@
 					},
 					modes : { wysiwyg:1, source:1 },
+					readOnly : 1,
 					canUndo : false
 				});
Index: CKEditor/branches/versions/3.6.x/_source/plugins/about/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/about/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/about/plugin.js	(revision 6772)
@@ -12,4 +12,5 @@
 		command.modes = { wysiwyg:1, source:1 };
 		command.canUndo = false;
+		command.readOnly = 1;
 
 		editor.ui.addButton( 'About',
Index: CKEditor/branches/versions/3.6.x/_source/plugins/basicstyles/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/basicstyles/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/basicstyles/plugin.js	(revision 6772)
@@ -18,5 +18,5 @@
 			editor.attachStyleStateChange( style, function( state )
 				{
-					editor.getCommand( commandName ).setState( state );
+					!editor.readOnly && editor.getCommand( commandName ).setState( state );
 				});
 
Index: CKEditor/branches/versions/3.6.x/_source/plugins/bidi/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/bidi/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/bidi/plugin.js	(revision 6772)
@@ -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/versions/3.6.x/_source/plugins/blockquote/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/blockquote/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/blockquote/plugin.js	(revision 6772)
@@ -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/versions/3.6.x/_source/plugins/button/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/button/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/button/plugin.js	(revision 6772)
@@ -142,17 +142,31 @@
 		{
 			var modeStates = {};
+
+			function updateState()
+			{
+				// "this" is a CKEDITOR.ui.button instance.
+
+				var mode = editor.mode;
+
+				if ( mode )
+				{
+					// Restore saved button state.
+					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 );
+				}
+			}
+
 			editor.on( 'beforeModeUnload', function()
 				{
-					modeStates[ editor.mode ] = this._.state;
+					if ( editor.mode && this._.state != CKEDITOR.TRISTATE_DISABLED )
+						modeStates[ editor.mode ] = this._.state;
 				}, this );
 
-			editor.on( 'mode', function()
-				{
-					var mode = editor.mode;
-					// Restore saved button state.
-					this.setState( this.modes[ mode ] ?
-						modeStates[ mode ] != undefined ? modeStates[ mode ] :
-							CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED );
-				}, this);
+			editor.on( 'mode', updateState, this);
+
+			// If this button is sensitive to readOnly state, update it accordingly.
+			!this.readOnly && editor.on( 'readOnly', updateState, this);
 		}
 		else if ( command )
Index: CKEditor/branches/versions/3.6.x/_source/plugins/clipboard/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/clipboard/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/clipboard/plugin.js	(revision 6772)
@@ -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/versions/3.6.x/_source/plugins/editingblock/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/editingblock/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/editingblock/plugin.js	(revision 6772)
@@ -11,9 +11,4 @@
 (function()
 {
-	var getMode = function( editor, mode )
-	{
-		return editor._.modes && editor._.modes[ mode || editor.mode ];
-	};
-
 	// This is a semaphore used to avoid recursive calls between
 	// the following data handling functions.
@@ -50,5 +45,5 @@
 						{
 							isHandlingData = true;
-							getMode( editor ).loadData( editor.getData() );
+							editor.getMode().loadData( editor.getData() );
 							isHandlingData = false;
 						}
@@ -60,6 +55,9 @@
 							editor.on( 'mode', function()
 								{
-									setData();
-									editor.removeListener( 'mode', arguments.callee );
+									if ( editor.mode )
+									{
+										setData();
+										editor.removeListener( 'mode', arguments.callee );
+									}
 								});
 						}
@@ -72,5 +70,5 @@
 					{
 						isHandlingData = true;
-						editor.setData( getMode( editor ).getData(), null, 1 );
+						editor.setData( editor.getMode().getData(), null, 1 );
 						isHandlingData = false;
 					}
@@ -80,5 +78,5 @@
 				{
 					if ( editor.mode )
-						event.data = getMode( editor ).getSnapshotData();
+						event.data = editor.getMode().getSnapshotData();
 				});
 
@@ -86,5 +84,5 @@
 				{
 					if ( editor.mode )
-						getMode( editor ).loadSnapshotData( event.data );
+						editor.getMode().loadSnapshotData( event.data );
 				});
 
@@ -168,5 +166,5 @@
 			this.fire( 'beforeModeUnload' );
 
-			var currentMode = getMode( this );
+			var currentMode = this.getMode();
 			data = currentMode.getData();
 			currentMode.unload( holderElement );
@@ -177,5 +175,5 @@
 
 		// Load required mode.
-		var modeEditor = getMode( this, mode );
+		var modeEditor = this.getMode( mode );
 		if ( !modeEditor )
 			throw '[CKEDITOR.editor.setMode] Unknown mode "' + mode + '".';
@@ -194,4 +192,15 @@
 
 	/**
+	 * Gets the current or any of the objects that represent the editing
+	 * area modes. The two most common editing modes are "wysiwyg" and "source".
+	 * @param {String} [mode] The mode to be retrieved. If not specified, the
+	 *		current one is returned.
+	 */
+	CKEDITOR.editor.prototype.getMode = function( mode )
+	{
+		return this._.modes && this._.modes[ mode || this.mode ];
+	};
+
+	/**
 	 * Moves the selection focus to the editing are space in the editor.
 	 */
@@ -199,5 +208,5 @@
 	{
 		this.forceNextSelectionCheck();
-		var mode = getMode( this );
+		var mode = this.getMode();
 		if ( mode )
 			mode.focus();
Index: CKEditor/branches/versions/3.6.x/_source/plugins/elementspath/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/elementspath/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/elementspath/plugin.js	(revision 6772)
@@ -16,4 +16,5 @@
 		{
 			editorFocus : false,
+			readOnly : 1,
 			exec : function( editor )
 			{
Index: CKEditor/branches/versions/3.6.x/_source/plugins/enterkey/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/enterkey/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/enterkey/plugin.js	(revision 6772)
@@ -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/versions/3.6.x/_source/plugins/find/dialogs/find.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/find/dialogs/find.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/find/dialogs/find.js	(revision 6772)
@@ -855,4 +855,6 @@
 
 				this.selectPage( startupPage );
+
+				this[ ( startupPage == 'find' && this._.editor.readOnly? 'hide' : 'show' ) + 'Page' ]( 'replace');
 			},
 			onHide : function()
Index: CKEditor/branches/versions/3.6.x/_source/plugins/find/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/find/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/find/plugin.js	(revision 6772)
@@ -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/versions/3.6.x/_source/plugins/indent/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/indent/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/indent/plugin.js	(revision 6772)
@@ -16,4 +16,7 @@
 	function onSelectionChange( evt )
 	{
+		if ( evt.editor.readOnly )
+			return;
+
 		var editor = evt.editor,
 			elementPath = evt.data.path,
Index: CKEditor/branches/versions/3.6.x/_source/plugins/justify/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/justify/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/justify/plugin.js	(revision 6772)
@@ -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/versions/3.6.x/_source/plugins/link/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/link/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/link/plugin.js	(revision 6772)
@@ -68,4 +68,7 @@
 		 editor.on( 'selectionChange', function( evt )
 			{
+				if ( editor.readOnly )
+					return;
+
 				/*
 				 * Despite our initial hope, document.queryCommandEnabled() does not work
Index: CKEditor/branches/versions/3.6.x/_source/plugins/list/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/list/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/list/plugin.js	(revision 6772)
@@ -219,4 +219,7 @@
 	function onSelectionChange( evt )
 	{
+		if ( evt.editor.readOnly )
+			return;
+
 		var path = evt.data.path,
 			blockLimit = path.blockLimit,
Index: CKEditor/branches/versions/3.6.x/_source/plugins/maximize/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/maximize/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/maximize/plugin.js	(revision 6772)
@@ -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/versions/3.6.x/_source/plugins/menu/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/menu/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/menu/plugin.js	(revision 6772)
@@ -98,5 +98,5 @@
 							var item = this.editor.getMenuItem( itemName );
 
-							if ( item )
+							if ( item && ( !item.command || this.editor.getCommand( item.command ).state ) )
 							{
 								item.state = listenerItems[ itemName ];
Index: CKEditor/branches/versions/3.6.x/_source/plugins/preview/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/preview/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/preview/plugin.js	(revision 6772)
@@ -14,4 +14,5 @@
 		modes : { wysiwyg:1, source:1 },
 		canUndo : false,
+		readOnly : 1,
 		exec : function( editor )
 		{
Index: CKEditor/branches/versions/3.6.x/_source/plugins/print/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/print/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/print/plugin.js	(revision 6772)
@@ -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/versions/3.6.x/_source/plugins/richcombo/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/richcombo/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/richcombo/plugin.js	(revision 6772)
@@ -129,10 +129,14 @@
 			};
 
-			editor.on( 'mode', function()
-				{
-					this.setState( this.modes[ editor.mode ] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED );
-					this.setValue( '' );
-				},
-				this );
+			function updateState()
+			{
+				var state = this.modes[ editor.mode ] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED;
+				this.setState( editor.readOnly && !this.readOnly ? CKEDITOR.TRISTATE_DISABLED : state );
+				this.setValue( '' );
+			}
+
+			editor.on( 'mode', updateState, this );
+			// If this combo is sensitive to readOnly state, update it accordingly.
+			!this.readOnly && editor.on( 'readOnly', updateState, this);
 
 			var keyDownFn = CKEDITOR.tools.addFunction( function( ev, element )
Index: CKEditor/branches/versions/3.6.x/_source/plugins/save/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/save/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/save/plugin.js	(revision 6772)
@@ -13,4 +13,5 @@
 	{
 		modes : { wysiwyg:1, source:1 },
+		readOnly : 1,
 
 		exec : function( editor )
Index: CKEditor/branches/versions/3.6.x/_source/plugins/selection/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/selection/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/selection/plugin.js	(revision 6772)
@@ -93,4 +93,5 @@
 	{
 		modes : { wysiwyg : 1, source : 1 },
+		readOnly : CKEDITOR.env.ie || CKEDITOR.env.webkit,
 		exec : function( editor )
 		{
Index: CKEditor/branches/versions/3.6.x/_source/plugins/showblocks/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/showblocks/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/showblocks/plugin.js	(revision 6772)
@@ -90,4 +90,5 @@
 	var commandDefinition =
 	{
+		readOnly : 1,
 		preserveState : true,
 		editorFocus : false,
@@ -101,6 +102,9 @@
 		refresh : function( editor )
 		{
-			var funcName = ( this.state == CKEDITOR.TRISTATE_ON ) ? 'addClass' : 'removeClass';
-			editor.document.getBody()[ funcName ]( 'cke_show_blocks' );
+			if ( editor.document )
+			{
+				var funcName = ( this.state == CKEDITOR.TRISTATE_ON ) ? 'addClass' : 'removeClass';
+				editor.document.getBody()[ funcName ]( 'cke_show_blocks' );
+			}
 		}
 	};
Index: CKEditor/branches/versions/3.6.x/_source/plugins/showborders/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/showborders/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/showborders/plugin.js	(revision 6772)
@@ -41,4 +41,5 @@
 		preserveState : true,
 		editorFocus : false,
+		readOnly: 1,
 
 		exec : function ( editor )
@@ -50,6 +51,9 @@
 		refresh : function( editor )
 		{
-			var funcName = ( this.state == CKEDITOR.TRISTATE_ON ) ? 'addClass' : 'removeClass';
-			editor.document.getBody()[ funcName ]( 'cke_show_borders' );
+			if ( editor.document )
+			{
+				var funcName = ( this.state == CKEDITOR.TRISTATE_ON ) ? 'addClass' : 'removeClass';
+				editor.document.getBody()[ funcName ]( 'cke_show_borders' );
+			}
 		}
 	};
Index: CKEditor/branches/versions/3.6.x/_source/plugins/sourcearea/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/sourcearea/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/sourcearea/plugin.js	(revision 6772)
@@ -41,4 +41,6 @@
 							textarea.addClass( 'cke_source' );
 							textarea.addClass( 'cke_enable_context_menu' );
+
+							editor.readOnly && textarea.setAttribute( 'readOnly', 'readonly' );
 
 							var styles =
@@ -146,4 +148,15 @@
 						}
 					});
+			});
+
+		editor.on( 'readOnly', function()
+			{
+				if ( editor.mode == 'source' )
+				{
+					if ( editor.readOnly )
+						editor.textarea.setAttribute( 'readOnly', 'readonly' );
+					else
+						editor.textarea.removeAttribute( 'readOnly' );
+				}
 			});
 
@@ -182,5 +195,5 @@
 			modes : { wysiwyg:1, source:1 },
 			editorFocus : false,
-
+			readOnly : 1,
 			exec : function( editor )
 			{
Index: CKEditor/branches/versions/3.6.x/_source/plugins/toolbar/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/toolbar/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/toolbar/plugin.js	(revision 6772)
@@ -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/versions/3.6.x/_source/plugins/undo/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/undo/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/undo/plugin.js	(revision 6772)
@@ -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/versions/3.6.x/_source/plugins/wysiwygarea/plugin.js
===================================================================
--- CKEditor/branches/versions/3.6.x/_source/plugins/wysiwygarea/plugin.js	(revision 6766)
+++ CKEditor/branches/versions/3.6.x/_source/plugins/wysiwygarea/plugin.js	(revision 6772)
@@ -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();
@@ -1138,4 +1141,14 @@
 				});
 
+			editor.on( 'readOnly', function()
+				{
+					if ( editor.mode == 'wysiwyg' )
+					{
+						// Symply reload the wysiwyg area. It'll take care of read-only.
+						var wysiwyg = editor.getMode();
+						wysiwyg.loadData( wysiwyg.getData() );
+					}
+				});
+
 			// IE>=8 stricts mode doesn't have 'contentEditable' in effect
 			// on element unless it has layout. (#5562)
@@ -1167,4 +1180,7 @@
 			function blinkCursor( retry )
 			{
+				if ( editor.readOnly )
+					return;
+
 				CKEDITOR.tools.tryThese(
 					function()
