diff --git a/src/js/_enqueues/admin/post.js b/src/js/_enqueues/admin/post.js index f6da847f9c..127757ede5 100644 --- a/src/js/_enqueues/admin/post.js +++ b/src/js/_enqueues/admin/post.js @@ -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 diff --git a/src/js/media/views/attachment/details.js b/src/js/media/views/attachment/details.js index b9cf51445e..f6c2726351 100644 --- a/src/js/media/views/attachment/details.js +++ b/src/js/media/views/attachment/details.js @@ -1,7 +1,9 @@ +/* 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', @@ -26,6 +28,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. * @@ -43,6 +81,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(); }, /** diff --git a/src/wp-admin/css/media.css b/src/wp-admin/css/media.css index 3857baaf01..59fd90477a 100644 --- a/src/wp-admin/css/media.css +++ b/src/wp-admin/css/media.css @@ -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; + } } /** diff --git a/src/wp-admin/includes/media.php b/src/wp-admin/includes/media.php index 24f65818e4..622b24b214 100644 --- a/src/wp-admin/includes/media.php +++ b/src/wp-admin/includes/media.php @@ -3268,6 +3268,10 @@ function attachment_submitbox_metadata() {