diff --git a/src/js/_enqueues/admin/site-icon.js b/src/js/_enqueues/admin/site-icon.js index 5b4bc28a2044f..d032d89d7ee90 100644 --- a/src/js/_enqueues/admin/site-icon.js +++ b/src/js/_enqueues/admin/site-icon.js @@ -1,15 +1,40 @@ -(function($) { - var frame; - - function calculateImageSelectOptions ( attachment ) { - var realWidth = attachment.get( 'width' ), +/** + * Handle the site icon setting in options-general.php. + * + * @since 6.5.0 + * @output wp-admin/js/site-icon.js + */ + +/* global jQuery, wp */ + +( function ( $ ) { + var $chooseButton = $( '#choose-from-library-button' ), + $iconPreview = $( '#site-icon-preview' ), + $browserIconPreview = $( '#browser-icon-preview' ), + $appIconPreview = $( '#app-icon-preview' ), + $hiddenDataField = $( '#site_icon_hidden_field' ), + $removeButton = $( '#js-remove-site-icon' ), + frame; + + /** + * Calculate image selection options based on the attachment dimensions. + * + * @since 6.5.0 + * + * @param {Object} attachment The attachment object representing the image. + * @return {Object} The image selection options. + */ + function calculateImageSelectOptions( attachment ) { + var realWidth = attachment.get( 'width' ), realHeight = attachment.get( 'height' ), xInit = 512, yInit = 512, ratio = xInit / yInit, - xImg = xInit, - yImg = yInit, - x1, y1, imgSelectOptions; + xImg = xInit, + yImg = yInit, + x1, + y1, + imgSelectOptions; if ( realWidth / realHeight > ratio ) { yInit = realHeight; @@ -35,104 +60,177 @@ x1: x1, y1: y1, x2: xInit + x1, - y2: yInit + y1 + y2: yInit + y1, }; return imgSelectOptions; } - $( function() { - // Build the choose from library frame. - $( '#choose-from-library-link' ).on( 'click', function() { - var $el = $(this); - - // Create the media frame. - frame = wp.media({ - button: { - // Set the text of the button. - text: $el.data('update'), - // Don't close, we might need to crop. - close: false - }, - states: [ - new wp.media.controller.Library({ - title: $el.data( 'choose' ), - library: wp.media.query({ type: 'image' }), - date: false, - suggestedWidth: $el.data( 'size' ), - suggestedHeight: $el.data( 'size' ) - }), - new wp.media.controller.SiteIconCropper({ - control: { - params: { - width: $el.data( 'size' ), - height: $el.data( 'size' ) - } + /** + * Initializes the media frame for selecting or cropping an image. + * + * @since 6.5.0 + */ + $chooseButton.on( 'click', function () { + var $el = $( this ); + + // Create the media frame. + frame = wp.media( { + button: { + // Set the text of the button. + text: $el.data( 'update' ), + + // Don't close, we might need to crop. + close: false, + }, + states: [ + new wp.media.controller.Library( { + title: $el.data( 'choose-text' ), + library: wp.media.query( { type: 'image' } ), + date: false, + suggestedWidth: $el.data( 'size' ), + suggestedHeight: $el.data( 'size' ), + } ), + new wp.media.controller.SiteIconCropper( { + control: { + params: { + width: $el.data( 'size' ), + height: $el.data( 'size' ), }, - imgSelectOptions: calculateImageSelectOptions - }) - ] - }); - - frame.on( 'cropped', function( attachment) { - $( '#site_icon_hidden_field' ).val(attachment.id); - switchToUpdate(attachment.url); + }, + imgSelectOptions: calculateImageSelectOptions, + } ), + ], + } ); + + frame.on( 'cropped', function ( attachment ) { + $hiddenDataField.val( attachment.id ); + switchToUpdate( attachment ); + frame.close(); + + // Start over with a frame that is so fresh and so clean clean. + frame = null; + } ); + + // When an image is selected, run a callback. + frame.on( 'select', function () { + // Grab the selected attachment. + var attachment = frame.state().get( 'selection' ).first(); + + if ( + attachment.attributes.height === $el.data( 'size' ) && + $el.data( 'size' ) === attachment.attributes.width + ) { + switchToUpdate( attachment.attributes ); frame.close(); - // Start over with a frame that is so fresh and so clean clean. - frame = null; - }); - - // When an image is selected, run a callback. - frame.on( 'select', function() { - // Grab the selected attachment. - var attachment = frame.state().get('selection').first(); - - if ( attachment.attributes.height === $el.data('size') && $el.data('size') === attachment.attributes.width ) { - // Set the value of the hidden input to the attachment id. - $( '#site_icon_hidden_field').val(attachment.id); - switchToUpdate(attachment.attributes.url); - frame.close(); - } else { - frame.setState( 'cropper' ); - } - }); - - frame.open(); - }); - }); - - function switchToUpdate( url ){ - // Set site-icon-img src to the url and remove the hidden class. - $( '#site-icon-preview').find('img').not('.browser-preview').each( function(i, img ){ - $(img).attr('src', url ); - }); - $( '#site-icon-preview' ).removeClass( 'hidden' ); - // Remove hidden class from remove. - $( '#js-remove-site-icon' ).removeClass( 'hidden' ); - // If the button is not in the update state, swap the classes. - if( $( '#choose-from-library-link' ).attr( 'data-state' ) !== '1' ){ - var classes = $( '#choose-from-library-link' ).attr( 'class' ); - $( '#choose-from-library-link' ).attr( 'class', $( '#choose-from-library-link' ).attr('data-alt-classes') ); - $( '#choose-from-library-link' ).attr( 'data-alt-classes', classes ); - $( '#choose-from-library-link' ).attr( 'data-state', '1' ); + + // Set the value of the hidden input to the attachment id. + $hiddenDataField.val( attachment.id ); + } else { + frame.setState( 'cropper' ); + } + } ); + + frame.open(); + } ); + + /** + * Update the UI when a site icon is selected. + * + * @since 6.5.0 + * + * @param {array} attributes The attributes for the attachment. + */ + function switchToUpdate( attributes ) { + var i18nAppAlternativeString, i18nBrowserAlternativeString; + + if ( attributes.alt ) { + i18nAppAlternativeString = wp.i18n.sprintf( + /* translators: %s: The selected image alt text. */ + wp.i18n.__( 'App icon preview: Current image: %s' ), + attributes.alt + ); + i18nBrowserAlternativeString = wp.i18n.sprintf( + /* translators: %s: The selected image alt text. */ + wp.i18n.__( 'Browser icon preview: Current image: %s' ), + attributes.alt + ); + } else { + i18nAppAlternativeString = wp.i18n.sprintf( + /* translators: %s: The selected image filename. */ + wp.i18n.__( + 'App icon preview: The current image has no alternative text. The file name is: %s' + ), + attributes.filename + ); + i18nBrowserAlternativeString = wp.i18n.sprintf( + /* translators: %s: The selected image filename. */ + wp.i18n.__( + 'Browser icon preview: The current image has no alternative text. The file name is: %s' + ), + attributes.filename + ); } - // swap the text of the button - $( '#choose-from-library-link' ).text( $( '#choose-from-library-link' ).attr( 'data-update-text' ) ); + // Set site-icon-img src and alternative text to app icon preview. + $appIconPreview.attr( { + src: attributes.url, + alt: i18nAppAlternativeString, + } ); + + // Set site-icon-img src and alternative text to browser preview. + $browserIconPreview.attr( { + src: attributes.url, + alt: i18nBrowserAlternativeString, + } ); + + // Remove hidden class from icon preview div and remove button. + $iconPreview.removeClass( 'hidden' ); + $removeButton.removeClass( 'hidden' ); + + // If the choose button is not in the update state, swap the classes. + if ( $chooseButton.attr( 'data-state' ) !== '1' ) { + $chooseButton.attr( { + class: $chooseButton.attr( 'data-alt-classes' ), + 'data-alt-classes': $chooseButton.attr( 'class' ), + 'data-state': '1', + } ); + } + + // Swap the text of the choose button. + $chooseButton.text( $chooseButton.attr( 'data-update-text' ) ); } - $( '#js-remove-site-icon' ).on( 'click', function() { - $( '#site_icon_hidden_field' ).val( 'false' ); - $( '#site-icon-preview' ).toggleClass( 'hidden' ); + /** + * Handles the click event of the remove button. + * + * @since 6.5.0 + */ + $removeButton.on( 'click', function () { + $hiddenDataField.val( 'false' ); $( this ).toggleClass( 'hidden' ); - - var classes = $( '#choose-from-library-link' ).attr( 'class' ); - $( '#choose-from-library-link' ).attr( 'class', $( '#choose-from-library-link' ).attr( 'data-alt-classes' ) ); - $( '#choose-from-library-link' ).attr( 'data-alt-classes', classes ); - - // Swap the text of the button. - $( '#choose-from-library-link' ).text( $( '#choose-from-library-link' ).attr( 'data-choose-text' ) ); - // Set the state of the button so it can be changed on new icon. - $( '#choose-from-library-link' ).attr( 'data-state', ''); - }); -}(jQuery)); + $iconPreview.toggleClass( 'hidden' ); + $browserIconPreview.attr( { + src: '', + alt: '', + } ); + $appIconPreview.attr( { + src: '', + alt: '', + } ); + + /** + * Resets state to the button, for correct visual style and state. + * Updates the text of the button. + * Sets focus state to the button. + */ + $chooseButton + .attr( { + class: $chooseButton.attr( 'data-alt-classes' ), + 'data-alt-classes': $chooseButton.attr( 'class' ), + 'data-state': '', + } ) + .text( $chooseButton.attr( 'data-choose-text' ) ) + .trigger( 'focus' ); + } ); +} )( jQuery ); diff --git a/src/wp-admin/css/forms.css b/src/wp-admin/css/forms.css index db76d6cb05e7a..63eb3e88eb6ee 100644 --- a/src/wp-admin/css/forms.css +++ b/src/wp-admin/css/forms.css @@ -789,7 +789,7 @@ ul#add-to-blog-users { outline: 2px solid transparent; } -.button-add-site-icon{ +.button-add-site-icon { width: 100%; cursor: pointer; text-align: center; @@ -801,23 +801,23 @@ ul#add-to-blog-users { } .button-add-site-icon:focus, -.button-add-site-icon:hover{ - background: white; +.button-add-site-icon:hover { + background: #fff; } -.site-icon-section .favicon-preview{ +.site-icon-section .favicon-preview { float: left; } -.site-icon-section .app-icon-preview{ +.site-icon-section .app-icon-preview { float: left; margin: 0 20px; } -.site-icon-section .site-icon-preview img{ +.site-icon-section .site-icon-preview img { max-width: 100%; } -.button-ad-site-icon:focus{ +.button-add-site-icon:focus { background-color: #fff; border-color: #3582c4; border-style: solid; diff --git a/src/wp-admin/css/site-icon.css b/src/wp-admin/css/site-icon.css index 5660e9a39e81c..7c7b32fe58aae 100644 --- a/src/wp-admin/css/site-icon.css +++ b/src/wp-admin/css/site-icon.css @@ -7,7 +7,6 @@ overflow: hidden; position: relative; max-width: 180px; - float: left; } .site-icon-preview .favicon, diff --git a/src/wp-admin/includes/options.php b/src/wp-admin/includes/options.php index 816313ce83379..2ede58cfa3554 100644 --- a/src/wp-admin/includes/options.php +++ b/src/wp-admin/includes/options.php @@ -36,6 +36,7 @@ function options_general_add_js() {