From d5df031e6f999e04750f3417656dd461a0b283d0 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Sun, 12 Apr 2020 14:24:38 +0000 Subject: [PATCH] Privacy: Add an indication when the Copy action in Privacy Policy Guide is complete. This adds a "Copied!" text near the "Copy this section to clipboard" button to provide direct feedback that the action was completed. Props garrett-eclipse, nickylimjj, xkon, desrosj, birgire. Fixes #44588. git-svn-id: https://develop.svn.wordpress.org/trunk@47572 602fd350-edb4-49c9-b593-d223f7449a82 --- src/js/_enqueues/admin/privacy-tools.js | 23 ++++++++++-- src/wp-admin/css/edit.css | 12 +++++++ .../class-wp-privacy-policy-content.php | 36 +++++++++---------- src/wp-includes/script-loader.php | 2 +- 4 files changed, 50 insertions(+), 23 deletions(-) diff --git a/src/js/_enqueues/admin/privacy-tools.js b/src/js/_enqueues/admin/privacy-tools.js index d00d5d1573..7d91e50044 100644 --- a/src/js/_enqueues/admin/privacy-tools.js +++ b/src/js/_enqueues/admin/privacy-tools.js @@ -259,10 +259,14 @@ jQuery( document ).ready( function( $ ) { doNextErasure( 1, 1 ); }); - // Privacy policy page, copy button. + // Privacy Policy page, copy action. $( document ).on( 'click', function( event ) { - var $target = $( event.target ); - var $parent, $container, range; + var $parent, + $container, + range, + __ = wp.i18n.__, + $target = $( event.target ), + copiedNotice = $target.siblings( '.success' ); if ( $target.is( 'button.privacy-text-copy' ) ) { $parent = $target.parent().parent(); @@ -277,22 +281,35 @@ jQuery( document ).ready( function( $ ) { var documentPosition = document.documentElement.scrollTop, bodyPosition = document.body.scrollTop; + // Setup copy. window.getSelection().removeAllRanges(); + + // Hide tutorial content to remove from copied content. range = document.createRange(); $container.addClass( 'hide-privacy-policy-tutorial' ); + // Copy action. range.selectNodeContents( $container[0] ); window.getSelection().addRange( range ); document.execCommand( 'copy' ); + // Reset section. $container.removeClass( 'hide-privacy-policy-tutorial' ); window.getSelection().removeAllRanges(); + // Return scroll position - see #49540. if ( documentPosition > 0 && documentPosition !== document.documentElement.scrollTop ) { document.documentElement.scrollTop = documentPosition; } else if ( bodyPosition > 0 && bodyPosition !== document.body.scrollTop ) { document.body.scrollTop = bodyPosition; } + + // Display and speak notice to indicate action complete. + copiedNotice.addClass( 'visible' ); + wp.a11y.speak( __( 'The section has been copied to your clipboard.' ) ); + + // Delay notice dismissal. + setTimeout( function(){ copiedNotice.removeClass( 'visible' ); }, 3000 ); } catch ( er ) {} } } diff --git a/src/wp-admin/css/edit.css b/src/wp-admin/css/edit.css index 7e0beb356a..1c2b3336ca 100644 --- a/src/wp-admin/css/edit.css +++ b/src/wp-admin/css/edit.css @@ -728,6 +728,18 @@ form#tags-filter { padding-bottom: 6px; } +.privacy-text-actions .success { + display: none; + color: #40860a; + float: right; + padding-right: 1em; +} + +.privacy-text-actions .success.visible { + display: inline-block; + height: 32px; +} + .wp-privacy-policy-guide .policy-text h2 { margin: 1.2em 0 1em; padding: 0; diff --git a/src/wp-admin/includes/class-wp-privacy-policy-content.php b/src/wp-admin/includes/class-wp-privacy-policy-content.php index c252bdebb6..3dd728cb52 100644 --- a/src/wp-admin/includes/class-wp-privacy-policy-content.php +++ b/src/wp-admin/includes/class-wp-privacy-policy-content.php @@ -372,12 +372,9 @@ final class WP_Privacy_Policy_Content { public static function privacy_policy_guide() { $content_array = self::get_suggested_policy_text(); - $content = ''; $toc = array( '
  • ' . __( 'Introduction' ) . '
  • ' ); $date_format = __( 'F j, Y' ); - $copy = __( 'Copy this section to clipboard' ); - $return_to_top = '' . __( '↑ Return to Top' ) . ''; foreach ( $content_array as $section ) { $class = ''; @@ -385,7 +382,7 @@ final class WP_Privacy_Policy_Content { $removed = ''; if ( ! empty( $section['removed'] ) ) { - $class = ' text-removed'; + $class = 'text-removed'; $date = date_i18n( $date_format, $section['removed'] ); /* translators: %s: Date of plugin deactivation. */ $meta = sprintf( __( 'Removed %s.' ), $date ); @@ -394,7 +391,7 @@ final class WP_Privacy_Policy_Content { $removed = __( 'You deactivated this plugin on %s and may no longer need this policy.' ); $removed = '

    ' . sprintf( $removed, $date ) . '

    '; } elseif ( ! empty( $section['updated'] ) ) { - $class = ' text-updated'; + $class = 'text-updated'; $date = date_i18n( $date_format, $section['updated'] ); /* translators: %s: Date of privacy policy text update. */ $meta = sprintf( __( 'Updated %s.' ), $date ); @@ -408,36 +405,37 @@ final class WP_Privacy_Policy_Content { $toc_id = 'wp-privacy-policy-guide-' . sanitize_title( $plugin_name ); $toc[] = sprintf( '
  • %2$s' . $meta . '
  • ', $toc_id, $plugin_name ); - $content .= '
    '; + $content .= '
    '; $content .= ' '; /* translators: %s: Plugin name. */ $content .= '

    ' . sprintf( __( 'Source: %s' ), $plugin_name ) . '

    '; $content .= $removed; $content .= '
    ' . $section['policy_text'] . '
    '; - $content .= $return_to_top; + $content .= '' . __( '↑ Return to Top' ) . ''; if ( empty( $section['removed'] ) ) { - $content .= '
    '; - $content .= ''; - $content .= '
    '; + $content .= '
    '; + $content .= ''; + $content .= ''; + $content .= '
    '; } - $content .= "
    \n"; // End of .privacy-text-section. + $content .= '
    '; // End of .privacy-text-section. } if ( count( $toc ) > 2 ) { ?> -
    +

      - +
    add( 'site-health', "/wp-admin/js/site-health$suffix.js", array( 'clipboard', 'jquery', 'wp-util', 'wp-a11y', 'wp-i18n' ), false, 1 ); $scripts->set_translations( 'site-health' ); - $scripts->add( 'privacy-tools', "/wp-admin/js/privacy-tools$suffix.js", array( 'jquery' ), false, 1 ); + $scripts->add( 'privacy-tools', "/wp-admin/js/privacy-tools$suffix.js", array( 'jquery', 'wp-a11y', 'wp-i18n' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'privacy-tools', 'privacyToolsL10n',