Accessibility: Privacy: Accessibility improvements for the Privacy Policy Guide page.

Improves accessibility of the "Copy this section" button and "Return to Top" link:
- uses `setTimeout()` and `clearTimeout()` to properly handle the "Copied!" text
- simplifies the button text by removing the redundant visually hidden text
- fixes the mismatching visual and DOM order of the Copy button and the "Return to Top" link 
- improves the "Return to Top" links by providing real page fragment identifiers, when possible
- hides the "Return to Top" up arrow from assistive technologies
- minor coding standards

Props afercia, garrett-eclipse.
See #48463, #50322.
Fixes #50335.


git-svn-id: https://develop.svn.wordpress.org/trunk@48234 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Andrea Fercia 2020-06-30 13:54:40 +00:00
parent 2df56667b3
commit 0445f4b95c
4 changed files with 42 additions and 31 deletions

View File

@ -6,7 +6,8 @@
// Privacy request action handling. // Privacy request action handling.
jQuery( document ).ready( function( $ ) { jQuery( document ).ready( function( $ ) {
var strings = window.privacyToolsL10n || {}; var strings = window.privacyToolsL10n || {},
copiedNoticeTimeout;
function setActionState( $action, state ) { function setActionState( $action, state ) {
$action.children().addClass( 'hidden' ); $action.children().addClass( 'hidden' );
@ -88,7 +89,7 @@ jQuery( document ).ready( function( $ ) {
onExportFailure( strings.noExportFile ); onExportFailure( strings.noExportFile );
} }
setTimeout( function(){ $rowActions.removeClass( 'processing' ); }, 500 ); setTimeout( function() { $rowActions.removeClass( 'processing' ); }, 500 );
} }
function onExportFailure( errorMessage ) { function onExportFailure( errorMessage ) {
@ -97,12 +98,13 @@ jQuery( document ).ready( function( $ ) {
appendResultsAfterRow( $requestRow, 'notice-error', strings.exportError, [ errorMessage ] ); appendResultsAfterRow( $requestRow, 'notice-error', strings.exportError, [ errorMessage ] );
} }
setTimeout( function(){ $rowActions.removeClass( 'processing' ); }, 500 ); setTimeout( function() { $rowActions.removeClass( 'processing' ); }, 500 );
} }
function setExportProgress( exporterIndex ) { function setExportProgress( exporterIndex ) {
var progress = ( exportersCount > 0 ? exporterIndex / exportersCount : 0 ); var progress = ( exportersCount > 0 ? exporterIndex / exportersCount : 0 ),
var progressString = Math.round( progress * 100 ).toString() + '%'; progressString = Math.round( progress * 100 ).toString() + '%';
$progress.html( progressString ); $progress.html( progressString );
} }
@ -125,7 +127,7 @@ jQuery( document ).ready( function( $ ) {
if ( ! response.success ) { if ( ! response.success ) {
// e.g. invalid request ID. // e.g. invalid request ID.
setTimeout( function(){ onExportFailure( response.data ); }, 500 ); setTimeout( function() { onExportFailure( response.data ); }, 500 );
return; return;
} }
@ -136,12 +138,12 @@ jQuery( document ).ready( function( $ ) {
if ( exporterIndex < exportersCount ) { if ( exporterIndex < exportersCount ) {
setTimeout( doNextExport( exporterIndex + 1, 1 ) ); setTimeout( doNextExport( exporterIndex + 1, 1 ) );
} else { } else {
setTimeout( function(){ onExportDoneSuccess( responseData.url ); }, 500 ); setTimeout( function() { onExportDoneSuccess( responseData.url ); }, 500 );
} }
} }
}).fail( function( jqxhr, textStatus, error ) { }).fail( function( jqxhr, textStatus, error ) {
// e.g. Nonce failure. // e.g. Nonce failure.
setTimeout( function(){ onExportFailure( error ); }, 500 ); setTimeout( function() { onExportFailure( error ); }, 500 );
}); });
} }
@ -173,8 +175,8 @@ jQuery( document ).ready( function( $ ) {
setErasureProgress( 0 ); setErasureProgress( 0 );
function onErasureDoneSuccess() { function onErasureDoneSuccess() {
var summaryMessage = strings.noDataFound; var summaryMessage = strings.noDataFound,
var classes = 'notice-success'; classes = 'notice-success';
setActionState( $action, 'remove-personal-data-success' ); setActionState( $action, 'remove-personal-data-success' );
@ -195,19 +197,20 @@ jQuery( document ).ready( function( $ ) {
} }
appendResultsAfterRow( $requestRow, classes, summaryMessage, messages ); appendResultsAfterRow( $requestRow, classes, summaryMessage, messages );
setTimeout( function(){ $rowActions.removeClass( 'processing' ); }, 500 ); setTimeout( function() { $rowActions.removeClass( 'processing' ); }, 500 );
} }
function onErasureFailure() { function onErasureFailure() {
setActionState( $action, 'remove-personal-data-failed' ); setActionState( $action, 'remove-personal-data-failed' );
appendResultsAfterRow( $requestRow, 'notice-error', strings.removalError, [] ); appendResultsAfterRow( $requestRow, 'notice-error', strings.removalError, [] );
setTimeout( function(){ $rowActions.removeClass( 'processing' ); }, 500 ); setTimeout( function() { $rowActions.removeClass( 'processing' ); }, 500 );
} }
function setErasureProgress( eraserIndex ) { function setErasureProgress( eraserIndex ) {
var progress = ( erasersCount > 0 ? eraserIndex / erasersCount : 0 ); var progress = ( erasersCount > 0 ? eraserIndex / erasersCount : 0 ),
var progressString = Math.round( progress * 100 ).toString() + '%'; progressString = Math.round( progress * 100 ).toString() + '%';
$progress.html( progressString ); $progress.html( progressString );
} }
@ -226,7 +229,7 @@ jQuery( document ).ready( function( $ ) {
var responseData = response.data; var responseData = response.data;
if ( ! response.success ) { if ( ! response.success ) {
setTimeout( function(){ onErasureFailure(); }, 500 ); setTimeout( function() { onErasureFailure(); }, 500 );
return; return;
} }
if ( responseData.items_removed ) { if ( responseData.items_removed ) {
@ -245,11 +248,11 @@ jQuery( document ).ready( function( $ ) {
if ( eraserIndex < erasersCount ) { if ( eraserIndex < erasersCount ) {
setTimeout( doNextErasure( eraserIndex + 1, 1 ) ); setTimeout( doNextErasure( eraserIndex + 1, 1 ) );
} else { } else {
setTimeout( function(){ onErasureDoneSuccess(); }, 500 ); setTimeout( function() { onErasureDoneSuccess(); }, 500 );
} }
} }
}).fail( function() { }).fail( function() {
setTimeout( function(){ onErasureFailure(); }, 500 ); setTimeout( function() { onErasureFailure(); }, 500 );
}); });
} }
@ -268,6 +271,8 @@ jQuery( document ).ready( function( $ ) {
$target = $( event.target ), $target = $( event.target ),
copiedNotice = $target.siblings( '.success' ); copiedNotice = $target.siblings( '.success' );
clearTimeout( copiedNoticeTimeout );
if ( $target.is( 'button.privacy-text-copy' ) ) { if ( $target.is( 'button.privacy-text-copy' ) ) {
$parent = $target.parent().parent(); $parent = $target.parent().parent();
$container = $parent.find( 'div.wp-suggested-text' ); $container = $parent.find( 'div.wp-suggested-text' );
@ -309,10 +314,11 @@ jQuery( document ).ready( function( $ ) {
wp.a11y.speak( __( 'The section has been copied to your clipboard.' ) ); wp.a11y.speak( __( 'The section has been copied to your clipboard.' ) );
// Delay notice dismissal. // Delay notice dismissal.
setTimeout( function(){ copiedNotice.removeClass( 'visible' ); }, 3000 ); copiedNoticeTimeout = setTimeout( function() {
copiedNotice.removeClass( 'visible' );
}, 3000 );
} catch ( er ) {} } catch ( er ) {}
} }
} }
}); });
}); });

