1 /*
  2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
  3 For licensing, see LICENSE.html or http://ckeditor.com/license
  4 */
  5
  6 /**
  7  * @fileOverview The "sourcearea" plugin. It registers the "source" editing
  8  *		mode, which displays the raw data being edited in the editor.
  9  */
 10
 11 CKEDITOR.plugins.add( 'sourcearea',
 12 {
 13 	requires : [ 'editingblock' ],
 14
 15 	init : function( editor )
 16 	{
 17 		var sourcearea = CKEDITOR.plugins.sourcearea;
 18
 19 		editor.on( 'editingBlockReady', function()
 20 			{
 21 				var textarea,
 22 					onResize;
 23
 24 				editor.addMode( 'source',
 25 					{
 26 						load : function( holderElement, data )
 27 						{
 28 							if ( CKEDITOR.env.ie && CKEDITOR.env.version < 8 )
 29 								holderElement.setStyle( 'position', 'relative' );
 30
 31 							// Create the source area <textarea>.
 32 							editor.textarea = textarea = new CKEDITOR.dom.element( 'textarea' );
 33 							textarea.setAttributes(
 34 								{
 35 									dir : 'ltr',
 36 									tabIndex : -1
 37 								});
 38 							textarea.addClass( 'cke_source' );
 39
 40 							var styles =
 41 							{
 42 								width	: '100%',
 43 								height	: '100%',
 44 								resize	: 'none',
 45 								outline	: 'none',
 46 								'text-align' : 'left'
 47 							};
 48
 49 							// The textarea height/width='100%' doesn't
 50 							// constraint to the 'td' in IE strick mode
 51 							if ( CKEDITOR.env.ie )
 52 							{
 53 								if ( !CKEDITOR.env.ie8Compat )
 54 								{
 55 									onResize = function()
 56 										{
 57 											// Holder rectange size is stretched by textarea,
 58 											// so hide it just for a moment.
 59 											textarea.hide();
 60 											textarea.setStyle( 'height', holderElement.$.clientHeight + 'px' );
 61 											// When we have proper holder size, show textarea again.
 62 											textarea.show();
 63 										};
 64 									editor.on( 'resize', onResize );
 65 									styles.height = holderElement.$.clientHeight + 'px';
 66 								}
 67 							}
 68 							else
 69 							{
 70 								// By some yet unknown reason, we must stop the
 71 								// mousedown propagation for the textarea,
 72 								// otherwise it's not possible to place the caret
 73 								// inside of it (non IE).
 74 								textarea.on( 'mousedown', function( evt )
 75 									{
 76 										evt = evt.data.$;
 77 										if ( evt.stopPropagation )
 78 											evt.stopPropagation();
 79 									} );
 80 							}
 81
 82 							// Reset the holder element and append the
 83 							// <textarea> to it.
 84 							holderElement.setHtml( '' );
 85 							holderElement.append( textarea );
 86 							textarea.setStyles( styles );
 87
 88 							// The editor data "may be dirty" after this point.
 89 							editor.mayBeDirty = true;
 90
 91 							// Set the <textarea> value.
 92 							this.loadData( data );
 93
 94 							var keystrokeHandler = editor.keystrokeHandler;
 95 							if ( keystrokeHandler )
 96 								keystrokeHandler.attach( textarea );
 97
 98 							setTimeout( function()
 99 							{
100 								editor.mode = 'source';
101 								editor.fire( 'mode' );
102 							},
103 							( CKEDITOR.env.gecko || CKEDITOR.env.webkit ) ? 100 : 0 );
104 						},
105
106 						loadData : function( data )
107 						{
108 							textarea.setValue( data );
109 						},
110
111 						getData : function()
112 						{
113 							return textarea.getValue();
114 						},
115
116 						getSnapshotData : function()
117 						{
118 							return textarea.getValue();
119 						},
120
121 						unload : function( holderElement )
122 						{
123 							editor.textarea = textarea = null;
124
125 							if ( onResize )
126 								editor.removeListener( 'resize', onResize );
127 						},
128
129 						focus : function()
130 						{
131 							textarea.focus();
132 						}
133 					});
134 			});
135
136 		editor.addCommand( 'source', sourcearea.commands.source );
137
138 		if ( editor.ui.addButton )
139 		{
140 			editor.ui.addButton( 'Source',
141 				{
142 					label : editor.lang.source,
143 					command : 'source'
144 				});
145 		}
146
147 		editor.on( 'mode', function()
148 			{
149 				editor.getCommand( 'source' ).setState(
150 					editor.mode == 'source' ?
151 						CKEDITOR.TRISTATE_ON :
152 						CKEDITOR.TRISTATE_OFF );
153 			});
154 	}
155 });
156
157 /**
158  * Holds the definition of commands an UI elements included with the sourcearea
159  * plugin.
160  * @example
161  */
162 CKEDITOR.plugins.sourcearea =
163 {
164 	commands :
165 	{
166 		source :
167 		{
168 			modes : { wysiwyg:1, source:1 },
169
170 			exec : function( editor )
171 			{
172 				if ( editor.mode == 'wysiwyg' )
173 					editor.fire( 'saveSnapshot' );
174 				editor.getCommand( 'source' ).setState( CKEDITOR.TRISTATE_DISABLED );
175 				editor.setMode( editor.mode == 'source' ? 'wysiwyg' : 'source' );
176 			},
177
178 			canUndo : false
179 		}
180 	}
181 };
182