Accessibility: Media: Add a "Copy URL" button to the attachment File URL fields.

For a number of years, various screens in the WordPress admin provided users with a readonly input field to copy the attachment file URL. Manually copying from a readonly field is an annoying task at best even for mouser users. It's a usability and accessibility issue at the same time. 
These fields now have a new "Copy URL" button that is easy to use and accessible to everyone.

Props theolg, markdubois, vabrashev, sajjad67, xkon, nrqsnchz, melchoyce, audrasjb, afercia.
See #41612, #50322, #50335.
Fixes #48463.

Built from https://develop.svn.wordpress.org/trunk@48232


git-svn-id: http://core.svn.wordpress.org/trunk@48001 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Andrea Fercia 2020-06-30 13:16:04 +00:00
parent 91a38c62ea
commit eebf187963
20 changed files with 219 additions and 23 deletions

View File

@ -798,6 +798,16 @@ border color while dragging a file over the uploader drop area */
text-decoration: none;
}
.copy-to-clipboard-container {
display: flex;
align-items: center;
margin-top: 8px;
clear: both;
}
.copy-to-clipboard-container .success {
margin-right: 8px;
}
/*------------------------------------------------------------------------------
14.2 - Image Editor
@ -1216,6 +1226,10 @@ audio, video {
width: auto;
max-width: none;
}
.copy-to-clipboard-container .success {
font-size: 14px;
}
}
/**

File diff suppressed because one or more lines are too long

View File

@ -797,6 +797,16 @@ border color while dragging a file over the uploader drop area */
text-decoration: none;
}
.copy-to-clipboard-container {
display: flex;
align-items: center;
margin-top: 8px;
clear: both;
}
.copy-to-clipboard-container .success {
margin-left: 8px;
}
/*------------------------------------------------------------------------------
14.2 - Image Editor
@ -1215,6 +1225,10 @@ audio, video {
width: auto;
max-width: none;
}
.copy-to-clipboard-container .success {
font-size: 14px;
}
}
/**

File diff suppressed because one or more lines are too long

View File

@ -3268,6 +3268,10 @@ function attachment_submitbox_metadata() {
<div class="misc-pub-section misc-pub-attachment">
<label for="attachment_url"><?php _e( 'File URL:' ); ?></label>
<input type="text" class="widefat urlfield" readonly="readonly" name="attachment_url" id="attachment_url" value="<?php echo esc_attr( $att_url ); ?>" />
<span class="copy-to-clipboard-container">
<button type="button" class="button copy-attachment-url edit-media" data-clipboard-target="#attachment_url"><?php _e( 'Copy URL' ); ?></button>
<span class="success hidden" aria-hidden="true"><?php _e( 'Copied!' ); ?></span>
</span>
</div>
<div class="misc-pub-section misc-pub-filename">
<?php _e( 'File name:' ); ?> <strong><?php echo $filename; ?></strong>

View File

@ -4,7 +4,7 @@
* @output wp-admin/js/post.js
*/
/* global postL10n, ajaxurl, wpAjax, setPostThumbnailL10n, postboxes, pagenow, tinymce, alert, deleteUserSetting */
/* global postL10n, ajaxurl, wpAjax, setPostThumbnailL10n, postboxes, pagenow, tinymce, alert, deleteUserSetting, ClipboardJS */
/* global theList:true, theExtraList:true, getUserSetting, setUserSetting, commentReply, commentsBox */
/* global WPSetThumbnailHTML, wptitlehint */
@ -297,7 +297,10 @@ jQuery(document).ready( function($) {
$postVisibilitySelect = $('#post-visibility-select'),
$timestampdiv = $('#timestampdiv'),
$postStatusSelect = $('#post-status-select'),
isMac = window.navigator.platform ? window.navigator.platform.indexOf( 'Mac' ) !== -1 : false;
isMac = window.navigator.platform ? window.navigator.platform.indexOf( 'Mac' ) !== -1 : false,
copyAttachmentURLClipboard = new ClipboardJS( '.copy-attachment-url.edit-media' ),
copyAttachmentURLSuccessTimeout,
__ = wp.i18n.__;
postboxes.add_postbox_toggles(pagenow);
@ -1217,7 +1220,38 @@ jQuery(document).ready( function($) {
window.history.replaceState( null, null, location );
});
}
});
/**
* Copies the attachment URL in the Edit Media page to the clipboard.
*
* @since 5.5.0
*
* @param {MouseEvent} event A click event.
*
* @returns {void}
*/
copyAttachmentURLClipboard.on( 'success', function( event ) {
var triggerElement = $( event.trigger ),
successElement = $( '.success', triggerElement.closest( '.copy-to-clipboard-container' ) );
// Clear the selection and move focus back to the trigger.
event.clearSelection();
// Handle ClipboardJS focus bug, see https://github.com/zenorocha/clipboard.js/issues/680
triggerElement.focus();
// Show success visual feedback.
clearTimeout( copyAttachmentURLSuccessTimeout );
successElement.removeClass( 'hidden' );
// Hide success visual feedback after 3 seconds since last success.
copyAttachmentURLSuccessTimeout = setTimeout( function() {
successElement.addClass( 'hidden' );
}, 3000 );
// Handle success audible feedback.
wp.a11y.speak( __( 'The file URL has been copied to your clipboard' ) );
} );
} );
/**
* TinyMCE word count display

File diff suppressed because one or more lines are too long

View File

@ -355,6 +355,11 @@ TABLE OF CONTENTS:
margin-bottom: 4px;
}
/* Copy attachment URL button in the legacy edit media page. */
.wp-core-ui .copy-to-clipboard-container .copy-attachment-url {
margin-bottom: 0;
}
#media-upload.wp-core-ui .button {
padding: 0 10px 1px;
min-height: 24px;

