<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[48373] trunk/src: Accessibility: Allow post boxes on the Dashboard and Classic Editor pages to be reordered by using the keyboard.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/48373">48373</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/48373","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>afercia</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2020-07-07 12:58:10 +0000 (Tue, 07 Jul 2020)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Accessibility: Allow post boxes on the Dashboard and Classic Editor pages to be reordered by using the keyboard.

So far, it has been possible to rearrange into a new order the post boxes (also known as "widgets" on the Dashboard and "meta boxes" on the Edit post page) only by using a pointing device, for example a mouse.

This change adds new controls and functionality to allow the boxes to be rearranged also with the keyboard. Additionally, audible messages are sent to the admin ARIA live region to notify screen reader users of the reorder action result.

Props joedolson, anevins, antpb, audrasjb, xkon, MarcoZ, karmatosed, afercia.
Fixes <a href="https://core.trac.wordpress.org/ticket/39074">#39074</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcjs_enqueuesadminpostboxjs">trunk/src/js/_enqueues/admin/postbox.js</a></li>
<li><a href="#trunksrcwpadmincsscommoncss">trunk/src/wp-admin/css/common.css</a></li>
<li><a href="#trunksrcwpadmincssdashboardcss">trunk/src/wp-admin/css/dashboard.css</a></li>
<li><a href="#trunksrcwpadminincludesajaxactionsphp">trunk/src/wp-admin/includes/ajax-actions.php</a></li>
<li><a href="#trunksrcwpadminincludestemplatephp">trunk/src/wp-admin/includes/template.php</a></li>
<li><a href="#trunksrcwpincludesscriptloaderphp">trunk/src/wp-includes/script-loader.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcjs_enqueuesadminpostboxjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/js/_enqueues/admin/postbox.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/js/_enqueues/admin/postbox.js   2020-07-07 12:55:26 UTC (rev 48372)
+++ trunk/src/js/_enqueues/admin/postbox.js     2020-07-07 12:58:10 UTC (rev 48373)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -42,7 +42,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                 */
</span><span class="cx" style="display: block; padding: 0 10px">                handle_click : function () {
</span><span class="cx" style="display: block; padding: 0 10px">                        var $el = $( this ),
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                p = $el.parent( '.postbox' ),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         p = $el.closest( '.postbox' ),
</ins><span class="cx" style="display: block; padding: 0 10px">                                 id = p.attr( 'id' ),
</span><span class="cx" style="display: block; padding: 0 10px">                                ariaExpandedValue;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -51,7 +51,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        p.toggleClass( 'closed' );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
</del><span class="cx" style="display: block; padding: 0 10px">                         ariaExpandedValue = ! p.hasClass( 'closed' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        if ( $el.hasClass( 'handlediv' ) ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -90,6 +89,143 @@
</span><span class="cx" style="display: block; padding: 0 10px">                },
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 * Handles clicks on the move up/down buttons.
+                *
+                * @since 5.5.0
+                *
+                * @return {void}
+                */
+               handleOrder: function() {
+                       var button = $( this ),
+                               postbox = button.closest( '.postbox' ),
+                               postboxId = postbox.attr( 'id' ),
+                               postboxesWithinSortables = postbox.closest( '.meta-box-sortables' ).find( '.postbox:visible' ),
+                               postboxesWithinSortablesCount = postboxesWithinSortables.length,
+                               postboxWithinSortablesIndex = postboxesWithinSortables.index( postbox ),
+                               firstOrLastPositionMessage;
+
+                       if ( 'dashboard_browser_nag' === postboxId ) {
+                               return;
+                       }
+
+                       // If on the first or last position, do nothing and send an audible message to screen reader users.
+                       if ( 'true' === button.attr( 'aria-disabled' ) ) {
+                               firstOrLastPositionMessage = button.hasClass( 'handle-order-higher' ) ?
+                                       __( 'The box is on the first position' ) :
+                                       __( 'The box is on the last position' );
+
+                               wp.a11y.speak( firstOrLastPositionMessage );
+                               return;
+                       }
+
+                       // Move a postbox up.
+                       if ( button.hasClass( 'handle-order-higher' ) ) {
+                               // If the box is first within a sortable area, move it to the previous sortable area.
+                               if ( 0 === postboxWithinSortablesIndex ) {
+                                       postboxes.handleOrderBetweenSortables( 'previous', button, postbox );
+                                       return;
+                               }
+
+                               postbox.prevAll( '.postbox:visible' ).eq( 0 ).before( postbox );
+                               button.focus();
+                               postboxes.updateOrderButtonsProperties();
+                               postboxes.save_order( postboxes.page );
+                       }
+
+                       // Move a postbox down.
+                       if ( button.hasClass( 'handle-order-lower' ) ) {
+                               // If the box is last within a sortable area, move it to the next sortable area.
+                               if ( postboxWithinSortablesIndex + 1 === postboxesWithinSortablesCount ) {
+                                       postboxes.handleOrderBetweenSortables( 'next', button, postbox );
+                                       return;
+                               }
+
+                               postbox.nextAll( '.postbox:visible' ).eq( 0 ).after( postbox );
+                               button.focus();
+                               postboxes.updateOrderButtonsProperties();
+                               postboxes.save_order( postboxes.page );
+                       }
+
+               },
+
+               /**
+                * Moves postboxes between the sortables areas.
+                *
+                * @since 5.5.0
+                *
+                * @param {string} position The "previous" or "next" sortables area.
+                * @param {object} button   The jQuery object representing the button that was clicked.
+                * @param {object} postbox  The jQuery object representing the postbox to be moved.
+                *
+                * @return {void}
+                */
+               handleOrderBetweenSortables: function( position, button, postbox ) {
+                       var closestSortablesId = button.closest( '.meta-box-sortables' ).attr( 'id' ),
+                               sortablesIds = [],
+                               sortablesIndex,
+                               detachedPostbox;
+
+                       // Get the list of sortables within the page.
+                       $( '.meta-box-sortables:visible' ).each( function() {
+                               sortablesIds.push( $( this ).attr( 'id' ) );
+                       });
+
+                       // Return if there's only one visible sortables area, e.g. in the block editor page.
+                       if ( 1 === sortablesIds.length ) {
+                               return;
+                       }
+
+                       // Find the index of the current sortables area within all the sortable areas.
+                       sortablesIndex = $.inArray( closestSortablesId, sortablesIds );
+                       // Detach the postbox to be moved.
+                       detachedPostbox = postbox.detach();
+
+                       // Move the detached postbox to its new position.
+                       if ( 'previous' === position ) {
+                               $( detachedPostbox ).appendTo( '#' + sortablesIds[ sortablesIndex - 1 ] );
+                       }
+
+                       if ( 'next' === position ) {
+                               $( detachedPostbox ).prependTo( '#' + sortablesIds[ sortablesIndex + 1 ] );
+                       }
+
+                       postboxes._mark_area();
+                       button.focus();
+                       postboxes.updateOrderButtonsProperties();
+                       postboxes.save_order( postboxes.page );
+               },
+
+               /**
+                * Update the move buttons properties depending on the postbox position.
+                *
+                * @since 5.5.0
+                *
+                * @return {void}
+                */
+               updateOrderButtonsProperties: function() {
+                       var firstSortablesId = $( '.meta-box-sortables:first' ).attr( 'id' ),
+                               lastSortablesId = $( '.meta-box-sortables:last' ).attr( 'id' ),
+                               firstPostbox = $( '.postbox:visible:first' ),
+                               lastPostbox = $( '.postbox:visible:last' ),
+                               firstPostboxSortablesId = firstPostbox.closest( '.meta-box-sortables' ).attr( 'id' ),
+                               lastPostboxSortablesId = lastPostbox.closest( '.meta-box-sortables' ).attr( 'id' );
+
+                       // Enable all buttons as a reset first.
+                       $( '.handle-order-higher' ).attr( 'aria-disabled', 'false' );
+                       $( '.handle-order-lower' ).attr( 'aria-disabled', 'false' );
+
+                       // Set an aria-disabled=true attribute on the first visible "move" buttons.
+                       if ( firstSortablesId === firstPostboxSortablesId ) {
+                               $( firstPostbox ).find( '.handle-order-higher' ).attr( 'aria-disabled', 'true' );
+                       }
+
+                       // Set an aria-disabled=true attribute on the last visible "move" buttons.
+                       if ( lastSortablesId === lastPostboxSortablesId ) {
+                               $( '.postbox:visible .handle-order-lower' ).last().attr( 'aria-disabled', 'true' );
+                       }
+               },
+
+               /**
</ins><span class="cx" style="display: block; padding: 0 10px">                  * Adds event handlers to all postboxes and screen option on the current page.
</span><span class="cx" style="display: block; padding: 0 10px">                 *
</span><span class="cx" style="display: block; padding: 0 10px">                 * @since 2.7.0
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -103,7 +239,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">                 * @return {void}
</span><span class="cx" style="display: block; padding: 0 10px">                 */
</span><span class="cx" style="display: block; padding: 0 10px">                add_postbox_toggles : function (page, args) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        var $handles = $( '.postbox .hndle, .postbox .handlediv' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 var $handles = $( '.postbox .hndle, .postbox .handlediv' ),
+                               $orderButtons = $( '.postbox .handle-order-higher, .postbox .handle-order-lower' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        this.page = page;
</span><span class="cx" style="display: block; padding: 0 10px">                        this.init( page, args );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -110,6 +247,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        $handles.on( 'click.postboxes', this.handle_click );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        // Handle the order of the postboxes.
+                       $orderButtons.on( 'click.postboxes', this.handleOrder );
+
</ins><span class="cx" style="display: block; padding: 0 10px">                         /**
</span><span class="cx" style="display: block; padding: 0 10px">                         * @since 2.7.0
</span><span class="cx" style="display: block; padding: 0 10px">                         */
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -123,6 +263,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">                         * Event handler for the postbox dismiss button. After clicking the button
</span><span class="cx" style="display: block; padding: 0 10px">                         * the postbox will be hidden.
</span><span class="cx" style="display: block; padding: 0 10px">                         *
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         * As of WordPress 5.5, this is only used for the browser update nag.
+                        *
</ins><span class="cx" style="display: block; padding: 0 10px">                          * @since 3.2.0
</span><span class="cx" style="display: block; padding: 0 10px">                         *
</span><span class="cx" style="display: block; padding: 0 10px">                         * @return {void}
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -248,6 +390,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                $el.sortable('cancel');
</span><span class="cx" style="display: block; padding: 0 10px">                                                return;
</span><span class="cx" style="display: block; padding: 0 10px">                                        }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+                                       postboxes.updateOrderButtonsProperties();
</ins><span class="cx" style="display: block; padding: 0 10px">                                         postboxes.save_order(page);
</span><span class="cx" style="display: block; padding: 0 10px">                                },
</span><span class="cx" style="display: block; padding: 0 10px">                                receive: function(e,ui) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -266,10 +410,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        this._mark_area();
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        // Update the "move" buttons properties.
+                       this.updateOrderButtonsProperties();
+                       $document.on( 'postbox-toggled', this.updateOrderButtonsProperties );
+
</ins><span class="cx" style="display: block; padding: 0 10px">                         // Set the handle buttons `aria-expanded` attribute initial value on page load.
</span><span class="cx" style="display: block; padding: 0 10px">                        $handleButtons.each( function () {
</span><span class="cx" style="display: block; padding: 0 10px">                                var $el = $( this );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                $el.attr( 'aria-expanded', ! $el.parent( '.postbox' ).hasClass( 'closed' ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         $el.attr( 'aria-expanded', ! $el.closest( '.postbox' ).hasClass( 'closed' ) );
</ins><span class="cx" style="display: block; padding: 0 10px">                         });
</span><span class="cx" style="display: block; padding: 0 10px">                },
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -332,7 +480,15 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                postVars[ 'order[' + this.id.split( '-' )[0] + ']' ] = $( this ).sortable( 'toArray' ).join( ',' );
</span><span class="cx" style="display: block; padding: 0 10px">                        } );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $.post( ajaxurl, postVars );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $.post(
+                               ajaxurl,
+                               postVars,
+                               function( response ) {
+                                       if ( response.success ) {
+                                               wp.a11y.speak( __( 'The boxes order has been saved.' ) );
+                                       }
+                               }
+                       );
</ins><span class="cx" style="display: block; padding: 0 10px">                 },
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                /**
</span></span></pre></div>
<a id="trunksrcwpadmincsscommoncss"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-admin/css/common.css</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/css/common.css 2020-07-07 12:55:26 UTC (rev 48372)
+++ trunk/src/wp-admin/css/common.css   2020-07-07 12:58:10 UTC (rev 48373)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -727,7 +727,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">        color: #23282d;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-.postbox .hndle,
</del><span class="cx" style="display: block; padding: 0 10px"> .stuffbox .hndle {
</span><span class="cx" style="display: block; padding: 0 10px">        border-bottom: 1px solid #ccd0d4;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1983,14 +1982,34 @@
</span><span class="cx" style="display: block; padding: 0 10px">        cursor: auto;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* Configurable dashboard widgets "Configure" edit-box link. */
</ins><span class="cx" style="display: block; padding: 0 10px"> .hndle a {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        font-size: 11px;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ font-size: 12px;
</ins><span class="cx" style="display: block; padding: 0 10px">         font-weight: 400;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.postbox-header {
+       display: flex;
+       align-items: center;
+       justify-content: space-between;
+       border-bottom: 1px solid #ccd0d4;
+}
+
+.postbox-header .hndle {
+       flex-grow: 1;
+       /* Handle the alignment for the configurable dashboard widgets "Configure" edit-box link. */
+       display: flex;
+       justify-content: space-between;
+       align-items: center;
+}
+
+.postbox-header .handle-actions {
+       flex-shrink: 0;
+}
+
+.postbox .handle-order-higher,
+.postbox .handle-order-lower,
</ins><span class="cx" style="display: block; padding: 0 10px"> .postbox .handlediv {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        display: none;
-       float: right;
</del><span class="cx" style="display: block; padding: 0 10px">         width: 36px;
</span><span class="cx" style="display: block; padding: 0 10px">        height: 36px;
</span><span class="cx" style="display: block; padding: 0 10px">        margin: 0;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2000,10 +2019,17 @@
</span><span class="cx" style="display: block; padding: 0 10px">        cursor: pointer;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-.js .postbox .handlediv {
-       display: block;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.postbox .handle-order-higher,
+.postbox .handle-order-lower {
+       color: #72777c;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.postbox .handle-order-higher[aria-disabled="true"],
+.postbox .handle-order-lower[aria-disabled="true"] {
+       cursor: default;
+       color: #a0a5aa;
+}
+
</ins><span class="cx" style="display: block; padding: 0 10px"> .sortable-placeholder {
</span><span class="cx" style="display: block; padding: 0 10px">        border: 1px dashed #b4b9be;
</span><span class="cx" style="display: block; padding: 0 10px">        margin-bottom: 20px;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2949,10 +2975,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /* Metabox collapse arrow indicators */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-.sidebar-name .toggle-indicator:before,
-.js .meta-box-sortables .postbox .toggle-indicator:before,
-.bulk-action-notice .toggle-indicator:before,
-.privacy-text-box .toggle-indicator:before {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.sidebar-name .toggle-indicator::before,
+.meta-box-sortables .postbox .toggle-indicator::before,
+.meta-box-sortables .postbox .order-higher-indicator::before,
+.meta-box-sortables .postbox .order-lower-indicator::before,
+.bulk-action-notice .toggle-indicator::before,
+.privacy-text-box .toggle-indicator::before {
</ins><span class="cx" style="display: block; padding: 0 10px">         content: "\f142";
</span><span class="cx" style="display: block; padding: 0 10px">        display: inline-block;
</span><span class="cx" style="display: block; padding: 0 10px">        font: normal 20px/1 dashicons;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2962,37 +2990,55 @@
</span><span class="cx" style="display: block; padding: 0 10px">        text-decoration: none;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-.js .widgets-holder-wrap.closed .toggle-indicator:before,
-.js .meta-box-sortables .postbox.closed .handlediv .toggle-indicator:before,
-.bulk-action-notice .bulk-action-errors-collapsed .toggle-indicator:before,
-.privacy-text-box.closed .toggle-indicator:before {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.js .widgets-holder-wrap.closed .toggle-indicator::before,
+.meta-box-sortables .postbox.closed .handlediv .toggle-indicator::before,
+.bulk-action-notice .bulk-action-errors-collapsed .toggle-indicator::before,
+.privacy-text-box.closed .toggle-indicator::before {
</ins><span class="cx" style="display: block; padding: 0 10px">         content: "\f140";
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-.js .postbox .handlediv .toggle-indicator:before {
-       margin-top: 4px;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.postbox .handle-order-higher .order-higher-indicator::before {
+       content: "\f343";
+       color: inherit;
+}
+
+.postbox .handle-order-lower .order-lower-indicator::before {
+       content: "\f347";
+       color: inherit;
+}
+
+.postbox .handle-order-higher .order-higher-indicator::before,
+.postbox .handle-order-lower .order-lower-indicator::before,
+.postbox .handlediv .toggle-indicator::before {
</ins><span class="cx" style="display: block; padding: 0 10px">         width: 20px;
</span><span class="cx" style="display: block; padding: 0 10px">        border-radius: 50%;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        text-indent: -1px; /* account for the dashicon alignment */
</del><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-.rtl.js .postbox .handlediv .toggle-indicator:before {
-       text-indent: 1px; /* account for the dashicon alignment */
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.postbox .handlediv .toggle-indicator::before {
+       text-indent: -1px; /* account for the dashicon glyph uneven horizontal alignment */
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-.bulk-action-notice .toggle-indicator:before {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.rtl .postbox .handlediv .toggle-indicator::before {
+       text-indent: 1px; /* account for the dashicon glyph uneven horizontal alignment */
+}
+
+.bulk-action-notice .toggle-indicator::before {
</ins><span class="cx" style="display: block; padding: 0 10px">         line-height: 16px;
</span><span class="cx" style="display: block; padding: 0 10px">        vertical-align: top;
</span><span class="cx" style="display: block; padding: 0 10px">        color: #72777c;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-.js .postbox .handlediv:focus {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.postbox .handle-order-higher:focus,
+.postbox .handle-order-lower:focus,
+.postbox .handlediv:focus {
</ins><span class="cx" style="display: block; padding: 0 10px">         box-shadow: none;
</span><span class="cx" style="display: block; padding: 0 10px">        /* Only visible in Windows High Contrast mode */
</span><span class="cx" style="display: block; padding: 0 10px">        outline: 1px solid transparent;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-.js .postbox .handlediv:focus .toggle-indicator:before {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.postbox .handle-order-higher:focus .order-higher-indicator::before,
+.postbox .handle-order-lower:focus .order-lower-indicator::before,
+.postbox .handlediv:focus .toggle-indicator::before {
</ins><span class="cx" style="display: block; padding: 0 10px">         box-shadow:
</span><span class="cx" style="display: block; padding: 0 10px">                0 0 0 1px #5b9dd9,
</span><span class="cx" style="display: block; padding: 0 10px">                0 0 2px 1px rgba(30, 140, 190, 0.8);
</span></span></pre></div>
<a id="trunksrcwpadmincssdashboardcss"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-admin/css/dashboard.css</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/css/dashboard.css      2020-07-07 12:55:26 UTC (rev 48372)
+++ trunk/src/wp-admin/css/dashboard.css        2020-07-07 12:58:10 UTC (rev 48373)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -48,6 +48,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> #dashboard-widgets .meta-box-sortables {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        display: flow-root; /* avoid margin collapsing between parent and first/last child elements */
</ins><span class="cx" style="display: block; padding: 0 10px">         /* Required min-height to make the jQuery UI Sortable drop zone work. */
</span><span class="cx" style="display: block; padding: 0 10px">        min-height: 100px;
</span><span class="cx" style="display: block; padding: 0 10px">        margin: 0 8px 20px;
</span></span></pre></div>
<a id="trunksrcwpadminincludesajaxactionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-admin/includes/ajax-actions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/includes/ajax-actions.php      2020-07-07 12:55:26 UTC (rev 48372)
+++ trunk/src/wp-admin/includes/ajax-actions.php        2020-07-07 12:58:10 UTC (rev 48373)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1927,7 +1927,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                update_user_option( $user->ID, "screen_layout_$page", $page_columns, true );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        wp_die( 1 );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ wp_send_json_success();
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span></span></pre></div>
<a id="trunksrcwpadminincludestemplatephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-admin/includes/template.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/includes/template.php  2020-07-07 12:55:26 UTC (rev 48372)
+++ trunk/src/wp-admin/includes/template.php    2020-07-07 12:58:10 UTC (rev 48373)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1314,6 +1314,16 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                        // get_hidden_meta_boxes() doesn't apply in the block editor.
</span><span class="cx" style="display: block; padding: 0 10px">                                        $hidden_class = ( ! $screen->is_block_editor() && in_array( $box['id'], $hidden, true ) ) ? ' hide-if-js' : '';
</span><span class="cx" style="display: block; padding: 0 10px">                                        echo '<div id="' . $box['id'] . '" class="postbox ' . postbox_classes( $box['id'], $page ) . $hidden_class . '" ' . '>' . "\n";
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+                                       echo '<div class="postbox-header">';
+                                       echo '<h2 class="hndle">';
+                                       if ( 'dashboard_php_nag' === $box['id'] ) {
+                                               echo '<span aria-hidden="true" class="dashicons dashicons-warning"></span>';
+                                               echo '<span class="screen-reader-text">' . __( 'Warning:' ) . ' </span>';
+                                       }
+                                       echo "{$box['title']}";
+                                       echo "</h2>\n";
+
</ins><span class="cx" style="display: block; padding: 0 10px">                                         if ( 'dashboard_browser_nag' !== $box['id'] ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                                $widget_title = $box['title'];
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1323,6 +1333,28 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                        unset( $box['args']['__widget_basename'] );
</span><span class="cx" style="display: block; padding: 0 10px">                                                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                echo '<div class="handle-actions hide-if-no-js">';
+
+                                               echo '<button type="button" class="handle-order-higher" aria-disabled="false" aria-describedby="' . $box['id'] . '-handle-order-higher-description">';
+                                               echo '<span class="screen-reader-text">' . __( 'Move up' ) . '</span>';
+                                               echo '<span class="order-higher-indicator" aria-hidden="true"></span>';
+                                               echo '</button>';
+                                               echo '<span class="hidden" id="' . $box['id'] . '-handle-order-higher-description">' . sprintf(
+                                                       /* translators: %s: Meta box title. */
+                                                       __( 'Move %s box up' ),
+                                                       $widget_title
+                                               ) . '</span>';
+
+                                               echo '<button type="button" class="handle-order-lower" aria-disabled="false" aria-describedby="' . $box['id'] . '-handle-order-lower-description">';
+                                               echo '<span class="screen-reader-text">' . __( 'Move down' ) . '</span>';
+                                               echo '<span class="order-lower-indicator" aria-hidden="true"></span>';
+                                               echo '</button>';
+                                               echo '<span class="hidden" id="' . $box['id'] . '-handle-order-lower-description">' . sprintf(
+                                                       /* translators: %s: Meta box title. */
+                                                       __( 'Move %s box down' ),
+                                                       $widget_title
+                                               ) . '</span>';
+
</ins><span class="cx" style="display: block; padding: 0 10px">                                                 echo '<button type="button" class="handlediv" aria-expanded="true">';
</span><span class="cx" style="display: block; padding: 0 10px">                                                echo '<span class="screen-reader-text">' . sprintf(
</span><span class="cx" style="display: block; padding: 0 10px">                                                        /* translators: %s: Meta box title. */
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1331,14 +1363,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                ) . '</span>';
</span><span class="cx" style="display: block; padding: 0 10px">                                                echo '<span class="toggle-indicator" aria-hidden="true"></span>';
</span><span class="cx" style="display: block; padding: 0 10px">                                                echo '</button>';
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+                                               echo '</div>';
</ins><span class="cx" style="display: block; padding: 0 10px">                                         }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        echo '<h2 class="hndle">';
-                                       if ( 'dashboard_php_nag' === $box['id'] ) {
-                                               echo '<span aria-hidden="true" class="dashicons dashicons-warning"></span>';
-                                               echo '<span class="screen-reader-text">' . __( 'Warning:' ) . ' </span>';
-                                       }
-                                       echo "<span>{$box['title']}</span>";
-                                       echo "</h2>\n";
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 echo '</div>';
+
</ins><span class="cx" style="display: block; padding: 0 10px">                                         echo '<div class="inside">' . "\n";
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                                        if ( WP_DEBUG && ! $block_compatible && 'edit' === $screen->parent_base && ! $screen->is_block_editor() && ! isset( $_GET['meta-box-loader'] ) ) {
</span></span></pre></div>
<a id="trunksrcwpincludesscriptloaderphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/script-loader.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/script-loader.php   2020-07-07 12:55:26 UTC (rev 48372)
+++ trunk/src/wp-includes/script-loader.php     2020-07-07 12:58:10 UTC (rev 48373)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1208,7 +1208,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $scripts->add( 'xfn', "/wp-admin/js/xfn$suffix.js", array( 'jquery' ), false, 1 );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $scripts->add( 'postbox', "/wp-admin/js/postbox$suffix.js", array( 'jquery-ui-sortable' ), false, 1 );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $scripts->add( 'postbox', "/wp-admin/js/postbox$suffix.js", array( 'jquery-ui-sortable', 'wp-a11y' ), false, 1 );
</ins><span class="cx" style="display: block; padding: 0 10px">                 $scripts->set_translations( 'postbox' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $scripts->add( 'tags-box', "/wp-admin/js/tags-box$suffix.js", array( 'jquery', 'tags-suggest' ), false, 1 );
</span></span></pre>
</div>
</div>

</body>
</html>