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