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 CKEDITOR.plugins.add( 'listblock',
  7 {
  8 	requires : [ 'panel' ],
  9
 10 	onLoad : function()
 11 	{
 12 		CKEDITOR.ui.panel.prototype.addListBlock = function( name, multiSelect )
 13 		{
 14 			return this.addBlock( name, new CKEDITOR.ui.listBlock( this.getHolderElement(), multiSelect ) );
 15 		};
 16
 17 		CKEDITOR.ui.listBlock = CKEDITOR.tools.createClass(
 18 			{
 19 				base : CKEDITOR.ui.panel.block,
 20
 21 				$ : function( blockHolder, multiSelect )
 22 				{
 23 					// Call the base contructor.
 24 					this.base( blockHolder );
 25
 26 					this.multiSelect = !!multiSelect;
 27
 28 					var keys = this.keys;
 29 					keys[ 40 ]	= 'next';					// ARROW-DOWN
 30 					keys[ 9 ]	= 'next';					// TAB
 31 					keys[ 38 ]	= 'prev';					// ARROW-UP
 32 					keys[ CKEDITOR.SHIFT + 9 ]	= 'prev';	// SHIFT + TAB
 33 					keys[ 32 ]	= 'click';					// SPACE
 34
 35 					this._.pendingHtml = [];
 36 					this._.items = {};
 37 					this._.groups = {};
 38 				},
 39
 40 				_ :
 41 				{
 42 					close : function()
 43 					{
 44 						if ( this._.started )
 45 						{
 46 							this._.pendingHtml.push( '</ul>' );
 47 							delete this._.started;
 48 						}
 49 					},
 50
 51 					getClick : function()
 52 					{
 53 						if ( !this._.click )
 54 						{
 55 							this._.click = CKEDITOR.tools.addFunction( function( value )
 56 								{
 57 									var marked = true;
 58
 59 									if ( this.multiSelect )
 60 										marked = this.toggle( value );
 61 									else
 62 										this.mark( value );
 63
 64 									if ( this.onClick )
 65 										this.onClick( value, marked );
 66 								},
 67 								this );
 68 						}
 69 						return this._.click;
 70 					}
 71 				},
 72
 73 				proto :
 74 				{
 75 					add : function( value, html, title )
 76 					{
 77 						var pendingHtml = this._.pendingHtml,
 78 							id = 'cke_' + CKEDITOR.tools.getNextNumber();
 79
 80 						if ( !this._.started )
 81 						{
 82 							pendingHtml.push( '<ul class=cke_panel_list>' );
 83 							this._.started = 1;
 84 						}
 85
 86 						this._.items[ value ] = id;
 87
 88 						pendingHtml.push(
 89 							'<li id=', id, ' class=cke_panel_listItem>' +
 90 								'<a _cke_focus=1 hidefocus=true' +
 91 									' title="', title || value, '"' +
 92 									' href="javascript:void(\'', value, '\')"' +
 93 									' onclick="CKEDITOR.tools.callFunction(', this._.getClick(), ',\'', value, '\'); return false;">',
 94 									html || value,
 95 								'</a>' +
 96 							'</li>' );
 97 					},
 98
 99 					startGroup : function( title )
100 					{
101 						this._.close();
102
103 						var id = 'cke_' + CKEDITOR.tools.getNextNumber();
104
105 						this._.groups[ title ] = id;
106
107 						this._.pendingHtml.push( '<h1 id=', id, ' class=cke_panel_grouptitle>', title, '</h1>' );
108 					},
109
110 					commit : function()
111 					{
112 						this._.close();
113 						this.element.appendHtml( this._.pendingHtml.join( '' ) );
114 						this._.pendingHtml = [];
115 					},
116
117 					toggle : function( value )
118 					{
119 						var isMarked = this.isMarked( value );
120
121 						if ( isMarked )
122 							this.unmark( value );
123 						else
124 							this.mark( value );
125
126 						return !isMarked;
127 					},
128
129 					hideGroup : function( groupTitle )
130 					{
131 						var group = this.element.getDocument().getById( this._.groups[ groupTitle ] ),
132 							list = group && group.getNext();
133
134 						if ( group )
135 						{
136 							group.setStyle( 'display', 'none' );
137
138 							if ( list && list.getName() == 'ul' )
139 								list.setStyle( 'display', 'none' );
140 						}
141 					},
142
143 					hideItem : function( value )
144 					{
145 						this.element.getDocument().getById( this._.items[ value ] ).setStyle( 'display', 'none' );
146 					},
147
148 					showAll : function()
149 					{
150 						var items = this._.items,
151 							groups = this._.groups,
152 							doc = this.element.getDocument();
153
154 						for ( var value in items )
155 						{
156 							doc.getById( items[ value ] ).setStyle( 'display', '' );
157 						}
158
159 						for ( var title in groups )
160 						{
161 							var group = doc.getById( groups[ title ] ),
162 								list = group.getNext();
163
164 							group.setStyle( 'display', '' );
165
166 							if ( list && list.getName() == 'ul' )
167 								list.setStyle( 'display', '' );
168 						}
169 					},
170
171 					mark : function( value )
172 					{
173 						if ( !this.multiSelect )
174 							this.unmarkAll();
175
176 						this.element.getDocument().getById( this._.items[ value ] ).addClass( 'cke_selected' );
177 					},
178
179 					unmark : function( value )
180 					{
181 						this.element.getDocument().getById( this._.items[ value ] ).removeClass( 'cke_selected' );
182 					},
183
184 					unmarkAll : function()
185 					{
186 						var items = this._.items,
187 							doc = this.element.getDocument();
188
189 						for ( var value in items )
190 						{
191 							doc.getById( items[ value ] ).removeClass( 'cke_selected' );
192 						}
193 					},
194
195 					isMarked : function( value )
196 					{
197 						return this.element.getDocument().getById( this._.items[ value ] ).hasClass( 'cke_selected' );
198 					},
199
200 					focus : function( value )
201 					{
202 						this._.focusIndex = -1;
203
204 						if ( value )
205 						{
206 							var selected = this.element.getDocument().getById( this._.items[ value ] ).getFirst();
207
208 							var links = this.element.getElementsByTag( 'a' ),
209 								link,
210 								i = -1;
211
212 							while( ( link = links.getItem( ++i ) ) )
213 							{
214 								if ( link.equals( selected ) )
215 								{
216 									this._.focusIndex = i;
217 									break;
218 								}
219 							}
220
221 							setTimeout( function()
222 								{
223 									selected.focus();
224 								},
225 								0 );
226 						}
227 					}
228 				}
229 			});
230 	}
231 });
232