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 "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 win = CKEDITOR.document.getWindow(); 19 20 editor.on( 'editingBlockReady', function() 21 { 22 var textarea, 23 onResize; 24 25 editor.addMode( 'source', 26 { 27 load : function( holderElement, data ) 28 { 29 if ( CKEDITOR.env.ie && CKEDITOR.env.version < 8 ) 30 holderElement.setStyle( 'position', 'relative' ); 31 32 // Create the source area <textarea>. 33 editor.textarea = textarea = new CKEDITOR.dom.element( 'textarea' ); 34 textarea.setAttributes( 35 { 36 dir : 'ltr', 37 tabIndex : CKEDITOR.env.webkit ? -1 : editor.tabIndex, 38 'role' : 'textbox', 39 'aria-label' : editor.lang.editorTitle.replace( '%1', editor.name ) 40 }); 41 textarea.addClass( 'cke_source' ); 42 textarea.addClass( 'cke_enable_context_menu' ); 43 44 editor.readOnly && textarea.setAttribute( 'readOnly', 'readonly' ); 45 46 var styles = 47 { 48 // IE7 has overflow the <textarea> from wrapping table cell. 49 width : CKEDITOR.env.ie7Compat ? '99%' : '100%', 50 height : '100%', 51 resize : 'none', 52 outline : 'none', 53 'text-align' : 'left' 54 }; 55 56 // Having to make <textarea> fixed sized to conque the following bugs: 57 // 1. The textarea height/width='100%' doesn't constraint to the 'td' in IE6/7. 58 // 2. Unexpected vertical-scrolling behavior happens whenever focus is moving out of editor 59 // if text content within it has overflowed. (#4762) 60 if ( CKEDITOR.env.ie ) 61 { 62 onResize = function() 63 { 64 // Holder rectange size is stretched by textarea, 65 // so hide it just for a moment. 66 textarea.hide(); 67 textarea.setStyle( 'height', holderElement.$.clientHeight + 'px' ); 68 textarea.setStyle( 'width', holderElement.$.clientWidth + 'px' ); 69 // When we have proper holder size, show textarea again. 70 textarea.show(); 71 }; 72 73 editor.on( 'resize', onResize ); 74 win.on( 'resize', onResize ); 75 setTimeout( onResize, 0 ); 76 } 77 78 // Reset the holder element and append the 79 // <textarea> to it. 80 holderElement.setHtml( '' ); 81 holderElement.append( textarea ); 82 textarea.setStyles( styles ); 83 84 editor.fire( 'ariaWidget', textarea ); 85 86 textarea.on( 'blur', function() 87 { 88 editor.focusManager.blur(); 89 }); 90 91 textarea.on( 'focus', function() 92 { 93 editor.focusManager.focus(); 94 }); 95 96 // The editor data "may be dirty" after this point. 97 editor.mayBeDirty = true; 98 99 // Set the <textarea> value. 100 this.loadData( data ); 101 102 var keystrokeHandler = editor.keystrokeHandler; 103 if ( keystrokeHandler ) 104 keystrokeHandler.attach( textarea ); 105 106 setTimeout( function() 107 { 108 editor.mode = 'source'; 109 editor.fire( 'mode', { previousMode : editor._.previousMode } ); 110 }, 111 ( CKEDITOR.env.gecko || CKEDITOR.env.webkit ) ? 100 : 0 ); 112 }, 113 114 loadData : function( data ) 115 { 116 textarea.setValue( data ); 117 editor.fire( 'dataReady' ); 118 }, 119 120 getData : function() 121 { 122 return textarea.getValue(); 123 }, 124 125 getSnapshotData : function() 126 { 127 return textarea.getValue(); 128 }, 129 130 unload : function( holderElement ) 131 { 132 textarea.clearCustomData(); 133 editor.textarea = textarea = null; 134 135 if ( onResize ) 136 { 137 editor.removeListener( 'resize', onResize ); 138 win.removeListener( 'resize', onResize ); 139 } 140 141 if ( CKEDITOR.env.ie && CKEDITOR.env.version < 8 ) 142 holderElement.removeStyle( 'position' ); 143 }, 144 145 focus : function() 146 { 147 textarea.focus(); 148 } 149 }); 150 }); 151 152 editor.on( 'readOnly', function() 153 { 154 if ( editor.mode == 'source' ) 155 { 156 if ( editor.readOnly ) 157 editor.textarea.setAttribute( 'readOnly', 'readonly' ); 158 else 159 editor.textarea.removeAttribute( 'readOnly' ); 160 } 161 }); 162 163 editor.addCommand( 'source', sourcearea.commands.source ); 164 165 if ( editor.ui.addButton ) 166 { 167 editor.ui.addButton( 'Source', 168 { 169 label : editor.lang.source, 170 command : 'source' 171 }); 172 } 173 174 editor.on( 'mode', function() 175 { 176 editor.getCommand( 'source' ).setState( 177 editor.mode == 'source' ? 178 CKEDITOR.TRISTATE_ON : 179 CKEDITOR.TRISTATE_OFF ); 180 }); 181 } 182 }); 183 184 /** 185 * Holds the definition of commands an UI elements included with the sourcearea 186 * plugin. 187 * @example 188 */ 189 CKEDITOR.plugins.sourcearea = 190 { 191 commands : 192 { 193 source : 194 { 195 modes : { wysiwyg:1, source:1 }, 196 editorFocus : false, 197 readOnly : 1, 198 exec : function( editor ) 199 { 200 if ( editor.mode == 'wysiwyg' ) 201 editor.fire( 'saveSnapshot' ); 202 editor.getCommand( 'source' ).setState( CKEDITOR.TRISTATE_DISABLED ); 203 editor.setMode( editor.mode == 'source' ? 'wysiwyg' : 'source' ); 204 }, 205 206 canUndo : false 207 } 208 } 209 }; 210