File diff suppressed because one or more lines are too long

View File

@ -354,6 +354,11 @@ TABLE OF CONTENTS:
margin-bottom: 4px;
}
/* Copy attachment URL button in the legacy edit media page. */
.wp-core-ui .copy-to-clipboard-container .copy-attachment-url {
margin-bottom: 0;
}
#media-upload.wp-core-ui .button {
padding: 0 10px 1px;
min-height: 24px;

File diff suppressed because one or more lines are too long

View File

@ -458,6 +458,26 @@
font-size: 12px;
}
.media-sidebar .copy-to-clipboard-container,
.attachment-details .copy-to-clipboard-container {
flex-wrap: wrap;
margin-top: 10px;
margin-right: calc( 35% - 1px );
padding-top: 10px;
}
/* Needs high specificity. */
.attachment-details .attachment-info .copy-to-clipboard-container {
float: none;
}
.media-sidebar .copy-to-clipboard-container .success,
.attachment-details .copy-to-clipboard-container .success {
padding: 0;
min-height: 0;
text-align: right;
}
.compat-item label span {
text-align: left;
}
@ -2540,6 +2560,18 @@
padding: 8px 2px 2px;
}
/* Needs high specificity. */
.media-sidebar .setting .copy-to-clipboard-container,
.attachment-details .attachment-info .copy-to-clipboard-container {
margin-right: 0;
padding-top: 0;
}
.media-sidebar .setting .copy-attachment-url,
.attachment-details .attachment-info .copy-attachment-url {
margin: 0 1px;
}
.media-sidebar .setting .value,
.attachment-details .setting .value {
float: none;
@ -2713,12 +2745,16 @@
.media-frame-toolbar .media-toolbar {
bottom: -54px;
}
}
@media screen and (max-width: 782px) {
.mode-grid .attachments-browser .media-toolbar-primary {
display: block;
}
.media-sidebar .copy-to-clipboard-container .success,
.attachment-details .copy-to-clipboard-container .success {
font-size: 14px;
line-height: 2.71428571;
}
}
/* Responsive on portrait and landscape */

