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 (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 styles = {}, 17 stylesList = [], 18 combo; 19 20 function loadStylesSet( callback ) 21 { 22 editor.getStylesSet( function( stylesDefinitions ) 23 { 24 if ( !stylesList.length ) 25 { 26 var style, 27 styleName; 28 29 // Put all styles into an Array. 30 for ( var i = 0, count = stylesDefinitions.length ; i < count ; i++ ) 31 { 32 var styleDefinition = stylesDefinitions[ i ]; 33 34 styleName = styleDefinition.name; 35 36 style = styles[ styleName ] = new CKEDITOR.style( styleDefinition ); 37 style._name = styleName; 38 style._.enterMode = config.enterMode; 39 40 stylesList.push( style ); 41 } 42 43 // Sorts the Array, so the styles get grouped by type. 44 stylesList.sort( sortStyles ); 45 } 46 47 callback && callback(); 48 }); 49 } 50 51 editor.ui.addRichCombo( 'Styles', 52 { 53 label : lang.label, 54 title : lang.panelTitle, 55 className : 'cke_styles', 56 57 panel : 58 { 59 css : editor.skin.editor.css.concat( config.contentsCss ), 60 multiSelect : true, 61 attributes : { 'aria-label' : lang.panelTitle } 62 }, 63 64 init : function() 65 { 66 combo = this; 67 68 loadStylesSet( function() 69 { 70 var style, 71 styleName, 72 lastType, 73 type, 74 i, 75 count; 76 77 // Loop over the Array, adding all items to the 78 // combo. 79 for ( i = 0, count = stylesList.length ; i < count ; i++ ) 80 { 81 style = stylesList[ i ]; 82 styleName = style._name; 83 type = style.type; 84 85 if ( type != lastType ) 86 { 87 combo.startGroup( lang[ 'panelTitle' + String( type ) ] ); 88 lastType = type; 89 } 90 91 combo.add( 92 styleName, 93 style.type == CKEDITOR.STYLE_OBJECT ? styleName : style.buildPreview(), 94 styleName ); 95 } 96 97 combo.commit(); 98 99 }); 100 }, 101 102 onClick : function( value ) 103 { 104 editor.focus(); 105 editor.fire( 'saveSnapshot' ); 106 107 var style = styles[ value ], 108 selection = editor.getSelection(), 109 elementPath = new CKEDITOR.dom.elementPath( selection.getStartElement() ); 110 111 style[ style.checkActive( elementPath ) ? 'remove' : 'apply' ]( editor.document ); 112 113 editor.fire( 'saveSnapshot' ); 114 }, 115 116 onRender : function() 117 { 118 editor.on( 'selectionChange', function( ev ) 119 { 120 var currentValue = this.getValue(), 121 elementPath = ev.data.path, 122 elements = elementPath.elements; 123 124 // For each element into the elements path. 125 for ( var i = 0, count = elements.length, element ; i < count ; i++ ) 126 { 127 element = elements[i]; 128 129 // Check if the element is removable by any of 130 // the styles. 131 for ( var value in styles ) 132 { 133 if ( styles[ value ].checkElementRemovable( element, true ) ) 134 { 135 if ( value != currentValue ) 136 this.setValue( value ); 137 return; 138 } 139 } 140 } 141 142 // If no styles match, just empty it. 143 this.setValue( '' ); 144 }, 145 this); 146 }, 147 148 onOpen : function() 149 { 150 if ( CKEDITOR.env.ie || CKEDITOR.env.webkit ) 151 editor.focus(); 152 153 var selection = editor.getSelection(), 154 element = selection.getSelectedElement(), 155 elementPath = new CKEDITOR.dom.elementPath( element || selection.getStartElement() ), 156 counter = [ 0, 0, 0, 0 ]; 157 158 this.showAll(); 159 this.unmarkAll(); 160 for ( var name in styles ) 161 { 162 var style = styles[ name ], 163 type = style.type; 164 165 if ( style.checkActive( elementPath ) ) 166 this.mark( name ); 167 else if ( type == CKEDITOR.STYLE_OBJECT && !style.checkApplicable( elementPath ) ) 168 { 169 this.hideItem( name ); 170 counter[ type ]--; 171 } 172 173 counter[ type ]++; 174 } 175 176 if ( !counter[ CKEDITOR.STYLE_BLOCK ] ) 177 this.hideGroup( lang[ 'panelTitle' + String( CKEDITOR.STYLE_BLOCK ) ] ); 178 179 if ( !counter[ CKEDITOR.STYLE_INLINE ] ) 180 this.hideGroup( lang[ 'panelTitle' + String( CKEDITOR.STYLE_INLINE ) ] ); 181 182 if ( !counter[ CKEDITOR.STYLE_OBJECT ] ) 183 this.hideGroup( lang[ 'panelTitle' + String( CKEDITOR.STYLE_OBJECT ) ] ); 184 }, 185 186 // Force a reload of the data 187 reset: function() 188 { 189 if ( combo ) 190 { 191 delete combo._.panel; 192 delete combo._.list; 193 combo._.committed = 0; 194 combo._.items = {}; 195 combo._.state = CKEDITOR.TRISTATE_OFF; 196 } 197 styles = {}; 198 stylesList = []; 199 loadStylesSet(); 200 } 201 }); 202 203 editor.on( 'instanceReady', function() { loadStylesSet(); } ); 204 } 205 }); 206 207 function sortStyles( styleA, styleB ) 208 { 209 var typeA = styleA.type, 210 typeB = styleB.type; 211 212 return typeA == typeB ? 0 : 213 typeA == CKEDITOR.STYLE_OBJECT ? -1 : 214 typeB == CKEDITOR.STYLE_OBJECT ? 1 : 215 typeB == CKEDITOR.STYLE_BLOCK ? 1 : 216 -1; 217 } 218 })(); 219