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