File diff suppressed because one or more lines are too long

View File

@ -457,6 +457,26 @@
font-size: 12px;
}
.media-sidebar .copy-to-clipboard-container,
.attachment-details .copy-to-clipboard-container {
flex-wrap: wrap;
margin-top: 10px;
margin-left: calc( 35% - 1px );
padding-top: 10px;
}
/* Needs high specificity. */
.attachment-details .attachment-info .copy-to-clipboard-container {
float: none;
}
.media-sidebar .copy-to-clipboard-container .success,
.attachment-details .copy-to-clipboard-container .success {
padding: 0;
min-height: 0;
text-align: left;
}
.compat-item label span {
text-align: right;
}
@ -2539,6 +2559,18 @@
padding: 8px 2px 2px;
}
/* Needs high specificity. */
.media-sidebar .setting .copy-to-clipboard-container,
.attachment-details .attachment-info .copy-to-clipboard-container {
margin-left: 0;
padding-top: 0;
}
.media-sidebar .setting .copy-attachment-url,
.attachment-details .attachment-info .copy-attachment-url {
margin: 0 1px;
}
.media-sidebar .setting .value,
.attachment-details .setting .value {
float: none;
@ -2712,12 +2744,16 @@
.media-frame-toolbar .media-toolbar {
bottom: -54px;
}
}
@media screen and (max-width: 782px) {
.mode-grid .attachments-browser .media-toolbar-primary {
display: block;
}
.media-sidebar .copy-to-clipboard-container .success,
.attachment-details .copy-to-clipboard-container .success {
font-size: 14px;
line-height: 2.71428571;
}
}
/* Responsive on portrait and landscape */

File diff suppressed because one or more lines are too long

View File