View File

@ -717,6 +717,8 @@ form#tags-filter {
} }
.privacy-text-actions { .privacy-text-actions {
display: inline-block;
width: 100%;
height: 32px; height: 32px;
line-height: 2.46153846; line-height: 2.46153846;
padding-bottom: 6px; padding-bottom: 6px;
@ -743,12 +745,19 @@ form#tags-filter {
font-style: italic; font-style: italic;
} }
.privacy-text-section a.return-to-top { .privacy-text-section .return-to-top {
float: right; float: right;
margin-right: -250px; margin-right: -250px;
margin-top: 6px; margin-top: 6px;
} }
#wpbody:target:before {
content: "";
display: block;
padding-top: 50px;
margin-top: -50px;
}
.hide-privacy-policy-tutorial { .hide-privacy-policy-tutorial {
background-color: #fff; background-color: #fff;
} }
@ -1758,8 +1767,7 @@ table.links-table {
flex-direction: column; flex-direction: column;
} }
.privacy-text-section a.return-to-top { .privacy-text-section .return-to-top {
float: none; margin: 2em 0 0;
margin: 0;
} }
} }

View File

@ -412,21 +412,18 @@ final class WP_Privacy_Policy_Content {
$content .= $removed; $content .= $removed;
$content .= '<div class="policy-text">' . $section['policy_text'] . '</div>'; $content .= '<div class="policy-text">' . $section['policy_text'] . '</div>';
$content .= '<a href="#" class="return-to-top">' . __( '&uarr; Return to Top' ) . '</a>';
if ( empty( $section['removed'] ) ) { if ( empty( $section['removed'] ) ) {
$content .= '<div class="privacy-text-actions">'; $content .= '<div class="privacy-text-actions">';
$content .= '<button type="button" class="privacy-text-copy button">'; $content .= '<button type="button" class="privacy-text-copy button">';
$content .= __( 'Copy this section to clipboard' ); $content .= __( 'Copy this section to clipboard' );
$content .= '<span class="screen-reader-text">';
/* translators: %s: Plugin name. */
$content .= sprintf( __( 'Copy suggested policy text from %s.' ), $plugin_name );
$content .= '</span>';
$content .= '</button>'; $content .= '</button>';
$content .= '<span class="success" aria-hidden="true">' . __( 'Copied!' ) . '</span>'; $content .= '<span class="success" aria-hidden="true">' . __( 'Copied!' ) . '</span>';
$content .= '</div>'; $content .= '</div>';
} }
$content .= '<a href="#wpbody" class="return-to-top"><span aria-hidden="true">&uarr; </span> ' . __( 'Return to Top' ) . '</a>';
$content .= '</div>'; // End of .privacy-text-section. $content .= '</div>'; // End of .privacy-text-section.
} }

