      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 (function()
      7 {
      8 	CKEDITOR.plugins.add( 'stylescombo',
      9 	{
     10 		requires : [ 'richcombo', 'styles' ],
     11
     12 		init : function( editor )
     13 		{
     14 			var config = editor.config,
     15 				lang = editor.lang.stylesCombo,
     16 				pluginPath = this.path,
     17 				styles;
     18
     19 			editor.ui.addRichCombo( 'Styles',
     20 				{
     21 					label : lang.label,
     22 					title : lang.panelTitle,
     23 					voiceLabel : lang.voiceLabel,
     24 					className : 'cke_styles',
     25 					multiSelect : true,
     26
     27 					panel :
     28 					{
     29 						css : [ config.contentsCss, CKEDITOR.getUrl( editor.skinPath + 'editor.css' ) ],
     30 						voiceLabel : lang.panelVoiceLabel
     31 					},
     32
     33 					init : function()
     34 					{
     35 						var combo = this,
     36 							stylesSet = config.stylesCombo_stylesSet.split( ':', 2 ),
     37 							stylesSetPath = stylesSet[ 1 ] || CKEDITOR.getUrl( pluginPath + 'styles/' + stylesSet[ 0 ] + '.js' ) ;
     38
     39 						stylesSet = stylesSet[ 0 ];
     40
     41 						CKEDITOR.loadStylesSet( stylesSet, stylesSetPath, function( stylesDefinitions )
     42 							{
     43 								var style,
     44 									styleName,
     45 									stylesList = [];
     46
     47 								styles = {};
     48
     49 								// Put all styles into an Array.
     50 								for ( var i = 0 ; i < stylesDefinitions.length ; i++ )
     51 								{
     52 									var styleDefinition = stylesDefinitions[ i ];
     53
     54 									styleName = styleDefinition.name;
     55
     56 									style = styles[ styleName ] = new CKEDITOR.style( styleDefinition );
     57 									style._name = styleName;
     58
     59 									stylesList.push( style );
     60 								}
     61
     62 								// Sorts the Array, so the styles get grouped
     63 								// by type.
     64 								stylesList.sort( sortStyles );
     65
     66 								// Loop over the Array, adding all items to the
     67 								// combo.
     68 								var lastType;
     69 								for ( i = 0 ; i < stylesList.length ; i++ )
     70 								{
     71 									style = stylesList[ i ];
     72 									styleName = style._name;
     73
     74 									var type = style.type;
     75
     76 									if ( type != lastType )
     77 									{
     78 										combo.startGroup( lang[ 'panelTitle' + String( type ) ] );
     79 										lastType = type;
     80 									}
     81
     82 									combo.add(
     83 										styleName,
     84 										style.type == CKEDITOR.STYLE_OBJECT ? styleName : buildPreview( style._.definition ),
     85 										styleName );
     86 								}
     87
     88 								combo.commit();
     89
     90 								combo.onOpen();
     91 							});
     92 					},
     93
     94 					onClick : function( value )
     95 					{
     96 						editor.focus();
     97 						editor.fire( 'saveSnapshot' );
     98
     99 						var style = styles[ value ],
    100 							selection = editor.getSelection();
    101
    102 						if ( style.type == CKEDITOR.STYLE_OBJECT )
    103 						{
    104 							var element = selection.getSelectedElement();
    105 							if ( element )
    106 								style.applyToObject( element );
    107
    108 							return;
    109 						}
    110
    111 						var elementPath = new CKEDITOR.dom.elementPath( selection.getStartElement() );
    112
    113 						if ( style.type == CKEDITOR.STYLE_INLINE && style.checkActive( elementPath ) )
    114 							style.remove( editor.document );
    115 						else
    116 							style.apply( editor.document );
    117
    118 						editor.fire( 'saveSnapshot' );
    119 					},
    120
    121 					onRender : function()
    122 					{
    123 						editor.on( 'selectionChange', function( ev )
    124 							{
    125 								var currentValue = this.getValue();
    126
    127 								var elementPath = ev.data.path,
    128 									elements = elementPath.elements;
    129
    130 								// For each element into the elements path.
    131 								for ( var i = 0, element ; i < elements.length ; i++ )
    132 								{
    133 									element = elements[i];
    134
    135 									// Check if the element is removable by any of
    136 									// the styles.
    137 									for ( var value in styles )
    138 									{
    139 										if ( styles[ value ].checkElementRemovable( element, true ) )
    140 										{
    141 											if ( value != currentValue )
    142 												this.setValue( value );
    143 											return;
    144 										}
    145 									}
    146 								}
    147
    148 								// If no styles match, just empty it.
    149 								this.setValue( '' );
    150 							},
    151 							this);
    152 					},
    153
    154 					onOpen : function()
    155 					{
    156 						if ( CKEDITOR.env.ie )
    157 							editor.focus();
    158
    159 						var selection = editor.getSelection();
    160
    161 						var element = selection.getSelectedElement(),
    162 							elementName = element && element.getName(),
    163 							elementPath = new CKEDITOR.dom.elementPath( element || selection.getStartElement() );
    164
    165 						var counter = [ 0, 0, 0, 0 ];
    166 						this.showAll();
    167 						this.unmarkAll();
    168 						for ( var name in styles )
    169 						{
    170 							var style = styles[ name ],
    171 								type = style.type;
    172
    173 							if ( type == CKEDITOR.STYLE_OBJECT )
    174 							{
    175 								if ( element && style.element == elementName )
    176 								{
    177 									if ( style.checkElementRemovable( element, true ) )
    178 										this.mark( name );
    179
    180 									counter[ type ]++;
    181 								}
    182 								else
    183 									this.hideItem( name );
    184 							}
    185 							else
    186 							{
    187 								if ( style.checkActive( elementPath ) )
    188 									this.mark( name );
    189
    190 								counter[ type ]++;
    191 							}
    192 						}
    193
    194 						if ( !counter[ CKEDITOR.STYLE_BLOCK ] )
    195 							this.hideGroup( lang[ 'panelTitle' + String( CKEDITOR.STYLE_BLOCK ) ] );
    196
    197 						if ( !counter[ CKEDITOR.STYLE_INLINE ] )
    198 							this.hideGroup( lang[ 'panelTitle' + String( CKEDITOR.STYLE_INLINE ) ] );
    199
    200 						if ( !counter[ CKEDITOR.STYLE_OBJECT ] )
    201 							this.hideGroup( lang[ 'panelTitle' + String( CKEDITOR.STYLE_OBJECT ) ] );
    202 					}
    203 				});
    204 		}
    205 	});
    206
    207 	var stylesSets = {};
    208
    209 	CKEDITOR.addStylesSet = function( name, styles )
    210 	{
    211 		stylesSets[ name ] = styles;
    212 	};
    213
    214 	CKEDITOR.loadStylesSet = function( name, url, callback )
    215 	{
    216 		var stylesSet = stylesSets[ name ];
    217
    218 		if ( stylesSet )
    219 		{
    220 			callback( stylesSet );
    221 			return ;
    222 		}
    223
    224 		CKEDITOR.scriptLoader.load( url, function()
    225 			{
    226 				callback( stylesSets[ name ] );
    227 			});
    228 	};
    229
    230 	function buildPreview( styleDefinition )
    231 	{
    232 		var html = [];
    233
    234 		var elementName = styleDefinition.element;
    235
    236 		// Avoid <bdo> in the preview.
    237 		if ( elementName == 'bdo' )
    238 			elementName = 'span';
    239
    240 		html = [ '<', elementName ];
    241
    242 		// Assign all defined attributes.
    243 		var attribs	= styleDefinition.attributes;
    244 		if ( attribs )
    245 		{
    246 			for ( var att in attribs )
    247 			{
    248 				html.push( ' ', att, '="', attribs[ att ], '"' );
    249 			}
    250 		}
    251
    252 		// Assign the style attribute.
    253 		var cssStyle = CKEDITOR.style.getStyleText( styleDefinition );
    254 		if ( cssStyle )
    255 			html.push( ' style="', cssStyle, '"' );
    256
    257 		html.push( '>', styleDefinition.name, '</', elementName, '>' );
    258
    259 		return html.join( '' );
    260 	}
    261
    262 	function sortStyles( styleA, styleB )
    263 	{
    264 		var typeA = styleA.type,
    265 			typeB = styleB.type;
    266
    267 		return typeA == typeB ? 0 :
    268 			typeA == CKEDITOR.STYLE_OBJECT ? -1 :
    269 			typeB == CKEDITOR.STYLE_OBJECT ? 1 :
    270 			typeB == CKEDITOR.STYLE_BLOCK ? 1 :
    271 			-1;
    272 	}
    273 })();
    274
    275 CKEDITOR.config.stylesCombo_stylesSet = 'default';
    276