@ -8994,10 +8994,12 @@ module.exports = Playlist;
/* 91 */
/***/ (function(module, exports) {
/* global ClipboardJS */
var Attachment = wp.media.view.Attachment,
l10n = wp.media.view.l10n,
$ = jQuery,
Details;
Details,
__ = wp.i18n.__;
Details = Attachment.extend(/** @lends wp.media.view.Attachment.Details.prototype */{
tagName: 'div',
@ -9022,6 +9024,42 @@ Details = Attachment.extend(/** @lends wp.media.view.Attachment.Details.prototyp
'keydown': 'toggleSelectionHandler'
},
/**
* Copies the attachment URL to the clipboard.
*
* @since 5.5.0
*
* @param {MouseEvent} event A click event.
*
* @returns {void}
*/
copyAttachmentDetailsURLClipboard: function() {
var clipboard = new ClipboardJS( '.copy-attachment-url' ),
successTimeout;
clipboard.on( 'success', function( event ) {
var triggerElement = $( event.trigger ),
successElement = $( '.success', triggerElement.closest( '.copy-to-clipboard-container' ) );
// Clear the selection and move focus back to the trigger.
event.clearSelection();
// Handle ClipboardJS focus bug, see https://github.com/zenorocha/clipboard.js/issues/680
triggerElement.focus();
// Show success visual feedback.
clearTimeout( successTimeout );
successElement.removeClass( 'hidden' );
// Hide success visual feedback after 3 seconds since last success.
successTimeout = setTimeout( function() {
successElement.addClass( 'hidden' );
}, 3000 );
// Handle success audible feedback.
wp.a11y.speak( __( 'The file URL has been copied to your clipboard' ) );
} );
},
/**
* Shows the details of an attachment.
*
@ -9039,6 +9077,8 @@ Details = Attachment.extend(/** @lends wp.media.view.Attachment.Details.prototyp
// Call 'initialize' directly on the parent class.
Attachment.prototype.initialize.apply( this, arguments );
this.copyAttachmentDetailsURLClipboard();
},
/**

File diff suppressed because one or more lines are too long

View File

@ -500,8 +500,12 @@ function wp_print_media_templates() {
</span>
<# } #>
<span class="setting" data-setting="url">
<label for="attachment-details-two-column-copy-link" class="name"><?php _e( 'Copy Link' ); ?></label>
<input type="text" id="attachment-details-two-column-copy-link" value="{{ data.url }}" readonly />
<label for="attachment-details-two-column-copy-link" class="name"><?php _e( 'File URL:' ); ?></label>
<input type="text" class="attachment-details-copy-link" id="attachment-details-two-column-copy-link" value="{{ data.url }}" readonly />
<span class="copy-to-clipboard-container">
<button type="button" class="button button-small copy-attachment-url" data-clipboard-target="#attachment-details-two-column-copy-link"><?php _e( 'Copy URL' ); ?></button>
<span class="success hidden" aria-hidden="true"><?php _e( 'Copied!' ); ?></span>
</span>
</span>
<div class="attachment-compat"></div>
</div>
@ -687,8 +691,12 @@ function wp_print_media_templates() {
<textarea id="attachment-details-description" {{ maybeReadOnly }}>{{ data.description }}</textarea>
</span>
<span class="setting" data-setting="url">
<label for="attachment-details-copy-link" class="name"><?php _e( 'Copy Link' ); ?></label>
<input type="text" id="attachment-details-copy-link" value="{{ data.url }}" readonly />
<label for="attachment-details-copy-link" class="name"><?php _e( 'File URL:' ); ?></label>
<input type="text" class="attachment-details-copy-link" id="attachment-details-copy-link" value="{{ data.url }}" readonly />
<div class="copy-to-clipboard-container">
<button type="button" class="button button-small copy-attachment-url" data-clipboard-target="#attachment-details-copy-link"><?php _e( 'Copy URL' ); ?></button>
<span class="success hidden" aria-hidden="true"><?php _e( 'Copied!' ); ?></span>
</div>
</span>
</script>

View File

@ -1232,7 +1232,7 @@ function wp_default_scripts( $scripts ) {
// To enqueue media-views or media-editor, call wp_enqueue_media().
// Both rely on numerous settings, styles, and templates to operate correctly.
$scripts->add( 'media-views', "/wp-includes/js/media-views$suffix.js", array( 'utils', 'media-models', 'wp-plupload', 'jquery-ui-sortable', 'wp-mediaelement', 'wp-api-request', 'wp-a11y', 'wp-i18n' ), false, 1 );
$scripts->add( 'media-views', "/wp-includes/js/media-views$suffix.js", array( 'utils', 'media-models', 'wp-plupload', 'jquery-ui-sortable', 'wp-mediaelement', 'wp-api-request', 'wp-a11y', 'wp-i18n', 'clipboard' ), false, 1 );
$scripts->set_translations( 'media-views' );
$scripts->add( 'media-editor', "/wp-includes/js/media-editor$suffix.js", array( 'shortcode', 'media-views' ), false, 1 );
$scripts->add( 'media-audiovideo', "/wp-includes/js/media-audiovideo$suffix.js", array( 'media-editor' ), false, 1 );
@ -1294,7 +1294,7 @@ function wp_default_scripts( $scripts ) {
)
);
$scripts->add( 'post', "/wp-admin/js/post$suffix.js", array( 'suggest', 'wp-lists', 'postbox', 'tags-box', 'underscore', 'word-count', 'wp-a11y', 'wp-sanitize' ), false, 1 );
$scripts->add( 'post', "/wp-admin/js/post$suffix.js", array( 'suggest', 'wp-lists', 'postbox', 'tags-box', 'underscore', 'word-count', 'wp-a11y', 'wp-sanitize', 'clipboard', 'wp-i18n' ), false, 1 );
did_action( 'init' ) && $scripts->localize(
'post',
'postL10n',

View File

@ -13,7 +13,7 @@
*
* @global string $wp_version
*/
$wp_version = '5.5-alpha-48231';
$wp_version = '5.5-alpha-48232';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.