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