1 /* 2 Copyright (c) 2003-2012, 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 html || value, 105 '</a>' + 106 '</li>' ); 107 }, 108 109 startGroup : function( title ) 110 { 111 this._.close(); 112 113 var id = CKEDITOR.tools.getNextId(); 114 115 this._.groups[ title ] = id; 116 117 this._.pendingHtml.push( '<h1 role="presentation" id=', id, ' class=cke_panel_grouptitle>', title, '</h1>' ); 118 }, 119 120 commit : function() 121 { 122 this._.close(); 123 this.element.appendHtml( this._.pendingHtml.join( '' ) ); 124 delete this._.size; 125 126 this._.pendingHtml = []; 127 }, 128 129 toggle : function( value ) 130 { 131 var isMarked = this.isMarked( value ); 132 133 if ( isMarked ) 134 this.unmark( value ); 135 else 136 this.mark( value ); 137 138 return !isMarked; 139 }, 140 141 hideGroup : function( groupTitle ) 142 { 143 var group = this.element.getDocument().getById( this._.groups[ groupTitle ] ), 144 list = group && group.getNext(); 145 146 if ( group ) 147 { 148 group.setStyle( 'display', 'none' ); 149 150 if ( list && list.getName() == 'ul' ) 151 list.setStyle( 'display', 'none' ); 152 } 153 }, 154 155 hideItem : function( value ) 156 { 157 this.element.getDocument().getById( this._.items[ value ] ).setStyle( 'display', 'none' ); 158 }, 159 160 showAll : function() 161 { 162 var items = this._.items, 163 groups = this._.groups, 164 doc = this.element.getDocument(); 165 166 for ( var value in items ) 167 { 168 doc.getById( items[ value ] ).setStyle( 'display', '' ); 169 } 170 171 for ( var title in groups ) 172 { 173 var group = doc.getById( groups[ title ] ), 174 list = group.getNext(); 175 176 group.setStyle( 'display', '' ); 177 178 if ( list && list.getName() == 'ul' ) 179 list.setStyle( 'display', '' ); 180 } 181 }, 182 183 mark : function( value ) 184 { 185 if ( !this.multiSelect ) 186 this.unmarkAll(); 187 188 var itemId = this._.items[ value ], 189 item = this.element.getDocument().getById( itemId ); 190 item.addClass( 'cke_selected' ); 191 192 this.element.getDocument().getById( itemId + '_option' ).setAttribute( 'aria-selected', true ); 193 this.onMark && this.onMark( item ); 194 }, 195 196 unmark : function( value ) 197 { 198 var doc = this.element.getDocument(), 199 itemId = this._.items[ value ], 200 item = doc.getById( itemId ); 201 202 item.removeClass( 'cke_selected' ); 203 doc.getById( itemId + '_option' ).removeAttribute( 'aria-selected' ); 204 205 this.onUnmark && this.onUnmark( item ); 206 }, 207 208 unmarkAll : function() 209 { 210 var items = this._.items, 211 doc = this.element.getDocument(); 212 213 for ( var value in items ) 214 { 215 var itemId = items[ value ]; 216 217 doc.getById( itemId ).removeClass( 'cke_selected' ); 218 doc.getById( itemId + '_option' ).removeAttribute( 'aria-selected' ); 219 } 220 221 this.onUnmark && this.onUnmark(); 222 }, 223 224 isMarked : function( value ) 225 { 226 return this.element.getDocument().getById( this._.items[ value ] ).hasClass( 'cke_selected' ); 227 }, 228 229 focus : function( value ) 230 { 231 this._.focusIndex = -1; 232 233 if ( value ) 234 { 235 var selected = this.element.getDocument().getById( this._.items[ value ] ).getFirst(); 236 237 var links = this.element.getElementsByTag( 'a' ), 238 link, 239 i = -1; 240 241 while ( ( link = links.getItem( ++i ) ) ) 242 { 243 if ( link.equals( selected ) ) 244 { 245 this._.focusIndex = i; 246 break; 247 } 248 } 249 250 setTimeout( function() 251 { 252 selected.focus(); 253 }, 254 0 ); 255 } 256 } 257 } 258 }); 259 } 260 }); 261