086f1097551e6025e3131300e368a575e2156b04
[ckeditor.git] / _source / plugins / stylescombo / plugin.js
1 /*
2 Copyright (c) 2003-2011, 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 })();