Ticket #23560: 23560.5.diff
File 23560.5.diff, 8.2 KB (added by , 10 years ago) |
---|
-
wp-includes/js/media-views.js
1375 1375 frame.setState( previous ); 1376 1376 else 1377 1377 frame.close(); 1378 1379 // Keep focus inside media modal 1380 // after cancelling a gallery 1381 $('.media-modal-close').focus(); 1378 1382 } 1379 1383 }, 1380 1384 separateCancel: new media.View({ … … 1485 1489 }) ); 1486 1490 1487 1491 this.controller.setState('gallery-edit'); 1492 1493 // Keep focus inside media modal 1494 // after jumping to gallery view 1495 $('.media-modal-close').focus(); 1488 1496 } 1489 1497 }); 1490 1498 }, … … 1637 1645 if ( ! this.views.attached || ! this.$el.is(':visible') ) 1638 1646 return this; 1639 1647 1640 this.$el.hide(); 1648 // Hide modal and remove restricted media modal tab focus once it's closed 1649 this.$el.hide().undelegate( 'keydown' ); 1650 1651 // Put focus back in useful location once modal is closed 1652 $('#wpbody-content').focus(); 1653 1641 1654 this.propagate('close'); 1642 1655 1643 1656 // If the `freeze` option is set, restore the container's scroll position. … … 1683 1696 this.escape(); 1684 1697 return; 1685 1698 } 1686 }1687 });1688 1699 1689 // wp.media.view.FocusManager 1690 // ---------------------------- 1691 media.view.FocusManager = media.View.extend({ 1692 events: { 1693 keydown: 'recordTab', 1694 focusin: 'updateIndex' 1695 }, 1696 1697 focus: function() { 1698 if ( _.isUndefined( this.index ) ) 1700 if ( $.ui.keyCode.TAB !== event.keyCode ) 1699 1701 return; 1700 1702 1701 // Update our collection of `$tabbables`. 1702 this.$tabbables = this.$(':tabbable'); 1703 // Keep tab focus within media modal while it's open 1704 this.tabbables = $( ':tabbable', this.$el ); 1705 this.tabbableFirst = this.tabbables.filter( ':first' ); 1706 this.tabbablesLast = this.tabbables.filter( ':last' ); 1703 1707 1704 // If tab is saved, focus it. 1705 this.$tabbables.eq( this.index ).focus(); 1706 }, 1707 1708 recordTab: function( event ) { 1709 // Look for the tab key. 1710 if ( 9 !== event.keyCode ) 1711 return; 1712 1713 // First try to update the index. 1714 if ( _.isUndefined( this.index ) ) 1715 this.updateIndex( event ); 1716 1717 // If we still don't have an index, bail. 1718 if ( _.isUndefined( this.index ) ) 1719 return; 1720 1721 var index = this.index + ( event.shiftKey ? -1 : 1 ); 1722 1723 if ( index >= 0 && index < this.$tabbables.length ) 1724 this.index = index; 1725 else 1726 delete this.index; 1727 }, 1728 1729 updateIndex: function( event ) { 1730 this.$tabbables = this.$(':tabbable'); 1731 1732 var index = this.$tabbables.index( event.target ); 1733 1734 if ( -1 === index ) 1735 delete this.index; 1736 else 1737 this.index = index; 1708 if ( event.target === this.tabbablesLast[0] && !event.shiftKey ) { 1709 this.tabbableFirst.focus(); 1710 return false; 1711 } else if ( event.target === this.tabbableFirst[0] && event.shiftKey ) { 1712 this.tabbablesLast.focus(); 1713 return false; 1714 } 1738 1715 } 1739 1716 }); 1740 1717 … … 2493 2470 className: 'attachment', 2494 2471 template: media.template('attachment'), 2495 2472 2473 attributes: { 2474 tabIndex: 0, 2475 role: 'checkbox' 2476 }, 2477 2496 2478 events: { 2497 2479 'click .attachment-preview': 'toggleSelectionHandler', 2498 2480 'change [data-setting]': 'updateSetting', … … 2501 2483 'change [data-setting] textarea': 'updateSetting', 2502 2484 'click .close': 'removeFromLibrary', 2503 2485 'click .check': 'removeFromSelection', 2504 'click a': 'preventDefault' 2486 'click a': 'preventDefault', 2487 'keydown': 'toggleSelectionHandler' 2505 2488 }, 2506 2489 2507 2490 buttons: {}, … … 2509 2492 initialize: function() { 2510 2493 var selection = this.options.selection; 2511 2494 2495 this.$el.attr('aria-label', this.model.attributes.title).attr('aria-checked', false); 2512 2496 this.model.on( 'change:sizes change:uploading', this.render, this ); 2513 2497 this.model.on( 'change:title', this._syncTitle, this ); 2514 2498 this.model.on( 'change:caption', this._syncCaption, this ); … … 2599 2583 toggleSelectionHandler: function( event ) { 2600 2584 var method; 2601 2585 2586 // Catch enter and space events 2587 if ( 'keydown' === event.type && $.ui.keyCode.ENTER !== event.keyCode && $.ui.keyCode.SPACE !== event.keyCode ) 2588 return; 2589 2602 2590 if ( event.shiftKey ) 2603 2591 method = 'between'; 2604 2592 else if ( event.ctrlKey || event.metaKey ) … … 2647 2635 return; 2648 2636 } 2649 2637 2638 // Fixes bug that loses focus when selecting a featured image 2639 if ( !method ) 2640 method = 'add'; 2641 2650 2642 if ( method !== 'add' ) 2651 2643 method = 'reset'; 2652 2644 … … 2682 2674 if ( ! selection || ( collection && collection !== selection ) ) 2683 2675 return; 2684 2676 2685 this.$el.addClass('selected') ;2677 this.$el.addClass('selected').attr('aria-checked', true); 2686 2678 }, 2687 2679 2688 2680 deselect: function( model, collection ) { … … 2694 2686 if ( ! selection || ( collection && collection !== selection ) ) 2695 2687 return; 2696 2688 2697 this.$el.removeClass('selected') ;2689 this.$el.removeClass('selected').attr('aria-checked', false); 2698 2690 }, 2699 2691 2700 2692 details: function( model, collection ) { … … 2876 2868 tagName: 'ul', 2877 2869 className: 'attachments', 2878 2870 2871 attributes: { 2872 tabIndex: -1 2873 }, 2874 2879 2875 cssTemplate: media.template('attachments-css'), 2880 2876 2881 2877 events: { … … 3488 3484 clear: function( event ) { 3489 3485 event.preventDefault(); 3490 3486 this.collection.reset(); 3487 3488 // Keep focus inside media modal 3489 // after clear link is selected 3490 $('.media-modal-close').focus(); 3491 3491 } 3492 3492 }); 3493 3493 … … 3731 3731 }, 3732 3732 3733 3733 initialize: function() { 3734 this.focusManager = new media.view.FocusManager({3735 el: this.el3736 });3737 3738 3734 media.view.Attachment.prototype.initialize.apply( this, arguments ); 3739 3735 }, 3740 3736 3741 3737 render: function() { 3742 3738 media.view.Attachment.prototype.render.apply( this, arguments ); 3743 this.focusManager.focus();3744 3739 return this; 3745 3740 }, 3746 3741 … … 3749 3744 3750 3745 if ( confirm( l10n.warnDelete ) ) 3751 3746 this.model.destroy(); 3747 3748 // Keep focus inside media modal 3749 // after image is deleted 3750 $('.media-modal-close').focus(); 3752 3751 }, 3753 3752 3754 3753 editAttachment: function() { … … 3777 3776 }, 3778 3777 3779 3778 initialize: function() { 3780 this.focusManager = new media.view.FocusManager({3781 el: this.el3782 });3783 3784 3779 this.model.on( 'change:compat', this.render, this ); 3785 3780 }, 3786 3781 … … 3800 3795 this.$el.html( compat.item ); 3801 3796 this.views.render(); 3802 3797 3803 this.focusManager.focus();3804 3798 return this; 3805 3799 }, 3806 3800 -
wp-includes/media-template.php
15 15 function wp_print_media_templates() { 16 16 global $is_IE; 17 17 $class = 'media-modal wp-core-ui'; 18 if ( $is_IE ) 19 $class .= ' isIE'; 18 20 if ( $is_IE && strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 7') !== false ) 19 21 $class .= ' ie7'; 20 22 ?> … … 142 144 <# } else if ( 'image' === data.type ) { #> 143 145 <div class="thumbnail"> 144 146 <div class="centered"> 145 <img src="{{ data.size.url }}" draggable="false" />147 <img src="{{ data.size.url }}" draggable="false" alt="" /> 146 148 </div> 147 149 </div> 148 150 <# } else { #> … … 157 159 <# } #> 158 160 159 161 <# if ( data.buttons.check ) { #> 160 <a class="check" href="#" title="<?php _e('Deselect'); ?>" ><div class="media-modal-icon"></div></a>162 <a class="check" href="#" title="<?php _e('Deselect'); ?>" tabindex="-1"><div class="media-modal-icon"></div></a> 161 163 <# } #> 162 164 </div> 163 165 <# -
wp-includes/css/media-views.css
441 441 border-right: 0; 442 442 } 443 443 444 .media-router > a:active, 445 .media-router > a:focus { 444 .media-router > a:active { 446 445 outline: none; 447 446 } 448 447 … … 635 634 user-select: none; 636 635 } 637 636 637 .attachment:focus { 638 box-shadow: 0px 0px 2pt 2pt #1e8cbe; 639 outline: none; 640 } 641 642 .isIE .attachment:focus { 643 outline: #1e8cbe solid; 644 } 645 638 646 .selected.attachment { 639 647 box-shadow: 640 648 0 0 0 1px #fff, 641 649 0 0 0 3px #ccc; 642 650 } 643 651 652 .isIE .selected.attachment { 653 outline: #1e8cbe solid; 654 } 655 644 656 .attachment-preview { 645 657 position: relative; 646 658 width: 199px; … … 836 848 right: 300px; 837 849 bottom: 0; 838 850 overflow: auto; 851 outline: none; 839 852 } 840 853 841 854 .attachments-browser .instructions {