View File

@ -278,8 +278,8 @@ function wp_privacy_generate_personal_data_export_group_html( $group_data, $grou
} }
if ( 1 < $groups_count ) { if ( 1 < $groups_count ) {
$group_html .= '<div class="return_to_top">'; $group_html .= '<div class="return-to-top">';
$group_html .= '<a href="#top">' . esc_html__( '&uarr; Return to top' ) . '</a>'; $group_html .= '<a href="#top"><span aria-hidden="true">&uarr; </span> ' . esc_html__( 'Return to top' ) . '</a>';
$group_html .= '</div>'; $group_html .= '</div>';
} }
@ -423,7 +423,7 @@ function wp_privacy_generate_personal_data_export_file( $request_id ) {
fwrite( $file, 'th { padding: 5px; text-align: left; width: 20%; }' ); fwrite( $file, 'th { padding: 5px; text-align: left; width: 20%; }' );
fwrite( $file, 'td { padding: 5px; }' ); fwrite( $file, 'td { padding: 5px; }' );
fwrite( $file, 'tr:nth-child(odd) { background-color: #fafafa; }' ); fwrite( $file, 'tr:nth-child(odd) { background-color: #fafafa; }' );
fwrite( $file, '.return_to_top { text-align:right; }' ); fwrite( $file, '.return-to-top { text-align: right; }' );
fwrite( $file, '</style>' ); fwrite( $file, '</style>' );
fwrite( $file, '<title>' ); fwrite( $file, '<title>' );
fwrite( $file, esc_html( $title ) ); fwrite( $file, esc_html( $title ) );