Making WordPress.org

Changeset 8973


Ignore:
Timestamp:
06/20/2019 01:16:39 PM (5 years ago)
Author:
SergeyBiryukov
Message:

Trac: Improve accessibility of keywords and focuses on Trac ticket pages.

Props afercia.
Fixes #4495.

Location:
sites/trunk/wordpress.org/public_html/style/trac
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/style/trac/wp-trac.css

    r8303 r8973  
    698698    left: auto;
    699699}
     700/* hide focus while clicking the buttons, pending better focus styles */
     701button:focus:active,
     702input[type=button]:focus:active,
     703input[type=submit]:focus:active,
     704input[type=reset]:focus:active {
     705    outline: none;
     706}
    700707input[type=text], input.textwidget, textarea {
    701708    -webkit-border-radius: 3px;
     
    10271034    display: none;
    10281035}
     1036.core-focuses-legend {
     1037    display: block !important;
     1038    color: inherit;
     1039    margin: 0 0 6px;
     1040    padding: 0;
     1041    font-size: inherit;
     1042    font-weight: normal;
     1043    transform: translateY(-2px);
     1044}
     1045#fieldset-focuses,
    10291046#propertyform[action*="/newticket"] fieldset {
    10301047    padding: 0;
     
    10361053}
    10371054#propertyform[action*="/newticket"] #properties table.trac-properties > tbody > tr > td#focuses {
    1038     padding-left: 0;
     1055    padding-left: 58px;
    10391056}
    10401057#propertyform > p,
     
    14521469    cursor: help;
    14531470}
    1454 #keyword-bin span a {
     1471#keyword-bin .keyword-button-remove {
    14551472    margin: 1px 0 0 -15px;
     1473    padding: 0;
    14561474    cursor: pointer;
    14571475    width: 15px;
     
    14671485    color: #999;
    14681486}
    1469 #keyword-bin span a:hover {
     1487#keyword-bin .keyword-button-remove:hover,
     1488#keyword-bin .keyword-button-remove:focus {
    14701489    color: #c00;
    14711490}
    14721491#edit-keywords {
    14731492    cursor: pointer;
    1474     font-size: 8px;
    1475     color: #999;
    1476     margin: 6px 6px 0 6px;
     1493    font-size: 13px;
     1494    color: inherit;
     1495    margin: 2px 0;
     1496    border-radius: 3px;
     1497    vertical-align: middle;
     1498    background: #f7f7f7;
     1499    border: 1px solid #ccc;
     1500    box-shadow: 0 1px 0 #ccc;
     1501    color: #555;
     1502    box-shadow: none;
     1503}
     1504#edit-keywords:hover,
     1505#edit-keywords:focus {
     1506    background: #fafafa;
     1507    color: #23282d;
     1508    border-color: #999;
     1509}
     1510/* hide focus when moved programmatically, pending better focus styles */
     1511#edit-keywords.hide-programmatic-focus:focus {
     1512    outline: none;
    14771513}
    14781514.has-js #field-keywords {
     
    14841520#keyword-label {
    14851521    float: left;
    1486     padding: 5px 6px 5px 0;
     1522    padding: 2px 0.4em 2px 0.1em; /* emulates table cell padding */
    14871523    text-align: right;
     1524    white-space: nowrap;
     1525}
     1526#keyword-add {
     1527    margin-left: calc( 2px + .3em ); /* emulates table cell padding */
     1528    margin-right: 6px;
    14881529}
    14891530
     
    14961537}
    14971538#properties table.trac-properties > tbody > tr > td#focuses {
    1498     padding: .6em 0 .3em 60px;
    1499     height: 66px;
     1539    padding: .6em 0 .3em 52px;
    15001540}
    15011541#focuses span {
     
    15111551#focuses li {
    15121552    font-size: 12px;
     1553    float: left;
     1554    margin: 0 6px 6px 0;
     1555}
     1556#focuses .core-focuses-button {
    15131557    display: inline-block;
    1514     float: left;
    1515     margin: 0 0 6px 6px;
    1516     -webkit-border-radius: 3px;
     1558    margin: 0;
     1559    padding: 4px 7px;
     1560    color: inherit;
     1561    border: 1px solid #ccc;
    15171562    border-radius: 3px;
    15181563    background: #eee;
    1519     color: #aaa;
    1520 }
    1521 #focuses a {
    1522     display: inline-block;
    1523     padding: 4px 7px;
    1524     color: inherit;
    1525     -webkit-border-radius: 3px;
    1526     border-radius: 3px;
    1527     background: inherit;
    1528     text-decoration: none;
    1529     border-bottom: none;
    1530 }
    1531 #focuses li:hover,
    1532 #focuses a:focus {
    1533     color: #000;
    15341564    cursor: pointer;
    15351565}
    1536 #focuses li.active,
    1537 #focuses li.active a:focus {
     1566#focuses .core-focuses-button:hover,
     1567#focuses .core-focuses-button:focus {
     1568    background: #fafafa;
     1569    color: #23282d;
     1570    border-color: #999;
     1571}
     1572#focuses li.active .core-focuses-button,
     1573#focuses li.active .core-focuses-button:focus {
    15381574    background: #666;
    15391575    color: #fff;
     1576    border-color: #666;
    15401577}
    15411578
  • sites/trunk/wordpress.org/public_html/style/trac/wp-trac.js

    r8453 r8973  
    924924            return {
    925925                init: function() {
    926                     elements.hiddenEl = $('#field-keywords');
     926                    elements.hiddenEl = $( '#field-keywords' ).attr( 'aria-label', 'Manual keywords' );
    927927                    if ( ! elements.hiddenEl.length ) {
    928928                        return;
    929929                    }
     930
     931                    // Attach change event handler on the field-keywords input.
     932                    elements.hiddenEl.change( wpTrac.workflow.populate );
    930933
    931934                    // Designed so the list could have come from another file.
     
    947950
    948951                    // Keyword removal.
    949                     elements.bin.on( 'click', 'a', function(e) {
    950                         e.preventDefault();
     952                    elements.bin.on( 'click', '.keyword-button-remove', function() {
    951953                        wpTrac.workflow.removeKeyword( $(this).parent() );
     954                        // Move focus to the Manual keyword button to avoid focus loss on keyword removal.
     955                        $( '#edit-keywords' )
     956                            .addClass( 'hide-programmatic-focus' )
     957                            .focus()
     958                            .on( 'blur', function() {
     959                                $( this ).removeClass( 'hide-programmatic-focus' );
     960                            } );
    952961                    });
    953962
     
    966975                    });
    967976
    968                     // Manual link.
     977                    // Manual keyword button.
    969978                    $('#edit-keywords').click( function() {
     979                        if ( elements.hiddenEl.is( ':visible' ) ) {
     980                            elements.hiddenEl.hide();
     981                            $( this ).attr( 'aria-expanded', 'false' );
     982                            return;
     983                        }
     984
     985                        $( this ).attr( 'aria-expanded', 'true' );
    970986                        elements.hiddenEl.show().focus();
    971                         $(this).hide();
    972                         elements.hiddenEl.change( wpTrac.workflow.populate );
    973                     });
     987                    });
     988
     989                    // Handle keyboard interaction on the field-keywords field.
     990                    $( '#field-keywords' ).on( 'keydown', function( event ) {
     991                        // When pressing Enter or Escape.
     992                        if ( event.which === 13 || event.which === 27 ) {
     993                            // Prevent form submission.
     994                            event.preventDefault();
     995                            // Hide the input field and populate the keywords.
     996                            elements.hiddenEl.hide();
     997                            /*
     998                             * Move focus back to the Manual keyword button.
     999                             * This blurs the field and triggers the `change`
     1000                             * event thus the keywords are populated.
     1001                             */
     1002                            $( '#edit-keywords' )
     1003                                .attr( 'aria-expanded', 'false' )
     1004                                .focus();
     1005                        }
     1006                    } );
    9741007                },
    9751008
     
    9781011                    var container = elements.hiddenEl.parent(), html, labelWidth;
    9791012
    980                     // Necessary to keep everything in line. The + 4 is a careful CSS balance.
    981                     labelWidth = container.prev().width() + 4;
     1013                    // Necessary to keep everything in line.
     1014                    labelWidth = container.prev().width();
    9821015
    9831016                    // Rearrange the table to suit our needs.
     
    9901023
    9911024                    html = '<div><label id="keyword-label" for="keyword-add" style="width:' + labelWidth + 'px">Workflow Keywords:</label>';
    992                     html += '<select id="keyword-add"><option value=""> - Add - </option></select> <a id="edit-keywords">manual</a></div>';
     1025                    html += '<select id="keyword-add"><option value=""> - Add - </option></select>';
     1026                    html += '<button type="button" id="edit-keywords" aria-label="Manual keyword" aria-expanded="false">Manual</button></div>';
    9931027                    html += '<div id="keyword-bin"></div>';
    9941028                    container.prepend( html );
     
    10121046                    if ( 1 !== keywords.length || keywords[0] !== '' ) {
    10131047                        $.each( keywords, function( k, v ) {
    1014                             var html = $('<span />').text(v).attr('data-keyword', v).prepend('<a class="dashicons dashicons-dismiss" href="#" />');
     1048                            var html = $( '<span />' ).text( v ).attr( 'data-keyword', v ).prepend( '<button type="button" aria-label="Remove ' + v +' keyword" class="keyword-button-remove dashicons dashicons-dismiss" />' );
    10151049                            if ( v in coreKeywordList ) {
    10161050                                html.attr('title', coreKeywordList[v]);
     
    10871121
    10881122                    // Add it to the bin, and refresh the hidden input.
    1089                     html = $('<span />').text(keyword).attr('data-keyword', keyword).prepend('<a class="dashicons dashicons-dismiss" href="#" />');
     1123                    html = $( '<span />' ).text( keyword ).attr( 'data-keyword', keyword ).prepend( '<button type="button" aria-label="Remove ' + keyword +' keyword" class="keyword-button-remove dashicons dashicons-dismiss" />' );
    10901124                    if ( title ) {
    10911125                        html.attr('title', title);
     
    11721206
    11731207                container = $( '#focuses' );
    1174                 container.append( '<span>Focuses:</span>' );
     1208
    11751209                ul = $( '<ul />' );
    11761210                $.each( coreFocusesList, function( focus, description ) {
     1211                    var ariaPressed = 'false';
    11771212                    classes = focus.replace( ' ', '-' );
    11781213                    if ( -1 !== $.inArray( focus, focuses ) ) {
    11791214                        classes += ' active';
     1215                        ariaPressed = 'true';
    11801216                    }
    11811217                    ul.append( $( '<li />', {
     
    11831219                        title: description,
    11841220                        class: classes
    1185                     } ).html( '<a href="#">' + ( focus === 'administration' ? 'admin' : focus ) + '</a>' ) );
     1221                    } ).html( '<button type="button" class="core-focuses-button" aria-pressed="' + ariaPressed + '">' + ( focus === 'administration' ? 'admin' : focus ) + '</a>' ) );
    11861222                });
    11871223                ul.appendTo( container );
    1188 
    1189                 container.on( 'click', 'a', addRemove );
     1224                ul.wrap( '<fieldset id="fieldset-focuses" />' );
     1225                ul.before( '<legend class="core-focuses-legend">Focuses:</legend>' );
     1226
     1227                container.on( 'click', '.core-focuses-button', addRemove );
    11901228                container.closest( 'form' ).on( 'submit', submit );
    11911229                $( '#field-component' ).on( 'change', componentSync );
     
    11991237                    add( focus );
    12001238                }
    1201                 return false;
    12021239            }
    12031240
     
    12071244                }
    12081245                focus.addClass( 'active' );
     1246                focus.find( '.core-focuses-button' ).attr( 'aria-pressed', 'true' );
    12091247                focuses.push( focus.data( 'focus' ) );
    12101248                updateField();
     
    12161254                }
    12171255                focus.removeClass( 'active' );
     1256                focus.find( '.core-focuses-button' ).attr( 'aria-pressed', 'false' );
    12181257                var remove = focus.data( 'focus' );
    12191258                focuses = $.grep( focuses, function( value ) {
Note: See TracChangeset for help on using the changeset viewer.