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