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 "show border" plugin. The command display visible outline
  8  * border line around all table elements if table doesn't have a none-zero 'border' attribute specified.
  9  */
 10 
 11 (function()
 12 {
 13 	var showBorderClassName = 'cke_show_border',
 14 		cssStyleText,
 15 		cssTemplate =
 16 		// TODO: For IE6, we don't have child selector support,
 17 		// where nested table cells could be incorrect.
 18 		( CKEDITOR.env.ie6Compat ?
 19 		  [
 20 			'.%1 table.%2,',
 21 			 '.%1 table.%2 td, .%1 table.%2 th',
 22 			 '{',
 23 				'border : #d3d3d3 1px dotted',
 24 			 '}'
 25 		  ] :
 26 		  [
 27 			 '.%1 table.%2,',
 28 			 '.%1 table.%2 > tr > td, .%1 table.%2 > tr > th,',
 29 			 '.%1 table.%2 > tbody > tr > td, .%1 table.%2 > tbody > tr > th,',
 30 			 '.%1 table.%2 > thead > tr > td, .%1 table.%2 > thead > tr > th,',
 31 			 '.%1 table.%2 > tfoot > tr > td, .%1 table.%2 > tfoot > tr > th',
 32 			 '{',
 33 				'border : #d3d3d3 1px dotted',
 34 			 '}'
 35 		  ] ).join( '' );
 36 
 37 	cssStyleText = cssTemplate.replace( /%2/g, showBorderClassName ).replace( /%1/g, 'cke_show_borders ' );
 38 
 39 	var commandDefinition =
 40 	{
 41 		preserveState : true,
 42 		editorFocus : false,
 43 		readOnly: 1,
 44 
 45 		exec : function ( editor )
 46 		{
 47 			this.toggleState();
 48 			this.refresh( editor );
 49 		},
 50 
 51 		refresh : function( editor )
 52 		{
 53 			if ( editor.document )
 54 			{
 55 				var funcName = ( this.state == CKEDITOR.TRISTATE_ON ) ? 'addClass' : 'removeClass';
 56 				editor.document.getBody()[ funcName ]( 'cke_show_borders' );
 57 			}
 58 		}
 59 	};
 60 
 61 	CKEDITOR.plugins.add( 'showborders',
 62 	{
 63 		requires : [ 'wysiwygarea' ],
 64 		modes : { 'wysiwyg' : 1 },
 65 
 66 		init : function( editor )
 67 		{
 68 
 69 			var command = editor.addCommand( 'showborders', commandDefinition );
 70 			command.canUndo = false;
 71 
 72 			if ( editor.config.startupShowBorders !== false )
 73 				command.setState( CKEDITOR.TRISTATE_ON );
 74 
 75 			editor.addCss( cssStyleText );
 76 
 77 			// Refresh the command on setData.
 78 			editor.on( 'mode', function()
 79 				{
 80 					if ( command.state != CKEDITOR.TRISTATE_DISABLED )
 81 						command.refresh( editor );
 82 				}, null, null, 100 );
 83 
 84 			// Refresh the command on wysiwyg frame reloads.
 85 			editor.on( 'contentDom', function()
 86 				{
 87 					if ( command.state != CKEDITOR.TRISTATE_DISABLED )
 88 						command.refresh( editor );
 89 				});
 90 
 91 			editor.on( 'removeFormatCleanup', function( evt )
 92 				{
 93 					var element = evt.data;
 94 					if ( editor.getCommand( 'showborders' ).state == CKEDITOR.TRISTATE_ON &&
 95 						element.is( 'table' ) && ( !element.hasAttribute( 'border' ) || parseInt( element.getAttribute( 'border' ), 10 ) <= 0 ) )
 96 							element.addClass( showBorderClassName );
 97 				});
 98 		},
 99 
100 		afterInit : function( editor )
101 		{
102 			var dataProcessor = editor.dataProcessor,
103 				dataFilter = dataProcessor && dataProcessor.dataFilter,
104 				htmlFilter = dataProcessor && dataProcessor.htmlFilter;
105 
106 			if ( dataFilter )
107 			{
108 				dataFilter.addRules(
109 					{
110 						elements :
111 						{
112 							'table' : function( element )
113 							{
114 								var attributes = element.attributes,
115 									cssClass = attributes[ 'class' ],
116 									border = parseInt( attributes.border, 10 );
117 
118 								if ( ( !border || border <= 0 ) && ( !cssClass || cssClass.indexOf( showBorderClassName ) == -1 ) )
119 									attributes[ 'class' ] = ( cssClass || '' ) + ' ' + showBorderClassName;
120 							}
121 						}
122 					} );
123 			}
124 
125 			if ( htmlFilter )
126 			{
127 				htmlFilter.addRules(
128 				{
129 					elements :
130 					{
131 						'table' : function( table )
132 						{
133 							var attributes = table.attributes,
134 								cssClass = attributes[ 'class' ];
135 
136 							cssClass && ( attributes[ 'class' ] =
137 							              cssClass.replace( showBorderClassName, '' )
138 									              .replace( /\s{2}/, ' ' )
139 												  .replace( /^\s+|\s+$/, '' ) );
140 						}
141 					}
142 				} );
143 			}
144 		}
145 	});
146 
147 	// Table dialog must be aware of it.
148 	CKEDITOR.on( 'dialogDefinition', function( ev )
149 	{
150 		var dialogName = ev.data.name;
151 
152 		if ( dialogName == 'table' || dialogName == 'tableProperties' )
153 		{
154 			var dialogDefinition = ev.data.definition,
155 				infoTab = dialogDefinition.getContents( 'info' ),
156 				borderField = infoTab.get( 'txtBorder' ),
157 				originalCommit = borderField.commit;
158 
159 			borderField.commit = CKEDITOR.tools.override( originalCommit, function( org )
160 			{
161 				return function( data, selectedTable )
162 					{
163 						org.apply( this, arguments );
164 						var value = parseInt( this.getValue(), 10 );
165 						selectedTable[ ( !value || value <= 0 ) ? 'addClass' : 'removeClass' ]( showBorderClassName );
166 					};
167 			} );
168 
169 			var advTab = dialogDefinition.getContents( 'advanced' ),
170 				classField = advTab && advTab.get( 'advCSSClasses' );
171 
172 			if ( classField )
173 			{
174 				classField.setup = CKEDITOR.tools.override( classField.setup, function( originalSetup )
175 					{
176 						return function()
177 							{
178 								originalSetup.apply( this, arguments );
179 								this.setValue( this.getValue().replace( /cke_show_border/, '' ) );
180 							};
181 					});
182 
183 				classField.commit = CKEDITOR.tools.override( classField.commit, function( originalCommit )
184 					{
185 						return function( data, element )
186 							{
187 								originalCommit.apply( this, arguments );
188 
189 								if ( !parseInt( element.getAttribute( 'border' ), 10 ) )
190 									element.addClass( 'cke_show_border' );
191 							};
192 					});
193 			}
194 		}
195 	});
196 
197 } )();
198 
199 /**
200  * Whether to automatically enable the "show borders" command when the editor loads.
201  * (ShowBorders in FCKeditor)
202  * @name CKEDITOR.config.startupShowBorders
203  * @type Boolean
204  * @default true
205  * @example
206  * config.startupShowBorders = false;
207  */
208