1 /*
  2 Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
  3 For licensing, see LICENSE.html or http://ckeditor.com/license
  4 */
  5 
  6 /**
  7  * @fileOverview The default editing block plugin, which holds the editing area
  8  *		and source view.
  9  */
 10 
 11 (function()
 12 {
 13 	// This is a semaphore used to avoid recursive calls between
 14 	// the following data handling functions.
 15 	var isHandlingData;
 16 
 17 	CKEDITOR.plugins.add( 'editingblock',
 18 	{
 19 		init : function( editor )
 20 		{
 21 			if ( !editor.config.editingBlock )
 22 				return;
 23 
 24 			editor.on( 'themeSpace', function( event )
 25 				{
 26 					if ( event.data.space == 'contents' )
 27 						event.data.html += '<br>';
 28 				});
 29 
 30 			editor.on( 'themeLoaded', function()
 31 				{
 32 					editor.fireOnce( 'editingBlockReady' );
 33 				});
 34 
 35 			editor.on( 'uiReady', function()
 36 				{
 37 					editor.setMode( editor.config.startupMode );
 38 				});
 39 
 40 			editor.on( 'afterSetData', function()
 41 				{
 42 					if ( !isHandlingData )
 43 					{
 44 						function setData()
 45 						{
 46 							isHandlingData = true;
 47 							editor.getMode().loadData( editor.getData() );
 48 							isHandlingData = false;
 49 						}
 50 
 51 						if ( editor.mode )
 52 							setData();
 53 						else
 54 						{
 55 							editor.on( 'mode', function()
 56 								{
 57 									if ( editor.mode )
 58 									{
 59 										setData();
 60 										editor.removeListener( 'mode', arguments.callee );
 61 									}
 62 								});
 63 						}
 64 					}
 65 				});
 66 
 67 			editor.on( 'beforeGetData', function()
 68 				{
 69 					if ( !isHandlingData && editor.mode )
 70 					{
 71 						isHandlingData = true;
 72 						editor.setData( editor.getMode().getData(), null, 1 );
 73 						isHandlingData = false;
 74 					}
 75 				});
 76 
 77 			editor.on( 'getSnapshot', function( event )
 78 				{
 79 					if ( editor.mode )
 80 						event.data = editor.getMode().getSnapshotData();
 81 				});
 82 
 83 			editor.on( 'loadSnapshot', function( event )
 84 				{
 85 					if ( editor.mode )
 86 						editor.getMode().loadSnapshotData( event.data );
 87 				});
 88 
 89 			// For the first "mode" call, we'll also fire the "instanceReady"
 90 			// event.
 91 			editor.on( 'mode', function( event )
 92 				{
 93 					// Do that once only.
 94 					event.removeListener();
 95 
 96 					// Redirect the focus into editor for webkit. (#5713)
 97 					CKEDITOR.env.webkit && editor.container.on( 'focus', function()
 98 						{
 99 							editor.focus();
100 						});
101 
102 					if ( editor.config.startupFocus )
103 						editor.focus();
104 
105 					// Fire instanceReady for both the editor and CKEDITOR, but
106 					// defer this until the whole execution has completed
107 					// to guarantee the editor is fully responsible.
108 					setTimeout( function(){
109 						editor.fireOnce( 'instanceReady' );
110 						CKEDITOR.fire( 'instanceReady', null, editor );
111 					}, 0 );
112 				});
113 
114 			editor.on( 'destroy', function ()
115 			{
116 				// ->		currentMode.unload( holderElement );
117 				if ( this.mode )
118 					this._.modes[ this.mode ].unload( this.getThemeSpace( 'contents' ) );
119 			});
120 		}
121 	});
122 
123 	/**
124 	 * The current editing mode. An editing mode is basically a viewport for
125 	 * editing or content viewing. By default the possible values for this
126 	 * property are "wysiwyg" and "source".
127 	 * @type String
128 	 * @example
129 	 * alert( CKEDITOR.instances.editor1.mode );  // "wysiwyg" (e.g.)
130 	 */
131 	CKEDITOR.editor.prototype.mode = '';
132 
133 	/**
134 	 * Registers an editing mode. This function is to be used mainly by plugins.
135 	 * @param {String} mode The mode name.
136 	 * @param {Object} modeEditor The mode editor definition.
137 	 * @example
138 	 */
139 	CKEDITOR.editor.prototype.addMode = function( mode, modeEditor )
140 	{
141 		modeEditor.name = mode;
142 		( this._.modes || ( this._.modes = {} ) )[ mode ] = modeEditor;
143 	};
144 
145 	/**
146 	 * Sets the current editing mode in this editor instance.
147 	 * @param {String} mode A registered mode name.
148 	 * @example
149 	 * // Switch to "source" view.
150 	 * CKEDITOR.instances.editor1.setMode( 'source' );
151 	 */
152 	CKEDITOR.editor.prototype.setMode = function( mode )
153 	{
154 		this.fire( 'beforeSetMode', { newMode : mode } );
155 
156 		var data,
157 			holderElement = this.getThemeSpace( 'contents' ),
158 			isDirty = this.checkDirty();
159 
160 		// Unload the previous mode.
161 		if ( this.mode )
162 		{
163 			if ( mode == this.mode )
164 				return;
165 
166 			this._.previousMode = this.mode;
167 
168 			this.fire( 'beforeModeUnload' );
169 
170 			var currentMode = this.getMode();
171 			data = currentMode.getData();
172 			currentMode.unload( holderElement );
173 			this.mode = '';
174 		}
175 
176 		holderElement.setHtml( '' );
177 
178 		// Load required mode.
179 		var modeEditor = this.getMode( mode );
180 		if ( !modeEditor )
181 			throw '[CKEDITOR.editor.setMode] Unknown mode "' + mode + '".';
182 
183 		if ( !isDirty )
184 		{
185 			this.on( 'mode', function()
186 				{
187 					this.resetDirty();
188 					this.removeListener( 'mode', arguments.callee );
189 				});
190 		}
191 
192 		modeEditor.load( holderElement, ( typeof data ) != 'string'  ? this.getData() : data );
193 	};
194 
195 	/**
196 	 * Gets the current or any of the objects that represent the editing
197 	 * area modes. The two most common editing modes are "wysiwyg" and "source".
198 	 * @param {String} [mode] The mode to be retrieved. If not specified, the
199 	 *		current one is returned.
200 	 */
201 	CKEDITOR.editor.prototype.getMode = function( mode )
202 	{
203 		return this._.modes && this._.modes[ mode || this.mode ];
204 	};
205 
206 	/**
207 	 * Moves the selection focus to the editing are space in the editor.
208 	 */
209 	CKEDITOR.editor.prototype.focus = function()
210 	{
211 		this.forceNextSelectionCheck();
212 		var mode = this.getMode();
213 		if ( mode )
214 			mode.focus();
215 	};
216 })();
217 
218 /**
219  * The mode to load at the editor startup. It depends on the plugins
220  * loaded. By default, the "wysiwyg" and "source" modes are available.
221  * @type String
222  * @default 'wysiwyg'
223  * @example
224  * config.startupMode = 'source';
225  */
226 CKEDITOR.config.startupMode = 'wysiwyg';
227 
228 /**
229  * Sets whether the editor should have the focus when the page loads.
230  * @name CKEDITOR.config.startupFocus
231  * @type Boolean
232  * @default false
233  * @example
234  * config.startupFocus = true;
235  */
236 
237 /**
238  * Whether to render or not the editing block area in the editor interface.
239  * @type Boolean
240  * @default true
241  * @example
242  * config.editingBlock = false;
243  */
244 CKEDITOR.config.editingBlock = true;
245 
246 /**
247  * Fired when a CKEDITOR instance is created, fully initialized and ready for interaction.
248  * @name CKEDITOR#instanceReady
249  * @event
250  * @param {CKEDITOR.editor} editor The editor instance that has been created.
251  */
252 
253 /**
254  * Fired when the CKEDITOR instance is created, fully initialized and ready for interaction.
255  * @name CKEDITOR.editor#instanceReady
256  * @event
257  */
258 
259 /**
260  * Fired before changing the editing mode. See also CKEDITOR.editor#beforeSetMode and CKEDITOR.editor#mode
261  * @name CKEDITOR.editor#beforeModeUnload
262  * @event
263  */
264 
265  /**
266  * Fired before the editor mode is set. See also CKEDITOR.editor#mode and CKEDITOR.editor#beforeModeUnload
267  * @name CKEDITOR.editor#beforeSetMode
268  * @event
269  * @since 3.5.3
270  * @param {String} newMode The name of the mode which is about to be set.
271  */
272 
273 /**
274  * Fired after setting the editing mode. See also CKEDITOR.editor#beforeSetMode and CKEDITOR.editor#beforeModeUnload
275  * @name CKEDITOR.editor#mode
276  * @event
277  * @param {String} previousMode The previous mode of the editor.
278  */
279