Ticket #5647: 5647_3.patch
File 5647_3.patch, 17.6 KB (added by , 10 years ago) |
---|
-
_source/lang/en.js
766 766 clear : 'Clear' 767 767 }, 768 768 769 toolbarGroup : 770 { 771 mode : 'Editing Mode', 772 page : 'Page Tool', 773 template : 'Templates', 774 clipboard : 'Clipboard', 775 spellcheck : 'Spell Checking', 776 undo : 'Undo/Redo', 777 find : 'Find and Replace', 778 clear : 'Clear Format', 779 form : 'Form Fields', 780 basicstyle : 'Basic Styles', 781 list : 'List Operations', 782 indent : 'Indentation Operations', 783 block : 'Blocks', 784 justify : 'Justification Operations', 785 link : 'Links', 786 objects : 'Object Controls', 787 color : 'Font Colors', 788 tool : 'Tools' 789 }, 790 769 791 toolbarCollapse : 'Collapse Toolbar', 770 792 toolbarExpand : 'Expand Toolbar', 771 793 -
_source/plugins/toolbar/plugin.js
10 10 11 11 (function() 12 12 { 13 var toolbox = function() 13 // Trait for toolbar containing unit. 14 function container() 14 15 { 15 this.toolbars = []; 16 this.focusCommandExecuted = false; 17 }; 16 return CKEDITOR.tools.createClass( { 17 $ : function() 18 { 19 this.id = CKEDITOR.tools.getNextId(), 20 this.items = []; 21 }, 22 proto : 23 { 24 /** 25 * Focus the first/last item of the container. 26 * @param {Boolean} focusEnd 27 */ 28 focus : function( focusEnd ) 29 { 30 var current = this, 31 target; 18 32 19 toolbox.prototype.focus = function() 20 { 21 for ( var t = 0, toolbar ; toolbar = this.toolbars[ t++ ] ; ) 22 { 23 for ( var i = 0, item ; item = toolbar.items[ i++ ] ; ) 24 { 25 if ( item.focus ) 26 { 27 item.focus(); 28 return; 29 } 30 } 31 } 32 }; 33 while ( 1 ) 34 { 35 target = current.items[ focusEnd? current.items.length -1 : 0 ]; 36 if ( target && target.focus ) 37 break; 38 // No focusable candidate found, move focus to parent's siblings. 39 else if ( current.parent ) 40 current = current.parent; 41 else 42 { 43 target = current; 44 break; 45 } 46 } 47 48 target.focus( focusEnd ); 49 }, 50 51 add : function( item ) 52 { 53 var index = this.items.push( item ) - 1; 54 55 // Create the next/previous/parent reference. 56 if ( index > 0 ) 57 { 58 item.previous = this.items[ index - 1 ]; 59 item.previous.next = item; 60 } 61 item.parent = this; 62 } 63 } 64 } ); 65 } 33 66 67 var toolbox = container(), 68 toolbar = container(), 69 group = container(); 70 34 71 var commands = 35 72 { 36 73 toolbarFocus : … … 57 94 { 58 95 init : function( editor ) 59 96 { 60 var itemKeystroke = function( item, keystroke ) 97 var groupCycling = editor.config.toolbarGroupCycling !== false; 98 99 // Cycling the toolbar without considering groups. 100 function toolbarNavigate( item, closewise ) 61 101 { 62 var next, nextToolGroup, groupItemsCount; 102 var next; 103 while( !next ) 104 { 105 next = item.parent ? item[ closewise ? 'next' : 'previous' ] : item; 106 if ( !next ) 107 item = item.parent; 108 else if ( !next.focus ) 109 { 110 item = next; 111 next = null; 112 } 113 } 114 next.focus( !closewise ); 115 return false; 116 } 117 118 var buttonKeystroke = function( item, keystroke ) 119 { 120 var next, closewise; 63 121 var rtl = editor.lang.dir == 'rtl'; 64 122 65 123 switch ( keystroke ) 66 124 { 67 case rtl ? 37 : 39 : // RIGHT-ARROW68 125 case 9 : // TAB 69 do 70 { 71 // Look for the next item in the toolbar. 72 next = item.next; 126 case CKEDITOR.SHIFT + 9 : // SHIFT + TAB 73 127 74 if ( !next ) 75 { 76 nextToolGroup = item.toolbar.next; 77 groupItemsCount = nextToolGroup && nextToolGroup.items.length; 78 79 // Bypass the empty toolgroups. 80 while ( groupItemsCount === 0 ) 128 closewise = keystroke == 9; 129 130 // Move to next group if when button group existed. 131 if ( groupCycling && item.parent instanceof group ) 132 { 133 item = item.parent; 134 while( !next ) 135 { 136 next = item[ closewise ? 'next' : 'previous' ]; 137 if ( !next ) 138 { 139 if ( item.parent ) 140 item = item.parent; 141 else 142 next = item; 143 } 144 else if ( !next.focus ) 81 145 { 82 nextToolGroup = nextToolGroup.next;83 groupItemsCount = nextToolGroup && nextToolGroup.items.length;146 item = next; 147 next = null; 84 148 } 85 86 if ( nextToolGroup )87 next = nextToolGroup.items[ 0 ];88 149 } 89 150 90 item = next; 151 next.focus( !closewise ); 152 return false; 91 153 } 92 while ( item && !item.focus )93 94 // If available, just focus it, otherwise focus the95 // first one.96 if ( item )97 item.focus();98 154 else 99 editor.toolbox.focus();155 return toolbarNavigate( item, closewise ) 100 156 101 return false;102 157 158 case rtl ? 37 : 39 : // RIGHT-ARROW 103 159 case rtl ? 39 : 37 : // LEFT-ARROW 104 case CKEDITOR.SHIFT + 9 : // SHIFT + TAB105 do106 {107 // Look for the previous item in the toolbar.108 next = item.previous;109 160 110 if ( !next ) 111 { 112 nextToolGroup = item.toolbar.previous; 113 groupItemsCount = nextToolGroup && nextToolGroup.items.length; 114 115 // Bypass the empty toolgroups. 116 while ( groupItemsCount === 0 ) 161 if ( closewise == undefined ) 162 closewise = keystroke == ( rtl ? 37 : 39 ); 163 164 if ( groupCycling ) 165 { 166 while( !next ) 167 { 168 next = item[ closewise ? 'next' : 'previous' ]; 169 if ( !next ) 170 { 171 // Cyrcling inside the group when button group existed. 172 if ( item.parent instanceof group ) 173 next = item.parent; 174 else if ( item.parent ) 175 item = item.parent; 176 else 177 next = item; 178 } 179 else if ( !next.focus ) 117 180 { 118 nextToolGroup = nextToolGroup.previous;119 groupItemsCount = nextToolGroup && nextToolGroup.items.length;181 item = next; 182 next = null; 120 183 } 121 122 if ( nextToolGroup )123 next = nextToolGroup.items[ groupItemsCount - 1 ];124 184 } 125 185 126 item = next; 186 next.focus( !closewise ); 187 return false; 127 188 } 128 while ( item && !item.focus )129 130 // If available, just focus it, otherwise focus the131 // last one.132 if ( item )133 item.focus();134 189 else 135 { 136 var lastToolbarItems = editor.toolbox.toolbars[ editor.toolbox.toolbars.length - 1 ].items; 137 lastToolbarItems[ lastToolbarItems.length - 1 ].focus(); 138 } 190 return toolbarNavigate( item, closewise ); 139 191 140 return false;141 192 142 193 case 27 : // ESC 143 194 editor.focus(); … … 168 219 // Sends the ARIA label. 169 220 output.push( '<span id="', labelId, '" class="cke_voice_label">', editor.lang.toolbar, '</span>' ); 170 221 171 var toolb ars = editor.toolbox.toolbars,172 toolbar =222 var toolboxObj = editor.toolbox, 223 toolbarDef = 173 224 ( editor.config.toolbar instanceof Array ) ? 174 225 editor.config.toolbar 175 226 : 176 227 editor.config[ 'toolbar_' + editor.config.toolbar ]; 177 228 178 for ( var r = 0 ; r < toolbar .length ; r++ )229 for ( var r = 0 ; r < toolbarDef.length ; r++ ) 179 230 { 180 var row = toolbar [ r ];231 var row = toolbarDef[ r ]; 181 232 182 233 // It's better to check if the row object is really 183 234 // available because it's a common mistake to leave … … 187 238 if ( !row ) 188 239 continue; 189 240 190 var toolbarId = CKEDITOR.tools.getNextId(), 191 toolbarObj = { id : toolbarId, items : [] }; 241 var toolbarObj = new toolbar(); 192 242 193 243 if ( groupStarted ) 194 244 { … … 202 252 continue; 203 253 } 204 254 205 output.push( '<span id="', toolbar Id, '" class="cke_toolbar" role="presentation"><span class="cke_toolbar_start"></span>' );255 output.push( '<span id="', toolbar.id, '" class="cke_toolbar" role="presentation"><span class="cke_toolbar_start"></span>' ); 206 256 207 // Add the toolbar to the "editor.toolbox.toolbars" 208 // array. 209 var index = toolbars.push( toolbarObj ) - 1; 257 toolboxObj.add( toolbarObj ); 210 258 211 // Create the next/previous reference. 212 if ( index > 0 ) 259 for ( var i = 0 ; i < row.length ; i++ ) 213 260 { 214 toolbarObj.previous = toolbars[ index - 1 ]; 215 toolbarObj.previous.next = toolbarObj; 216 } 261 var item = row[ i ], 262 isGroup = ( typeof item == 'object' ), 263 buttons = isGroup ? item.buttons : [ item ]; 264 265 // Group start. 266 if ( isGroup ) 267 { 268 var groupObj = new group(); 269 output.push( '<span id="' + groupObj.id + '" class="cke_toolgroup" role="group" aria-labelledby="'+ groupObj.id + '_label">' + 270 '<span id="' + groupObj.id + '_label" class="cke_voice_label">' + ( editor.lang.toolbarGroup[ item.name ] || '' ) + ' </span>' ); 271 toolbarObj.add( groupObj ); 272 } 217 273 218 // Create all items defined for this toolbar.219 for ( var i = 0 ; i < row.length ; i++ )220 {221 var item,222 itemName = row[ i];274 // Create all items defined for this toolbar. 275 for ( var j = 0 ; j < buttons.length ; j++ ) 276 { 277 var button, 278 itemName = buttons[ j ]; 223 279 224 if ( itemName == '-' ) 225 item = CKEDITOR.ui.separator; 226 else 227 item = editor.ui.create( itemName ); 280 // Ignore separater in group mode. 281 if ( itemName == '-' && !isGroup ) 282 button = CKEDITOR.ui.separator; 283 else 284 button = editor.ui.create( itemName ); 228 285 229 if ( item)230 {231 if ( item.canGroup )232 {233 if ( !groupStarted)234 {235 output.push( '<span class="cke_toolgroup" role="presentation">' );236 groupStarted = 1;237 }238 }239 else if ( groupStarted )240 {241 output.push( '</span>' );242 groupStarted = 0;243 }286 if ( button ) 287 { 288 if ( button.canGroup ) 289 { 290 if ( !( groupStarted || isGroup ) ) 291 { 292 output.push( '<span class="cke_toolgroup" role="presentation">' ); 293 groupStarted = 1; 294 } 295 } 296 else if ( groupStarted ) 297 { 298 output.push( '</span>' ); 299 groupStarted = 0; 300 } 244 301 245 var itemObj = item.render( editor, output ); 246 index = toolbarObj.items.push( itemObj ) - 1; 302 var container = isGroup ? groupObj : toolbarObj; 303 var buttonObj = button.render( editor, output ); 304 container.add( buttonObj ); 247 305 248 if ( index > 0 ) 249 { 250 itemObj.previous = toolbarObj.items[ index - 1 ]; 251 itemObj.previous.next = itemObj; 306 buttonObj.onkey = buttonKeystroke; 252 307 } 308 } 253 309 254 itemObj.toolbar = toolbarObj; 255 itemObj.onkey = itemKeystroke; 256 257 /* 258 * Fix for #3052: 259 * Prevent JAWS from focusing the toolbar after document load. 260 */ 261 itemObj.onfocus = function() 262 { 263 if ( !editor.toolbox.focusCommandExecuted ) 264 editor.focus(); 265 }; 310 // Group close. 311 if ( isGroup ) 312 { 313 output.push( '</span>' ); 314 groupStarted = 0; 266 315 } 267 316 } 268 317 318 // Group must close on toolbar row end. 269 319 if ( groupStarted ) 270 320 { 271 321 output.push( '</span>' ); 272 322 groupStarted = 0; 273 323 } 274 275 324 output.push( '<span class="cke_toolbar_end"></span></span>' ); 276 325 } 277 326 … … 395 444 */ 396 445 CKEDITOR.config.toolbar_Basic = 397 446 [ 398 ['Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link', 'Unlink','-','About'] 447 [ 448 { 449 name: 'basicstyle', 450 buttons : [ 'Bold','Italic' ] 451 }, 452 { 453 name: 'list', 454 buttons : [ 'NumberedList','BulletedList' ] 455 }, 456 { 457 name: 'link', 458 buttons : [ 'Link','Unlink' ] 459 }, 460 'About' 461 ] 399 462 ]; 400 463 401 464 /** 402 * This is the default toolbar definition used by the editor. It contains all403 * editor features.465 * A toolbar definition with all default items and groups. 466 * that used as the default value of {@link CKEDITOR.config.toolbar}. 404 467 * @type Array 405 * @default (see example)406 468 * @example 407 * // This is actually the default value. 408 * config.toolbar_Full = 409 * [ 410 * ['Source','-','Save','NewPage','Preview','-','Templates'], 411 * ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'], 412 * ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'], 413 * ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'], 414 * '/', 415 * ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'], 416 * ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'], 417 * ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], 418 * ['BidiLtr', 'BidiRtl' ], 419 * ['Link','Unlink','Anchor'], 420 * ['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak','Iframe'], 421 * '/', 422 * ['Styles','Format','Font','FontSize'], 423 * ['TextColor','BGColor'], 424 * ['Maximize', 'ShowBlocks','-','About'] 425 * ]; 469 * CKEDITOR.config.toolbar = 'Full'; 426 470 */ 427 471 CKEDITOR.config.toolbar_Full = 428 472 [ 429 ['Source','-','Save','NewPage','Preview','-','Templates'], 430 ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'], 431 ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'], 432 ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'], 473 [ 474 { 475 name: 'mode', 476 buttons : [ 'Source' ] 477 }, 478 { 479 name: 'page', 480 buttons : [ 'Save','NewPage','Preview','Print' ] 481 }, 482 { 483 name: 'template', 484 buttons : [ 'Templates' ] 485 }, 486 { 487 name: 'clipboard', 488 buttons : [ 'Cut','Copy','Paste','PasteText','PasteFromWord' ] 489 }, 490 { 491 name: 'spellcheck', 492 buttons : [ 'SpellChecker', 'Scayt' ] 493 }, 494 { 495 name: 'undo', 496 buttons : [ 'Undo','Redo' ] 497 }, 498 { 499 name: 'find', 500 buttons : [ 'Find','Replace' ] 501 }, 502 { 503 name: 'clear', 504 buttons : [ 'SelectAll','RemoveFormat' ] 505 }, 506 { 507 name: 'form', 508 buttons : [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField' ] 509 } 510 ], 433 511 '/', 434 ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'], 435 ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'], 436 ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], 437 ['BidiLtr', 'BidiRtl' ], 438 ['Link','Unlink','Anchor'], 439 ['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak','Iframe'], 512 [ 513 { 514 name: 'basicstyle', 515 buttons : [ 'Bold','Italic','Underline','Strike','Subscript','Superscript' ] 516 }, 517 { 518 name: 'list', 519 buttons : [ 'NumberedList','BulletedList' ] 520 }, 521 { 522 name: 'indent', 523 buttons : [ 'Outdent','Indent' ] 524 }, 525 { 526 name: 'block', 527 buttons : [ 'Blockquote','CreateDiv' ] 528 }, 529 { 530 name: 'justify', 531 buttons : [ 'JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock' ] 532 }, 533 { 534 name: 'link', 535 buttons : [ 'Link','Unlink','Anchor' ] 536 }, 537 { 538 name: 'objects', 539 buttons : [ 'Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak' ] 540 } 541 ], 440 542 '/', 441 ['Styles','Format','Font','FontSize'], 442 ['TextColor','BGColor'], 443 ['Maximize', 'ShowBlocks','-','About'] 543 [ 544 'Styles','Format','Font','FontSize', 545 { 546 name: 'color', 547 buttons : [ 'TextColor','BGColor' ] 548 }, 549 { 550 name: 'tool', 551 buttons : [ 'Maximize', 'ShowBlocks' ] 552 }, 553 'About' 554 ] 444 555 ]; 445 556 446 557 /** … … 451 562 * @example 452 563 * // Defines a toolbar with only one strip containing the "Source" button, a 453 564 * // separator and the "Bold" and "Italic" buttons. 454 * config.toolbar =565 * config.toolbar = 455 566 * [ 456 * [ 'Source', '-', 'Bold', 'Italic' ] 457 * ]; 567 * [ 568 * // Single button as a group, without specifying group name. 569 * 'Source', '-', 570 * // Two buttons in a group, with "basic style" as group name. 571 * { 572 * name : 'basic_style', 573 * buttons: [ 'Bold', 'Italic' ] 574 * } 575 * ] 576 * ]; 458 577 * @example 459 578 * // Load toolbar_Name where Name = Basic. 460 579 * config.toolbar = 'Basic'; … … 479 598 * @example 480 599 * config.toolbarStartupExpanded = false; 481 600 */ 601 602 /** 603 * Whether enable the following keyboard navigation for toolbar group: 604 * <dl> 605 * <dt>Arrow Left/Arrow Right:</dt><dd>Cycle inside toolbar group</dd> 606 * <dt>Tab/Shift-Tab:</dt><dd>Navigate between toolbar groups, wrap at start or end.</dd> 607 * </dl> 608 * If set to "false" then both "Arrow" and "Tab" keystrokes cycling the entire toolbar without considering the group. 609 * @name CKEDITOR.config.toolbarGroupCycling 610 * @type Boolean 611 * @default true 612 * @example 613 * config.toolbarGroupCycling = false; 614 */ 615