Ticket #3074: 3074.patch
File 3074.patch, 14.3 KB (added by , 15 years ago) |
---|
-
_source/plugins/dialogui/plugin.js
436 436 /** @ignore */ 437 437 var innerHTML = function() 438 438 { 439 return [ '<tbody><tr><td class="cke_dialog_ui_button_txt">', 440 CKEDITOR.tools.htmlEncode( elementDefinition.label ), 441 '</td></tr></tbody>' ].join( '' ); 439 var styles = [], 440 align = elementDefinition.align || ( dialog.getParentEditor().lang.dir == 'ltr' ? 'left' : 'right' ); 441 442 if ( elementDefinition.style ) 443 { 444 var defStyle = CKEDITOR.tools.trim( elementDefinition.style ); 445 styles.push( defStyle ); 446 if ( defStyle.charAt( defStyle.length - 1 ) != ';' ) 447 styles.push( ';' ); 448 } 449 450 // IE6 & 7 BUG: Need to set margin as well as align. 451 if ( CKEDITOR.env.ie && CKEDITOR.env.version < 8 ) 452 { 453 styles.push( [ 454 'margin:', 455 'auto', 456 align == 'right' ? '0px' : 'auto', 457 'auto', 458 align == 'left' ? '0px' : 'auto' ].join( ' ' ), ';' ); 459 } 460 461 return [ 462 '<table align="', align, '" ', styles.length > 0 ? 'style="' + styles.join( '' ) + '">' : '>', 463 '<tbody><tr><td class="cke_dialog_ui_button_txt">', 464 CKEDITOR.tools.htmlEncode( elementDefinition.label ), 465 '</td></tr></tbody></table>' 466 ].join( '' ); 442 467 }; 443 468 444 469 // Add OnClick event to this input. … … 449 474 dialog.on( 'load', function( eventInfo ) 450 475 { 451 476 var element = this.getElement(); 452 element.on( 'mousedown', function( evt ) 453 { 454 // If button is disabled, don't do anything. 455 if ( me._.disabled ) 456 return; 477 (function() 478 { 479 element.on( 'mousedown', function( evt ) 480 { 481 // If button is disabled, don't do anything. 482 if ( me._.disabled ) 483 return; 457 484 458 // Change styles to indicate the button is being clicked. 459 me.getElement().addClass( 'active' ); 485 // Store the currently active button. 486 CKEDITOR.ui.dialog.button._.activeButton = [ me, me.getElement() ]; 487 } ); 460 488 461 // Store the currently active button. 462 CKEDITOR.ui.dialog.button._.activeButton = [ me, me.getElement() ]; 463 }); 489 element.on( 'keydown', function( evt ) 490 { 491 // Click if Enter is pressed. 492 if ( evt.data.$.keyCode == 13 ) 493 { 494 me.fire( 'click', { dialog : me.getDialog() } ); 495 evt.data.preventDefault(); 496 } 497 } ); 498 })(); 464 499 465 500 // IE BUG: Padding attributes are ignored for <td> cells. 466 501 if ( CKEDITOR.env.ie ) 467 element.getChild( [0, 0, 0 ] ).$.innerHTML += '';502 element.getChild( [0, 0, 0, 0] ).$.innerHTML += ''; 468 503 469 504 if ( !eventInfo.data.buttonHandlerRegistered ) 470 505 { … … 477 512 if ( !activeButton ) 478 513 return; 479 514 480 // Change styles to remove active status.481 activeButton[1].removeClass( 'active' );482 483 515 // Fire the click event - but only if the 484 516 // active button is the same as target. 485 if ( activeButton[1].equals( target.getAscendant( ' table' ) ) )517 if ( activeButton[1].equals( target.getAscendant( 'a' ) ) ) 486 518 activeButton[0].fire( 'click', { dialog : activeButton[0].getDialog() } ); 487 519 488 520 // Clear active button flag. 489 521 CKEDITOR.ui.dialog.button._.activeButton = null; 490 } );522 } ); 491 523 492 524 eventInfo.data.buttonHandlerRegistered = true; 493 525 } 494 526 495 this.getElement(). unselectable();527 this.getElement().getFirst().unselectable(); 496 528 }, this ); 497 529 498 var styles = {},499 align = elementDefinition.align || ( dialog.getParentEditor().lang.dir == 'ltr' ? 'left' : 'right' );530 var outerDefinition = CKEDITOR.tools.extend( {}, elementDefinition ); 531 delete outerDefinition.style; 500 532 501 // IE6 & 7 BUG: Need to set margin as well as align. 502 if ( CKEDITOR.env.ie && CKEDITOR.env.version < 8 ) 503 { 504 styles.margin = [ 505 'auto', 506 align == 'right' ? '0px' : 'auto', 507 'auto', 508 align == 'left' ? '0px' : 'auto' ].join( ' ' ); 509 } 510 511 CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, htmlList, 'table', styles, 512 { align : align }, innerHTML ); 533 CKEDITOR.ui.dialog.uiElement.call( this, dialog, outerDefinition, htmlList, 'a', { display : 'block', outline : 'none' }, 534 { href : 'javascript:void(0);', title : elementDefinition.label, hidefocus : 'true' }, 535 innerHTML ); 513 536 }, 514 537 515 538 /** … … 779 802 { 780 803 if ( !this._.disabled ) 781 804 return this.fire( 'click', { dialog : this._.dialog } ); 805 this.getElement().$.blur(); 782 806 }, 783 807 784 808 /** … … 801 825 this.getElement().addClass( 'disabled' ); 802 826 }, 803 827 828 isVisible : function() 829 { 830 return !!this.getElement().$.firstChild.offsetHeight; 831 }, 832 833 isEnabled : function() 834 { 835 return !this._.disabled; 836 }, 837 804 838 /** 805 839 * Defines the onChange event and onClick for button element definitions. 806 840 * @field … … 823 857 */ 824 858 accessKeyUp : function() 825 859 { 826 this.getElement().removeClass( 'active' );827 860 this.click(); 828 861 }, 829 862 … … 834 867 */ 835 868 accessKeyDown : function() 836 869 { 837 this.getElement().addClass( 'active' ); 838 } 870 this.focus(); 871 }, 872 873 keyboardFocusable : true 839 874 }, true ); 840 875 841 876 CKEDITOR.ui.dialog.textInput.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.labeledElement, … … 896 931 { 897 932 value = value || ''; 898 933 return CKEDITOR.ui.dialog.uiElement.prototype.setValue.call( this, value ); 899 } 934 }, 935 936 keyboardFocusable : true 900 937 }, commonPrototype, true ); 901 938 902 939 CKEDITOR.ui.dialog.textarea.prototype = new CKEDITOR.ui.dialog.textInput(); … … 966 1003 while ( selectElement.length > 0 ) 967 1004 selectElement.remove( 0 ); 968 1005 return this; 969 } 1006 }, 1007 1008 keyboardFocusable : true 970 1009 }, commonPrototype, true ); 971 1010 972 1011 CKEDITOR.ui.dialog.checkbox.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement, … … 1040 1079 } 1041 1080 return null; 1042 1081 } 1043 } 1082 }, 1083 1084 keyboardFocusable : true 1044 1085 }, commonPrototype, true ); 1045 1086 1046 1087 CKEDITOR.ui.dialog.radio.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement, … … 1128 1169 } 1129 1170 return null; 1130 1171 } 1131 } 1172 }, 1173 1174 keyboardFocusable : true 1132 1175 }, commonPrototype, true ); 1133 1176 1134 1177 CKEDITOR.ui.dialog.file.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.labeledElement, … … 1193 1236 * @type Object 1194 1237 * @example 1195 1238 */ 1196 eventProcessors : commonEventProcessors 1239 eventProcessors : commonEventProcessors, 1240 1241 keyboardFocusable : true 1197 1242 }, true ); 1198 1243 1199 1244 CKEDITOR.ui.dialog.fileButton.prototype = new CKEDITOR.ui.dialog.button; -
_source/plugins/dialog/plugin.js
89 89 // Initialize the tab and page map. 90 90 tabs : {}, 91 91 pageCount : 0, 92 lastTab : null 92 lastTab : null, 93 94 // Initialize the tab order array for input widgets. 95 focusList : [], 96 currentFocusIndex : 0 93 97 }; 94 98 95 99 /** … … 251 255 this.hide(); 252 256 }, this ); 253 257 258 var tabBarMode = false; 259 var focusKeydownHandler = function( evt ) 260 { 261 // If I'm not the top dialog, ignore. 262 if ( me != CKEDITOR.dialog._.currentTop ) 263 return; 264 265 var $evt = evt.data.$; 266 if ( $evt.keyCode == 9 ) 267 { 268 // Handling Tab and Shift-Tab. 269 if ( tabBarMode ) 270 { 271 // Change tabs. 272 } 273 else 274 { 275 // Change the focus of inputs. 276 var focusList = me._.focusList, 277 shiftPressed = $evt.shiftKey, 278 offset = shiftPressed ? -1 : 1; 279 if ( focusList.length < 1 ) 280 return; 281 282 var currentIndex = ( me._.currentFocusIndex + offset + focusList.length ) % focusList.length; 283 while ( !focusList[ currentIndex ].isFocusable() ) 284 { 285 currentIndex = ( currentIndex + offset + focusList.length ) % focusList.length; 286 if ( currentIndex == me._.currentFocusIndex ) 287 break; 288 } 289 focusList[ ( me._.currentFocusIndex = currentIndex ) ].focus(); 290 } 291 292 evt.data.preventDefault(); 293 } 294 else if ( $evt.keyCode == 192 && $evt.altKey ) 295 { 296 // Alt-` puts focus into the current tab item in the tab bar. 297 tabBarMode = true; 298 } 299 else if ( $evt.keyCode == 37 || $evt.keyCode == 39 ) 300 { 301 // Arrow keys - used for changing tabs. 302 } 303 else if ( $evt.keyCode == 27 ) 304 { 305 // Esc - puts the focus back into the dialog contents. 306 tabBarMode = false; 307 } 308 }; 309 310 this.on( 'show', function() 311 { 312 CKEDITOR.document.on( 'keydown', focusKeydownHandler ); 313 } ); 314 this.on( 'hide', function() 315 { 316 CKEDITOR.document.removeListener( 'keydown', focusKeydownHandler ); 317 } ); 318 319 254 320 // IE6 BUG: Text fields and text areas are only half-rendered the first time the dialog appears in IE6 (#2661). 255 321 // This is still needed after [2708] and [2709] because text fields in hidden TR tags are still broken. 256 322 if ( CKEDITOR.env.ie6Compat ) … … 577 643 addPage : function( contents ) 578 644 { 579 645 var pageHtml = [], 580 titleHtml = contents. title ? 'title="' + CKEDITOR.tools.htmlEncode( contents.title ) + '"' : '',646 titleHtml = contents.label ? ' title="' + CKEDITOR.tools.htmlEncode( contents.label ) + '"' : '', 581 647 elements = contents.elements, 582 648 vbox = CKEDITOR.dialog._.uiElementBuilders.vbox.build( this, 583 649 { … … 590 656 // Create the HTML for the tab and the content block. 591 657 var page = CKEDITOR.dom.element.createFromHtml( pageHtml.join( '' ) ); 592 658 var tab = CKEDITOR.dom.element.createFromHtml( [ 593 '<table><tbody><tr><td class="cke_dialog_tab" ', titleHtml, '>', 659 '<table><tbody><tr><td class="cke_dialog_tab">', 660 '<a href="javascript: void(0)"', titleHtml, ' style="display: block; outline: none;" hidefocus="true">', 594 661 '<table border="0" cellspacing="0" cellpadding="0"><tbody><tr>', 595 662 '<td class="cke_dialog_tab_left"></td>', 596 663 '<td class="cke_dialog_tab_center">', 597 664 CKEDITOR.tools.htmlEncode( contents.label.replace( / /g, '\xa0' ) ), 598 665 '</td>', 599 666 '<td class="cke_dialog_tab_right"></td>', 600 '</tr></tbody></table></ td></tr></tbody></table>'667 '</tr></tbody></table></a></td></tr></tbody></table>' 601 668 ].join( '' ) ); 602 669 tab = tab.getChild( [0,0,0] ); 603 670 … … 1671 1738 */ 1672 1739 uiElement : function( dialog, elementDefinition, htmlList, nodeNameArg, stylesArg, attributesArg, contentsArg ) 1673 1740 { 1674 if ( arguments.length < 4 )1741 if ( arguments.length < 4 ) 1675 1742 return; 1676 1743 1677 1744 var nodeName = ( nodeNameArg.call ? nodeNameArg( elementDefinition ) : nodeNameArg ) || 'div', … … 1744 1811 if ( this.accessKeyUp && this.accessKeyDown && elementDefinition.accessKey ) 1745 1812 registerAccessKey( this, dialog, 'CTRL+' + elementDefinition.accessKey ); 1746 1813 1814 var me = this; 1815 dialog.on( 'load', function() 1816 { 1817 if ( me.getInputElement() ) 1818 { 1819 me.getInputElement().on( 'focus', function() 1820 { 1821 me.fire( 'focus' ); 1822 }, me ); 1823 } 1824 } ); 1825 1826 // Register the object as a tab focus if it can be included. 1827 if ( this.keyboardFocusable ) 1828 { 1829 this.focusIndex = dialog._.focusList.push( this ) - 1; 1830 this.on( 'focus', function() 1831 { 1832 dialog._.currentFocusIndex = me.focusIndex; 1833 } ); 1834 } 1835 1747 1836 // Completes this object with everything we have in the 1748 1837 // definition. 1749 1838 CKEDITOR.tools.extend( this, elementDefinition ); … … 1993 2082 while ( ( cursor = cursor.getParent() ) && cursor.$.className.search( 'cke_dialog_page_contents' ) == -1 ) 1994 2083 { /*jsl:pass*/ } 1995 2084 2085 // Some widgets don't have parent tabs (e.g. OK and Cancel buttons). 2086 if ( !cursor ) 2087 return this; 2088 1996 2089 tabId = cursor.getAttribute( 'name' ); 1997 2090 1998 2091 this._.dialog.selectPage( tabId ); … … 2147 2240 var element = this.getInputElement(); 2148 2241 element.removeAttribute( 'disabled' ); 2149 2242 element.removeClass( 'cke_disabled' ); 2243 }, 2244 2245 /** 2246 * Determines whether an UI element is enabled or not. 2247 * @returns {Boolean} Whether the UI element is enabled. 2248 * @example 2249 */ 2250 isEnabled : function() 2251 { 2252 return !this.getInputElement().getAttribute( 'disabled' ); 2253 }, 2254 2255 /** 2256 * Determines whether an UI element is visible or not. 2257 * @returns {Boolean} Whether the UI element is visible. 2258 * @example 2259 */ 2260 isVisible : function() 2261 { 2262 return !!this.getInputElement().$.offsetHeight; 2263 }, 2264 2265 /** 2266 * Determines whether an UI element is focus-able or not. 2267 * Focus-able is defined as being both visible and enabled. 2268 * @returns {Boolean} Whether the UI element can be focused. 2269 * @example 2270 */ 2271 isFocusable : function() 2272 { 2273 if ( !this.isEnabled() || !this.isVisible() ) 2274 return false; 2275 return true; 2150 2276 } 2151 2277 }; 2152 2278 -
_source/skins/default/dialog.css
375 375 vertical-align: top; 376 376 } 377 377 378 .cke_skin_default .cke_dialog_ui_button 378 .cke_skin_default .cke_dialog_ui_button table 379 379 { 380 380 border: #737357 1px solid; 381 381 } 382 382 383 .cke_skin_default .cke_dialog_ui_button.disabled 383 .cke_skin_default .cke_dialog_ui_button.disabled table 384 384 { 385 385 border: #898980 1px solid; 386 386 } … … 399 399 background-color: #c5c5b3; 400 400 } 401 401 402 .cke_skin_default .cke_dialog_ui_button.active .cke_dialog_ui_button_txt 402 .cke_skin_default a:focus.cke_dialog_ui_button .cke_dialog_ui_button_txt, 403 .cke_skin_default a:active.cke_dialog_ui_button .cke_dialog_ui_button_txt 403 404 { 404 405 background-color: #e3e3c7; 405 406 }