Changeset 57713
- Timestamp:
- 02/26/2024 08:16:09 PM (2 months ago)
- Location:
- trunk/src
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/js/_enqueues/admin/site-icon.js
r57602 r57713 1 (function($) { 2 var frame; 3 4 function calculateImageSelectOptions ( attachment ) { 5 var realWidth = attachment.get( 'width' ), 1 /** 2 * Handle the site icon setting in options-general.php. 3 * 4 * @since 6.5.0 5 * @output wp-admin/js/site-icon.js 6 */ 7 8 /* global jQuery, wp */ 9 10 ( function ( $ ) { 11 var $chooseButton = $( '#choose-from-library-button' ), 12 $iconPreview = $( '#site-icon-preview' ), 13 $browserIconPreview = $( '#browser-icon-preview' ), 14 $appIconPreview = $( '#app-icon-preview' ), 15 $hiddenDataField = $( '#site_icon_hidden_field' ), 16 $removeButton = $( '#js-remove-site-icon' ), 17 frame; 18 19 /** 20 * Calculate image selection options based on the attachment dimensions. 21 * 22 * @since 6.5.0 23 * 24 * @param {Object} attachment The attachment object representing the image. 25 * @return {Object} The image selection options. 26 */ 27 function calculateImageSelectOptions( attachment ) { 28 var realWidth = attachment.get( 'width' ), 6 29 realHeight = attachment.get( 'height' ), 7 30 xInit = 512, 8 31 yInit = 512, 9 32 ratio = xInit / yInit, 10 xImg = xInit, 11 yImg = yInit, 12 x1, y1, imgSelectOptions; 33 xImg = xInit, 34 yImg = yInit, 35 x1, 36 y1, 37 imgSelectOptions; 13 38 14 39 if ( realWidth / realHeight > ratio ) { … … 36 61 y1: y1, 37 62 x2: xInit + x1, 38 y2: yInit + y1 63 y2: yInit + y1, 39 64 }; 40 65 … … 42 67 } 43 68 44 $( function() { 45 // Build the choose from library frame. 46 $( '#choose-from-library-link' ).on( 'click', function() { 47 var $el = $(this); 48 49 // Create the media frame. 50 frame = wp.media({ 51 button: { 52 // Set the text of the button. 53 text: $el.data('update'), 54 // Don't close, we might need to crop. 55 close: false 56 }, 57 states: [ 58 new wp.media.controller.Library({ 59 title: $el.data( 'choose' ), 60 library: wp.media.query({ type: 'image' }), 61 date: false, 62 suggestedWidth: $el.data( 'size' ), 63 suggestedHeight: $el.data( 'size' ) 64 }), 65 new wp.media.controller.SiteIconCropper({ 66 control: { 67 params: { 68 width: $el.data( 'size' ), 69 height: $el.data( 'size' ) 70 } 69 /** 70 * Initializes the media frame for selecting or cropping an image. 71 * 72 * @since 6.5.0 73 */ 74 $chooseButton.on( 'click', function () { 75 var $el = $( this ); 76 77 // Create the media frame. 78 frame = wp.media( { 79 button: { 80 // Set the text of the button. 81 text: $el.data( 'update' ), 82 83 // Don't close, we might need to crop. 84 close: false, 85 }, 86 states: [ 87 new wp.media.controller.Library( { 88 title: $el.data( 'choose-text' ), 89 library: wp.media.query( { type: 'image' } ), 90 date: false, 91 suggestedWidth: $el.data( 'size' ), 92 suggestedHeight: $el.data( 'size' ), 93 } ), 94 new wp.media.controller.SiteIconCropper( { 95 control: { 96 params: { 97 width: $el.data( 'size' ), 98 height: $el.data( 'size' ), 71 99 }, 72 imgSelectOptions: calculateImageSelectOptions 73 }) 74 ] 75 }); 76 77 frame.on( 'cropped', function( attachment) { 78 $( '#site_icon_hidden_field' ).val(attachment.id); 79 switchToUpdate(attachment.url); 100 }, 101 imgSelectOptions: calculateImageSelectOptions, 102 } ), 103 ], 104 } ); 105 106 frame.on( 'cropped', function ( attachment ) { 107 $hiddenDataField.val( attachment.id ); 108 switchToUpdate( attachment ); 109 frame.close(); 110 111 // Start over with a frame that is so fresh and so clean clean. 112 frame = null; 113 } ); 114 115 // When an image is selected, run a callback. 116 frame.on( 'select', function () { 117 // Grab the selected attachment. 118 var attachment = frame.state().get( 'selection' ).first(); 119 120 if ( 121 attachment.attributes.height === $el.data( 'size' ) && 122 $el.data( 'size' ) === attachment.attributes.width 123 ) { 124 switchToUpdate( attachment.attributes ); 80 125 frame.close(); 81 // Start over with a frame that is so fresh and so clean clean. 82 frame = null; 83 }); 84 85 // When an image is selected, run a callback. 86 frame.on( 'select', function() { 87 // Grab the selected attachment. 88 var attachment = frame.state().get('selection').first(); 89 90 if ( attachment.attributes.height === $el.data('size') && $el.data('size') === attachment.attributes.width ) { 91 // Set the value of the hidden input to the attachment id. 92 $( '#site_icon_hidden_field').val(attachment.id); 93 switchToUpdate(attachment.attributes.url); 94 frame.close(); 95 } else { 96 frame.setState( 'cropper' ); 97 } 98 }); 99 100 frame.open(); 101 }); 102 }); 103 104 function switchToUpdate( url ){ 105 // Set site-icon-img src to the url and remove the hidden class. 106 $( '#site-icon-preview').find('img').not('.browser-preview').each( function(i, img ){ 107 $(img).attr('src', url ); 108 }); 109 $( '#site-icon-preview' ).removeClass( 'hidden' ); 110 // Remove hidden class from remove. 111 $( '#js-remove-site-icon' ).removeClass( 'hidden' ); 112 // If the button is not in the update state, swap the classes. 113 if( $( '#choose-from-library-link' ).attr( 'data-state' ) !== '1' ){ 114 var classes = $( '#choose-from-library-link' ).attr( 'class' ); 115 $( '#choose-from-library-link' ).attr( 'class', $( '#choose-from-library-link' ).attr('data-alt-classes') ); 116 $( '#choose-from-library-link' ).attr( 'data-alt-classes', classes ); 117 $( '#choose-from-library-link' ).attr( 'data-state', '1' ); 126 127 // Set the value of the hidden input to the attachment id. 128 $hiddenDataField.val( attachment.id ); 129 } else { 130 frame.setState( 'cropper' ); 131 } 132 } ); 133 134 frame.open(); 135 } ); 136 137 /** 138 * Update the UI when a site icon is selected. 139 * 140 * @since 6.5.0 141 * 142 * @param {array} attributes The attributes for the attachment. 143 */ 144 function switchToUpdate( attributes ) { 145 var i18nAppAlternativeString, i18nBrowserAlternativeString; 146 147 if ( attributes.alt ) { 148 i18nAppAlternativeString = wp.i18n.sprintf( 149 /* translators: %s: The selected image alt text. */ 150 wp.i18n.__( 'App icon preview: Current image: %s' ), 151 attributes.alt 152 ); 153 i18nBrowserAlternativeString = wp.i18n.sprintf( 154 /* translators: %s: The selected image alt text. */ 155 wp.i18n.__( 'Browser icon preview: Current image: %s' ), 156 attributes.alt 157 ); 158 } else { 159 i18nAppAlternativeString = wp.i18n.sprintf( 160 /* translators: %s: The selected image filename. */ 161 wp.i18n.__( 162 'App icon preview: The current image has no alternative text. The file name is: %s' 163 ), 164 attributes.filename 165 ); 166 i18nBrowserAlternativeString = wp.i18n.sprintf( 167 /* translators: %s: The selected image filename. */ 168 wp.i18n.__( 169 'Browser icon preview: The current image has no alternative text. The file name is: %s' 170 ), 171 attributes.filename 172 ); 118 173 } 119 174 120 // swap the text of the button 121 $( '#choose-from-library-link' ).text( $( '#choose-from-library-link' ).attr( 'data-update-text' ) ); 175 // Set site-icon-img src and alternative text to app icon preview. 176 $appIconPreview.attr( { 177 src: attributes.url, 178 alt: i18nAppAlternativeString, 179 } ); 180 181 // Set site-icon-img src and alternative text to browser preview. 182 $browserIconPreview.attr( { 183 src: attributes.url, 184 alt: i18nBrowserAlternativeString, 185 } ); 186 187 // Remove hidden class from icon preview div and remove button. 188 $iconPreview.removeClass( 'hidden' ); 189 $removeButton.removeClass( 'hidden' ); 190 191 // If the choose button is not in the update state, swap the classes. 192 if ( $chooseButton.attr( 'data-state' ) !== '1' ) { 193 $chooseButton.attr( { 194 class: $chooseButton.attr( 'data-alt-classes' ), 195 'data-alt-classes': $chooseButton.attr( 'class' ), 196 'data-state': '1', 197 } ); 198 } 199 200 // Swap the text of the choose button. 201 $chooseButton.text( $chooseButton.attr( 'data-update-text' ) ); 122 202 } 123 203 124 $( '#js-remove-site-icon' ).on( 'click', function() { 125 $( '#site_icon_hidden_field' ).val( 'false' ); 126 $( '#site-icon-preview' ).toggleClass( 'hidden' ); 204 /** 205 * Handles the click event of the remove button. 206 * 207 * @since 6.5.0 208 */ 209 $removeButton.on( 'click', function () { 210 $hiddenDataField.val( 'false' ); 127 211 $( this ).toggleClass( 'hidden' ); 128 129 var classes = $( '#choose-from-library-link' ).attr( 'class' ); 130 $( '#choose-from-library-link' ).attr( 'class', $( '#choose-from-library-link' ).attr( 'data-alt-classes' ) ); 131 $( '#choose-from-library-link' ).attr( 'data-alt-classes', classes ); 132 133 // Swap the text of the button. 134 $( '#choose-from-library-link' ).text( $( '#choose-from-library-link' ).attr( 'data-choose-text' ) ); 135 // Set the state of the button so it can be changed on new icon. 136 $( '#choose-from-library-link' ).attr( 'data-state', ''); 137 }); 138 }(jQuery)); 212 $iconPreview.toggleClass( 'hidden' ); 213 $browserIconPreview.attr( { 214 src: '', 215 alt: '', 216 } ); 217 $appIconPreview.attr( { 218 src: '', 219 alt: '', 220 } ); 221 222 /** 223 * Resets state to the button, for correct visual style and state. 224 * Updates the text of the button. 225 * Sets focus state to the button. 226 */ 227 $chooseButton 228 .attr( { 229 class: $chooseButton.attr( 'data-alt-classes' ), 230 'data-alt-classes': $chooseButton.attr( 'class' ), 231 'data-state': '', 232 } ) 233 .text( $chooseButton.attr( 'data-choose-text' ) ) 234 .trigger( 'focus' ); 235 } ); 236 } )( jQuery ); -
trunk/src/wp-admin/css/forms.css
r57602 r57713 790 790 } 791 791 792 .button-add-site-icon {792 .button-add-site-icon { 793 793 width: 100%; 794 794 cursor: pointer; … … 802 802 803 803 .button-add-site-icon:focus, 804 .button-add-site-icon:hover {805 background: white;806 } 807 808 .site-icon-section .favicon-preview {804 .button-add-site-icon:hover { 805 background: #fff; 806 } 807 808 .site-icon-section .favicon-preview { 809 809 float: left; 810 810 } 811 .site-icon-section .app-icon-preview {811 .site-icon-section .app-icon-preview { 812 812 float: left; 813 813 margin: 0 20px; 814 814 } 815 815 816 .site-icon-section .site-icon-preview img {816 .site-icon-section .site-icon-preview img { 817 817 max-width: 100%; 818 818 } 819 819 820 .button-ad -site-icon:focus{820 .button-add-site-icon:focus { 821 821 background-color: #fff; 822 822 border-color: #3582c4; -
trunk/src/wp-admin/css/site-icon.css
r57618 r57713 8 8 position: relative; 9 9 max-width: 180px; 10 float: left;11 10 } 12 11 -
trunk/src/wp-admin/includes/options.php
r56176 r57713 37 37 jQuery( function($) { 38 38 var $siteName = $( '#wp-admin-bar-site-name' ).children( 'a' ).first(), 39 $siteIconPreview = $('#site-icon-preview-site-title'), 39 40 homeURL = ( <?php echo wp_json_encode( get_home_url() ); ?> || '' ).replace( /^(https?:\/\/)?(www\.)?/, '' ); 40 41 … … 48 49 49 50 $siteName.text( title ); 51 $siteIconPreview.text( title ); 50 52 }); 51 53 -
trunk/src/wp-admin/options-general.php
r57618 r57713 108 108 $classes_for_upload_button = 'upload-button button-add-media button-add-site-icon'; 109 109 $classes_for_update_button = 'button'; 110 111 $classes_for_avatar = 'avatar avatar-150'; 110 $classes_for_wrapper = ''; 111 112 112 if ( has_site_icon() ) { 113 $classes_for_ avatar.= ' has-site-icon';113 $classes_for_wrapper .= ' has-site-icon'; 114 114 $classes_for_button = $classes_for_update_button; 115 115 $classes_for_button_on_change = $classes_for_upload_button; 116 116 } else { 117 $classes_for_ avatar.= ' hidden';117 $classes_for_wrapper .= ' hidden'; 118 118 $classes_for_button = $classes_for_upload_button; 119 119 $classes_for_button_on_change = $classes_for_update_button; 120 120 } 121 121 122 123 ?> 124 <div id="site-icon-preview" class="site-icon-preview wp-clearfix <?php echo esc_attr( $classes_for_avatar ); ?>"> 122 // Handle alt text for site icon on page load. 123 $site_icon_id = (int) get_option( 'site_icon' ); 124 $app_icon_alt_value = ''; 125 $browser_icon_alt_value = ''; 126 127 if ( $site_icon_id ) { 128 $img_alt = get_post_meta( $site_icon_id, '_wp_attachment_image_alt', true ); 129 $filename = wp_basename( get_site_icon_url() ); 130 $app_icon_alt_value = sprintf( 131 /* translators: %s: The selected image filename. */ 132 __( 'App icon preview: The current image has no alternative text. The file name is: %s' ), 133 $filename 134 ); 135 136 $browser_icon_alt_value = sprintf( 137 /* translators: %s: The selected image filename. */ 138 __( 'Browser icon preview: The current image has no alternative text. The file name is: %s' ), 139 $filename 140 ); 141 142 if ( $img_alt ) { 143 $app_icon_alt_value = sprintf( 144 /* translators: %s: The selected image alt text. */ 145 __( 'App icon preview: Current image: %s' ), 146 $img_alt 147 ); 148 149 $browser_icon_alt_value = sprintf( 150 /* translators: %s: The selected image alt text. */ 151 __( 'Browser icon preview: Current image: %s' ), 152 $img_alt 153 ); 154 } 155 } 156 ?> 157 158 159 <div id="site-icon-preview" class="site-icon-preview wp-clearfix settings-page-preview <?php echo esc_attr( $classes_for_wrapper ); ?>"> 125 160 <div class="favicon-preview"> 126 161 <img src="<?php echo esc_url( admin_url( 'images/' . ( is_rtl() ? 'browser-rtl.png' : 'browser.png' ) ) ); ?>" class="browser-preview" width="182" alt=""> 127 162 <div class="favicon"> 128 <img src="<?php site_icon_url(); ?>" alt="<?php esc_attr_e( 'Preview as a browser icon'); ?>">163 <img id="browser-icon-preview" src="<?php site_icon_url(); ?>" alt="<?php echo esc_attr( $browser_icon_alt_value ); ?>"> 129 164 </div> 130 <span class="browser-title" aria-hidden="true"><?php echo get_bloginfo( 'name' ); ?></span>165 <span id="site-icon-preview-site-title" class="browser-title" aria-hidden="true"><?php bloginfo( 'name' ); ?></span> 131 166 </div> 132 <img class="app-icon-preview" src="<?php site_icon_url(); ?>" alt="<?php esc_attr_e( 'Preview as an app icon'); ?>">167 <img id="app-icon-preview" class="app-icon-preview" src="<?php site_icon_url(); ?>" alt="<?php echo esc_attr( $app_icon_alt_value ); ?>"> 133 168 </div> 169 134 170 <input type="hidden" name="site_icon" id="site_icon_hidden_field" value="<?php form_option( 'site_icon' ); ?>" /> 135 171 <div class="action-buttons"> 136 172 <button type="button" 137 id="choose-from-library- link"173 id="choose-from-library-button" 138 174 type="button" 139 175 class="<?php echo esc_attr( $classes_for_button ); ?>" … … 162 198 163 199 <p class="description"> 164 <?php _e( 'Site Icons are what you see in browser tabs, bookmark bars, and within the WordPress mobile apps. Upload one here!' ); ?>165 </p>166 <p class="description">167 200 <?php 168 201 /* translators: %s: Site Icon size in pixels. */ 169 printf( __( 'Site Icons should be square and at least %s pixels.' ), '<strong>512 × 512</strong>' );202 printf( __( 'Site Icons are what you see in browser tabs, bookmark bars, and within the WordPress mobile apps. They should be square and at least %s pixels.' ), '<code>512 × 512</code>' ); 170 203 ?> 171 204 </p> -
trunk/src/wp-includes/script-loader.php
r57699 r57713 850 850 $scripts->add( 'wp-lists', "/wp-includes/js/wp-lists$suffix.js", array( 'wp-ajax-response', 'jquery-color' ), false, 1 ); 851 851 852 $scripts->add( 'site-icon', '/wp-admin/js/site-icon.js', array( 'jquery', 'jcrop' ), false, 1 ); 852 $scripts->add( 'site-icon', '/wp-admin/js/site-icon.js', array( 'jquery' ), false, 1 ); 853 $scripts->set_translations( 'site-icon' ); 853 854 854 855 // WordPress no longer uses or bundles Prototype or script.aculo.us. These are now pulled from an external source.
Note: See TracChangeset
for help on using the changeset viewer.