Ticket #5647: 5647.patch
File 5647.patch, 15.5 KB (added by , 15 years ago) |
---|
-
_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 = 'cke_' + CKEDITOR.tools.getNextNumber(), 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 buttonKeystroke = function( item, keystroke ) 61 98 { 62 var next, nextToolGroup, groupItemsCount;99 var next, closewise; 63 100 var rtl = editor.lang.dir == 'rtl'; 64 101 65 102 switch ( keystroke ) 66 103 { 67 case rtl ? 37 : 39 : // RIGHT-ARROW68 104 case 9 : // TAB 69 do 70 { 71 // Look for the next item in the toolbar. 72 next = item.next; 105 case CKEDITOR.SHIFT + 9 : // SHIFT + TAB 73 106 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 ) 107 closewise = keystroke == 9; 108 109 // Move to next group if when button group existed. 110 if ( item.parent instanceof group ) 111 { 112 item = item.parent; 113 while( !next ) 114 { 115 next = item[ closewise ? 'next' : 'previous' ]; 116 if ( !next ) 117 { 118 if ( item.parent ) 119 item = item.parent; 120 else 121 next = item; 122 } 123 else if ( !next.focus ) 81 124 { 82 nextToolGroup = nextToolGroup.next;83 groupItemsCount = nextToolGroup && nextToolGroup.items.length;125 item = next; 126 next = null; 84 127 } 85 86 if ( nextToolGroup )87 next = nextToolGroup.items[ 0 ];88 128 } 89 129 90 item = next; 130 next.focus( !closewise ); 131 return false; 91 132 } 92 while ( item && !item.focus )93 133 94 // If available, just focus it, otherwise focus the 95 // first one. 96 if ( item ) 97 item.focus(); 98 else 99 editor.toolbox.focus(); 134 case rtl ? 37 : 39 : // RIGHT-ARROW 135 case rtl ? 39 : 37 : // LEFT-ARROW 100 136 101 return false; 137 if ( closewise == undefined ) 138 closewise = keystroke == ( rtl ? 37 : 39 ); 102 139 103 case rtl ? 39 : 37 : // LEFT-ARROW 104 case CKEDITOR.SHIFT + 9 : // SHIFT + TAB 105 do 140 while( !next ) 106 141 { 107 // Look for the previous item in the toolbar. 108 next = item.previous; 109 142 next = item[ closewise ? 'next' : 'previous' ]; 110 143 if ( !next ) 111 144 { 112 nextToolGroup = item.toolbar.previous; 113 groupItemsCount = nextToolGroup && nextToolGroup.items.length; 114 115 // Bypass the empty toolgroups. 116 while ( groupItemsCount === 0 ) 117 { 118 nextToolGroup = nextToolGroup.previous; 119 groupItemsCount = nextToolGroup && nextToolGroup.items.length; 120 } 121 122 if ( nextToolGroup ) 123 next = nextToolGroup.items[ groupItemsCount - 1 ]; 124 } 125 126 item = next; 127 } 128 while ( item && !item.focus ) 129 130 // If available, just focus it, otherwise focus the 131 // last one. 132 if ( item ) 133 item.focus(); 134 else 135 { 136 var lastToolbarItems = editor.toolbox.toolbars[ editor.toolbox.toolbars.length - 1 ].items; 137 lastToolbarItems[ lastToolbarItems.length - 1 ].focus(); 145 // Cyrcling inside the group when button group existed. 146 if ( item.parent instanceof group ) 147 next = item.parent; 148 else if ( item.parent ) 149 item = item.parent; 150 else 151 next = item; 152 } 153 else if ( !next.focus ) 154 { 155 item = next; 156 next = null; 157 } 138 158 } 139 159 160 next.focus( !closewise ); 140 161 return false; 141 162 142 163 case 27 : // ESC … … 168 189 // Sends the ARIA label. 169 190 output.push( '<span id="', labelId, '" class="cke_voice_label">', editor.lang.toolbar, '</span>' ); 170 191 171 var toolb ars = editor.toolbox.toolbars,172 toolbar =192 var toolboxObj = editor.toolbox, 193 toolbarDef = 173 194 ( editor.config.toolbar instanceof Array ) ? 174 195 editor.config.toolbar 175 196 : 176 197 editor.config[ 'toolbar_' + editor.config.toolbar ]; 177 198 178 for ( var r = 0 ; r < toolbar .length ; r++ )199 for ( var r = 0 ; r < toolbarDef.length ; r++ ) 179 200 { 180 var row = toolbar [ r ];201 var row = toolbarDef[ r ]; 181 202 182 203 // It's better to check if the row object is really 183 204 // available because it's a common mistake to leave … … 187 208 if ( !row ) 188 209 continue; 189 210 190 var toolbarId = 'cke_' + CKEDITOR.tools.getNextNumber(), 191 toolbarObj = { id : toolbarId, items : [] }; 211 var toolbarObj = new toolbar(); 192 212 193 213 if ( groupStarted ) 194 214 { … … 202 222 continue; 203 223 } 204 224 205 output.push( '<span id="', toolbar Id, '" class="cke_toolbar" role="presentation"><span class="cke_toolbar_start"></span>' );225 output.push( '<span id="', toolbar.id, '" class="cke_toolbar" role="presentation"><span class="cke_toolbar_start"></span>' ); 206 226 207 // Add the toolbar to the "editor.toolbox.toolbars" 208 // array. 209 var index = toolbars.push( toolbarObj ) - 1; 227 toolboxObj.add( toolbarObj ); 210 228 211 // Create the next/previous reference. 212 if ( index > 0 ) 229 for ( var i = 0 ; i < row.length ; i++ ) 213 230 { 214 toolbarObj.previous = toolbars[ index - 1 ]; 215 toolbarObj.previous.next = toolbarObj; 216 } 231 var item = row[ i ], 232 isGroup = ( typeof item == 'object' ), 233 buttons = isGroup ? item.buttons : [ item ]; 234 235 // Group start. 236 if ( isGroup ) 237 { 238 var groupObj = new group(); 239 output.push( '<span id="' + groupObj.id + '" class="cke_toolgroup" role="group" aria-labelledby="'+ groupObj.id + '_label">' + 240 '<span id="' + groupObj.id + '_label" class="cke_voice_label">' + ( editor.lang.toolbarGroup[ item.name ] || '' ) + ' </span>' ); 241 toolbarObj.add( groupObj ); 242 } 217 243 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];244 // Create all items defined for this toolbar. 245 for ( var j = 0 ; j < buttons.length ; j++ ) 246 { 247 var button, 248 itemName = buttons[ j ]; 223 249 224 if ( itemName == '-' ) 225 item = CKEDITOR.ui.separator; 226 else 227 item = editor.ui.create( itemName ); 250 // Ignore separater in group mode. 251 if ( itemName == '-' && !isGroup ) 252 button = CKEDITOR.ui.separator; 253 else 254 button = editor.ui.create( itemName ); 228 255 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 }256 if ( button ) 257 { 258 if ( button.canGroup ) 259 { 260 if ( !( groupStarted || isGroup ) ) 261 { 262 output.push( '<span class="cke_toolgroup" role="presentation">' ); 263 groupStarted = 1; 264 } 265 } 266 else if ( groupStarted ) 267 { 268 output.push( '</span>' ); 269 groupStarted = 0; 270 } 244 271 245 var itemObj = item.render( editor, output ); 246 index = toolbarObj.items.push( itemObj ) - 1; 272 var container = isGroup ? groupObj : toolbarObj; 273 var buttonObj = button.render( editor, output ); 274 container.add( buttonObj ); 247 275 248 if ( index > 0 ) 249 { 250 itemObj.previous = toolbarObj.items[ index - 1 ]; 251 itemObj.previous.next = itemObj; 276 buttonObj.onkey = buttonKeystroke; 252 277 } 278 } 253 279 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 }; 280 // Group close. 281 if ( isGroup ) 282 { 283 output.push( '</span>' ); 284 groupStarted = 0; 266 285 } 267 286 } 268 287 288 // Group must close on toolbar row end. 269 289 if ( groupStarted ) 270 290 { 271 291 output.push( '</span>' ); 272 292 groupStarted = 0; 273 293 } 274 275 294 output.push( '<span class="cke_toolbar_end"></span></span>' ); 276 295 } 277 296 … … 442 461 ]; 443 462 444 463 /** 464 * This is a toolbar definition with all features, grouping by functionality. 465 * @type Array 466 * @default (see example) 467 * @example 468 * // This is actually the default value. 469 * CKEDITOR.config.toolbar_Full_Group = 470 * [ 471 * [ 472 * { 473 * name: 'mode', 474 * buttons : [ 'Source' ] 475 * }, 476 * { 477 * name: 'page', 478 * buttons : [ 'Save','NewPage','Preview','Print' ] 479 * }, 480 * { 481 * name: 'template', 482 * buttons : [ 'Templates' ] 483 * }, 484 * { 485 * name: 'clipboard', 486 * buttons : [ 'Cut','Copy','Paste','PasteText','PasteFromWord' ] 487 * }, 488 * { 489 * name: 'spellcheck', 490 * buttons : [ 'SpellChecker', 'Scayt' ] 491 * }, 492 * { 493 * name: 'undo', 494 * buttons : [ 'Undo','Redo' ] 495 * }, 496 * { 497 * name: 'find', 498 * buttons : [ 'Find','Replace' ] 499 * }, 500 * { 501 * name: 'clear', 502 * buttons : [ 'SelectAll','RemoveFormat' ] 503 * }, 504 * { 505 * name: 'form', 506 * buttons : [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField' ] 507 * } 508 * ], 509 * '/', 510 * [ 511 * { 512 * name: 'basicstyle', 513 * buttons : [ 'Bold','Italic','Underline','Strike','Subscript','Superscript' ] 514 * }, 515 * { 516 * name: 'list', 517 * buttons : [ 'NumberedList','BulletedList' ] 518 * }, 519 * { 520 * name: 'indent', 521 * buttons : [ 'Outdent','Indent' ] 522 * }, 523 * { 524 * name: 'block', 525 * buttons : [ 'Blockquote','CreateDiv' ] 526 * }, 527 * { 528 * name: 'justify', 529 * buttons : [ 'JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock' ] 530 * }, 531 * { 532 * name: 'link', 533 * buttons : [ 'Link','Unlink','Anchor' ] 534 * }, 535 * { 536 * name: 'objects', 537 * buttons : [ 'Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak' ] 538 * } 539 * ], 540 * '/', 541 * [ 542 * 'Styles','Format','Font','FontSize', 543 * { 544 * name: 'color', 545 * buttons : [ 'TextColor','BGColor' ] 546 * }, 547 * { 548 * name: 'tool', 549 * buttons : [ 'Maximize', 'ShowBlocks' ] 550 * }, 551 * 'About' 552 * ], 553 * ]; 554 * 555 */ 556 CKEDITOR.config.toolbar_Full_Group = 557 [ 558 [ 559 { 560 name: 'mode', 561 buttons : [ 'Source' ] 562 }, 563 { 564 name: 'page', 565 buttons : [ 'Save','NewPage','Preview','Print' ] 566 }, 567 { 568 name: 'template', 569 buttons : [ 'Templates' ] 570 }, 571 { 572 name: 'clipboard', 573 buttons : [ 'Cut','Copy','Paste','PasteText','PasteFromWord' ] 574 }, 575 { 576 name: 'spellcheck', 577 buttons : [ 'SpellChecker', 'Scayt' ] 578 }, 579 { 580 name: 'undo', 581 buttons : [ 'Undo','Redo' ] 582 }, 583 { 584 name: 'find', 585 buttons : [ 'Find','Replace' ] 586 }, 587 { 588 name: 'clear', 589 buttons : [ 'SelectAll','RemoveFormat' ] 590 }, 591 { 592 name: 'form', 593 buttons : [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField' ] 594 } 595 ], 596 '/', 597 [ 598 { 599 name: 'basicstyle', 600 buttons : [ 'Bold','Italic','Underline','Strike','Subscript','Superscript' ] 601 }, 602 { 603 name: 'list', 604 buttons : [ 'NumberedList','BulletedList' ] 605 }, 606 { 607 name: 'indent', 608 buttons : [ 'Outdent','Indent' ] 609 }, 610 { 611 name: 'block', 612 buttons : [ 'Blockquote','CreateDiv' ] 613 }, 614 { 615 name: 'justify', 616 buttons : [ 'JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock' ] 617 }, 618 { 619 name: 'link', 620 buttons : [ 'Link','Unlink','Anchor' ] 621 }, 622 { 623 name: 'objects', 624 buttons : [ 'Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak' ] 625 } 626 ], 627 '/', 628 [ 629 'Styles','Format','Font','FontSize', 630 { 631 name: 'color', 632 buttons : [ 'TextColor','BGColor' ] 633 }, 634 { 635 name: 'tool', 636 buttons : [ 'Maximize', 'ShowBlocks' ] 637 }, 638 'About' 639 ], 640 ]; 641 642 /** 445 643 * The toolbox (alias toolbar) definition. It is a toolbar name or an array of 446 644 * toolbars (strips), each one being also an array, containing a list of UI items. 447 645 * @type Array|String -
_source/lang/en.js
741 741 clear : 'Clear' 742 742 }, 743 743 744 toolbarGroup : 745 { 746 mode : 'Editing Mode', 747 page : 'Page Tool', 748 template : 'Templates', 749 clipboard : 'Clipboard', 750 spellcheck : 'Spell Checking', 751 undo : 'Undo/Redo', 752 find : 'Find and Replace', 753 clear : 'Clear Format', 754 form : 'Form Fields', 755 basicstyle : 'Basic Styles', 756 list : 'List Operations', 757 indent : 'Indentation Operations', 758 block : 'Blocks', 759 justify : 'Justification Operations', 760 link : 'Links', 761 objects : 'Object Controls', 762 color : 'Font Colors', 763 tool : 'Tools' 764 }, 765 744 766 toolbarCollapse : 'Collapse Toolbar', 745 767 toolbarExpand : 'Expand Toolbar' 746 768 };