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