General: Add an option to configure the site icon in general settings.

This restores the site icon setting to its original home on the settings page where it lives with the title and tagline.

The base for this code was originally added in [32994] and then removed in [33329]. The majority of the modification to that version are to remove the no-js pieces and make the workflow completely inline rather than putting the cropping on a separate page.

Additionally, since image crops rely on the ability to upload an image, this setting is gated by the `upload_files` capability.

Follow-up to: [32994], [33329].

Props jorbin, audrasjb, mukesh27, joedolson, afercia, kebbet, swissspidy, obenland, jameskoster, kjellr, andraganescu, stacimc, mikeschroder, h71, krupajnanda, huzaifaalmesbah.
Fixes #54370.
See #16434.


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


git-svn-id: http://core.svn.wordpress.org/trunk@57103 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Aaron Jorbin 2024-02-12 21:57:09 +00:00
parent bc39cfc822
commit d080076580
18 changed files with 356 additions and 8 deletions

View File

@ -790,6 +790,42 @@ ul#add-to-blog-users {
outline: 2px solid transparent;
}
.button-add-site-icon{
width: 100%;
cursor: pointer;
text-align: center;
border: 1px dashed #c3c4c7;
box-sizing: border-box;
padding: 9px 0;
line-height: 1.6;
max-width: 270px;
}
.button-add-site-icon:focus,
.button-add-site-icon:hover{
background: white;
}
.site-icon-section .favicon-preview{
float: right;
}
.site-icon-section .app-icon-preview{
float: right;
margin: 0 20px;
}
.site-icon-section .site-icon-preview img{
max-width: 100%;
}
.button-ad-site-icon:focus{
background-color: #fff;
border-color: #3582c4;
border-style: solid;
box-shadow: 0 0 0 1px #3582c4;
outline: 2px solid transparent;
}
/*------------------------------------------------------------------------------
15.0 - Comments Screen
------------------------------------------------------------------------------*/

File diff suppressed because one or more lines are too long

View File

@ -789,6 +789,42 @@ ul#add-to-blog-users {
outline: 2px solid transparent;
}
.button-add-site-icon{
width: 100%;
cursor: pointer;
text-align: center;
border: 1px dashed #c3c4c7;
box-sizing: border-box;
padding: 9px 0;
line-height: 1.6;
max-width: 270px;
}
.button-add-site-icon:focus,
.button-add-site-icon:hover{
background: white;
}
.site-icon-section .favicon-preview{
float: left;
}
.site-icon-section .app-icon-preview{
float: left;
margin: 0 20px;
}
.site-icon-section .site-icon-preview img{
max-width: 100%;
}
.button-ad-site-icon:focus{
background-color: #fff;
border-color: #3582c4;
border-style: solid;
box-shadow: 0 0 0 1px #3582c4;
outline: 2px solid transparent;
}
/*------------------------------------------------------------------------------
15.0 - Comments Screen
------------------------------------------------------------------------------*/

File diff suppressed because one or more lines are too long

View File

@ -8,6 +8,7 @@
overflow: hidden;
position: relative;
max-width: 180px;
float: right;
}
.site-icon-preview .favicon,
@ -53,3 +54,20 @@
.customize-control-site_icon .app-icon-preview {
margin-top: 9px;
}
.site-icon-section button.reset {
color: #b32d2e;
text-decoration: none;
border-color: transparent;
box-shadow: none;
background: transparent;
margin: 0 10px;
}
.site-icon-section button.reset:focus,
.site-icon-section button.reset:hover {
background: #b32d2e;
color: #fff;
border-color: #b32d2e;
box-shadow: 0 0 0 1px #b32d2e;
}

View File

@ -1,2 +1,2 @@
/*! This file is auto-generated */
.site-icon-preview .favicon-preview{margin:5px 0 20px;overflow:hidden;position:relative;max-width:180px}.site-icon-preview .browser-title,.site-icon-preview .favicon{height:16px;right:88px;overflow:hidden;position:absolute;top:16px}.site-icon-preview .favicon{width:16px}.site-icon-preview .browser-title{right:109px;width:72px;white-space:nowrap}.site-icon-preview .app-icon-preview{background-color:#000;border-radius:16px;height:64px;overflow:hidden;width:64px;margin-top:5px}.site-icon-preview .app-icon-preview,.site-icon-preview .favicon{direction:ltr}.customize-control-site_icon .favicon-preview{float:right;margin-left:12px;margin-bottom:0}.customize-control-site_icon .app-icon-preview{margin-top:9px}
.site-icon-preview .favicon-preview{margin:5px 0 20px;overflow:hidden;position:relative;max-width:180px;float:right}.site-icon-preview .browser-title,.site-icon-preview .favicon{height:16px;right:88px;overflow:hidden;position:absolute;top:16px}.site-icon-preview .favicon{width:16px}.site-icon-preview .browser-title{right:109px;width:72px;white-space:nowrap}.site-icon-preview .app-icon-preview{background-color:#000;border-radius:16px;height:64px;overflow:hidden;width:64px;margin-top:5px}.site-icon-preview .app-icon-preview,.site-icon-preview .favicon{direction:ltr}.customize-control-site_icon .favicon-preview{float:right;margin-left:12px;margin-bottom:0}.customize-control-site_icon .app-icon-preview{margin-top:9px}.site-icon-section button.reset{color:#b32d2e;text-decoration:none;border-color:transparent;box-shadow:none;background:0 0;margin:0 10px}.site-icon-section button.reset:focus,.site-icon-section button.reset:hover{background:#b32d2e;color:#fff;border-color:#b32d2e;box-shadow:0 0 0 1px #b32d2e}

View File

@ -7,6 +7,7 @@
overflow: hidden;
position: relative;
max-width: 180px;
float: left;
}
.site-icon-preview .favicon,
@ -52,3 +53,20 @@
.customize-control-site_icon .app-icon-preview {
margin-top: 9px;
}
.site-icon-section button.reset {
color: #b32d2e;
text-decoration: none;
border-color: transparent;
box-shadow: none;
background: transparent;
margin: 0 10px;
}
.site-icon-section button.reset:focus,
.site-icon-section button.reset:hover {
background: #b32d2e;
color: #fff;
border-color: #b32d2e;
box-shadow: 0 0 0 1px #b32d2e;
}

View File

@ -1,2 +1,2 @@
/*! This file is auto-generated */
.site-icon-preview .favicon-preview{margin:5px 0 20px;overflow:hidden;position:relative;max-width:180px}.site-icon-preview .browser-title,.site-icon-preview .favicon{height:16px;left:88px;overflow:hidden;position:absolute;top:16px}.site-icon-preview .favicon{width:16px}.site-icon-preview .browser-title{left:109px;width:72px;white-space:nowrap}.site-icon-preview .app-icon-preview{background-color:#000;border-radius:16px;height:64px;overflow:hidden;width:64px;margin-top:5px}.site-icon-preview .app-icon-preview,.site-icon-preview .favicon{direction:ltr}.customize-control-site_icon .favicon-preview{float:left;margin-right:12px;margin-bottom:0}.customize-control-site_icon .app-icon-preview{margin-top:9px}
.site-icon-preview .favicon-preview{margin:5px 0 20px;overflow:hidden;position:relative;max-width:180px;float:left}.site-icon-preview .browser-title,.site-icon-preview .favicon{height:16px;left:88px;overflow:hidden;position:absolute;top:16px}.site-icon-preview .favicon{width:16px}.site-icon-preview .browser-title{left:109px;width:72px;white-space:nowrap}.site-icon-preview .app-icon-preview{background-color:#000;border-radius:16px;height:64px;overflow:hidden;width:64px;margin-top:5px}.site-icon-preview .app-icon-preview,.site-icon-preview .favicon{direction:ltr}.customize-control-site_icon .favicon-preview{float:left;margin-right:12px;margin-bottom:0}.customize-control-site_icon .app-icon-preview{margin-top:9px}.site-icon-section button.reset{color:#b32d2e;text-decoration:none;border-color:transparent;box-shadow:none;background:0 0;margin:0 10px}.site-icon-section button.reset:focus,.site-icon-section button.reset:hover{background:#b32d2e;color:#fff;border-color:#b32d2e;box-shadow:0 0 0 1px #b32d2e}

138
wp-admin/js/site-icon.js Normal file
View File

@ -0,0 +1,138 @@
(function($) {
var frame;
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;
if ( realWidth / realHeight > ratio ) {
yInit = realHeight;
xInit = yInit * ratio;
} else {
xInit = realWidth;
yInit = xInit / ratio;
}
x1 = ( realWidth - xInit ) / 2;
y1 = ( realHeight - yInit ) / 2;
imgSelectOptions = {
aspectRatio: xInit + ':' + yInit,
handles: true,
keys: true,
instance: true,
persistent: true,
imageWidth: realWidth,
imageHeight: realHeight,
minWidth: xImg > xInit ? xInit : xImg,
minHeight: yImg > yInit ? yInit : yImg,
x1: x1,
y1: y1,
x2: xInit + x1,
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' )
}
},
imgSelectOptions: calculateImageSelectOptions
})
]
});
frame.on( 'cropped', function( attachment) {
$( '#site_icon_hidden_field' ).val(attachment.id);
switchToUpdate(attachment.url);
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' );
}
// swap the text of the button
$( '#choose-from-library-link' ).text( $( '#choose-from-library-link' ).attr( 'data-update-text' ) );
}
$( '#js-remove-site-icon' ).on( 'click', function() {
$( '#site_icon_hidden_field' ).val( 'false' );
$( '#site-icon-preview' ).toggleClass( 'hidden' );
$( 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));

2
wp-admin/js/site-icon.min.js vendored Normal file
View File

@ -0,0 +1,2 @@
/*! This file is auto-generated */
!function(a){var i;function t(t){var e=t.get("width"),t=t.get("height"),i=512,a=512,r=i/a,o=i,s=a;return r<e/t?i=(a=t)*r:a=(i=e)/r,{aspectRatio:i+":"+a,handles:!0,keys:!0,instance:!0,persistent:!0,imageWidth:e,imageHeight:t,minWidth:i<o?i:o,minHeight:a<s?a:s,x1:r=(e-i)/2,y1:o=(t-a)/2,x2:i+r,y2:a+o}}function r(i){var t;a("#site-icon-preview").find("img").not(".browser-preview").each(function(t,e){a(e).attr("src",i)}),a("#site-icon-preview").removeClass("hidden"),a("#js-remove-site-icon").removeClass("hidden"),"1"!==a("#choose-from-library-link").attr("data-state")&&(t=a("#choose-from-library-link").attr("class"),a("#choose-from-library-link").attr("class",a("#choose-from-library-link").attr("data-alt-classes")),a("#choose-from-library-link").attr("data-alt-classes",t),a("#choose-from-library-link").attr("data-state","1")),a("#choose-from-library-link").text(a("#choose-from-library-link").attr("data-update-text"))}a(function(){a("#choose-from-library-link").on("click",function(){var e=a(this);(i=wp.media({button:{text:e.data("update"),close:!1},states:[new wp.media.controller.Library({title:e.data("choose"),library:wp.media.query({type:"image"}),date:!1,suggestedWidth:e.data("size"),suggestedHeight:e.data("size")}),new wp.media.controller.SiteIconCropper({control:{params:{width:e.data("size"),height:e.data("size")}},imgSelectOptions:t})]})).on("cropped",function(t){a("#site_icon_hidden_field").val(t.id),r(t.url),i.close(),i=null}),i.on("select",function(){var t=i.state().get("selection").first();t.attributes.height===e.data("size")&&e.data("size")===t.attributes.width?(a("#site_icon_hidden_field").val(t.id),r(t.attributes.url),i.close()):i.setState("cropper")}),i.open()})}),a("#js-remove-site-icon").on("click",function(){a("#site_icon_hidden_field").val("false"),a("#site-icon-preview").toggleClass("hidden"),a(this).toggleClass("hidden");var t=a("#choose-from-library-link").attr("class");a("#choose-from-library-link").attr("class",a("#choose-from-library-link").attr("data-alt-classes")),a("#choose-from-library-link").attr("data-alt-classes",t),a("#choose-from-library-link").text(a("#choose-from-library-link").attr("data-choose-text")),a("#choose-from-library-link").attr("data-state","")})}(jQuery);

View File

@ -97,7 +97,86 @@ $tagline_description = sprintf(
<p class="description" id="tagline-description"><?php echo $tagline_description; ?></p></td>
</tr>
<?php
<?php if ( current_user_can( 'upload_files' ) ) : ?>
<tr class="hide-if-no-js site-icon-section">
<th scope="row"><?php _e( 'Site Icon' ); ?></th>
<td>
<?php
wp_enqueue_media();
wp_enqueue_script( 'site-icon' );
$classes_for_upload_button = 'upload-button button-add-media button-add-site-icon';
$classes_for_update_button = 'button';
$classes_for_avatar = 'avatar avatar-150';
if ( has_site_icon() ) {
$classes_for_avatar .= ' has-site-icon';
$classes_for_button = $classes_for_update_button;
$classes_for_button_on_change = $classes_for_upload_button;
} else {
$classes_for_avatar .= ' hidden';
$classes_for_button = $classes_for_upload_button;
$classes_for_button_on_change = $classes_for_update_button;
}
?>
<div id="site-icon-preview" class="site-icon-preview wp-clearfix <?php echo esc_attr( $classes_for_avatar ); ?>">
<div class="favicon-preview">
<img src="<?php echo esc_url( admin_url( 'images/' . ( is_rtl() ? 'browser-rtl.png' : 'browser.png' ) ) ); ?>" class="browser-preview" width="182" alt="">
<div class="favicon">
<img src="<?php site_icon_url(); ?>" alt="Preview as a browser icon">
</div>
<span class="browser-title" aria-hidden="true"><?php echo get_bloginfo( 'name' ); ?></span>
</div>
<img class="app-icon-preview" src="<?php site_icon_url(); ?>" alt="Preview as an app icon">
</div>
<input type="hidden" name="site_icon" id="site_icon_hidden_field" value="<?php form_option( 'site_icon' ); ?>" />
<p>
<button type="button"
id="choose-from-library-link"
type="button"
class="<?php echo esc_attr( $classes_for_button ); ?>"
data-alt-classes="<?php echo esc_attr( $classes_for_button_on_change ); ?>"
data-size="512"
data-choose-text="<?php esc_attr_e( 'Choose a Site Icon' ); ?>"
data-update-text="<?php esc_attr_e( 'Change Site Icon' ); ?>"
data-update="<?php esc_attr_e( 'Set as Site Icon' ); ?>"
data-state="<?php echo esc_attr( has_site_icon() ); ?>"
>
<?php if ( has_site_icon() ) : ?>
<?php _e( 'Change Site Icon' ); ?>
<?php else : ?>
<?php _e( 'Choose a Site Icon' ); ?>
<?php endif; ?>
</button>
<button
id="js-remove-site-icon"
type="button"
<?php echo has_site_icon() ? 'class="button button-secondary reset"' : 'class="button button-secondary reset hidden"'; ?>
>
<?php _e( 'Remove Site Icon' ); ?>
</button>
</p>
<p class="description" id="site-icon-description">
<?php _e( 'Site Icons are what you see in browser tabs, bookmark bars, and within the WordPress mobile apps. Upload one here!' ); ?>
</p>
<p class="description" id="site-icon-further-description">
<?php
/* translators: %s: Site Icon size in pixels. */
printf( __( 'Site Icons should be square and at least %s pixels.' ), '<strong>512 &times; 512</strong>' );
?>
</p>
</td>
</tr>
<?php
endif;
/* End Site Icon */
if ( ! is_multisite() ) {
$wp_site_url_class = '';
$wp_home_class = '';

View File

@ -90,6 +90,7 @@ $allowed_options = array(
'general' => array(
'blogname',
'blogdescription',
'site_icon',
'gmt_offset',
'date_format',
'time_format',

View File

@ -850,6 +850,7 @@
height: 100%;
}
.options-general-php .crop-content.site-icon,
.wp-customizer:not(.mobile) .media-frame-content .crop-content.site-icon {
margin-left: 300px;
}
@ -2561,6 +2562,10 @@
width: 230px;
}
.options-general-php .crop-content.site-icon {
margin-left: 262px;
}
.attachments-browser .attachments,
.attachments-browser .uploader-inline,
.attachments-browser .media-toolbar,
@ -2828,6 +2833,10 @@
position: fixed;
}
.options-general-php .crop-content.site-icon {
margin-left: 0;
}
.media-sidebar {
z-index: 1900;
max-width: 70%;

File diff suppressed because one or more lines are too long

View File

@ -849,6 +849,7 @@
height: 100%;
}
.options-general-php .crop-content.site-icon,
.wp-customizer:not(.mobile) .media-frame-content .crop-content.site-icon {
margin-right: 300px;
}
@ -2560,6 +2561,10 @@
width: 230px;
}
.options-general-php .crop-content.site-icon {
margin-right: 262px;
}
.attachments-browser .attachments,
.attachments-browser .uploader-inline,
.attachments-browser .media-toolbar,
@ -2827,6 +2832,10 @@
position: fixed;
}
.options-general-php .crop-content.site-icon {
margin-right: 0;
}
.media-sidebar {
z-index: 1900;
max-width: 70%;

File diff suppressed because one or more lines are too long

View File

@ -849,6 +849,8 @@ function wp_default_scripts( $scripts ) {
$scripts->add( 'wp-lists', "/wp-includes/js/wp-lists$suffix.js", array( 'wp-ajax-response', 'jquery-color' ), false, 1 );
$scripts->add( 'site-icon', '/wp-admin/js/site-icon.js', array( 'jquery', 'jcrop' ), false, 1 );
// WordPress no longer uses or bundles Prototype or script.aculo.us. These are now pulled from an external source.
$scripts->add( 'prototype', 'https://ajax.googleapis.com/ajax/libs/prototype/1.7.1.0/prototype.js', array(), '1.7.1' );
$scripts->add( 'scriptaculous-root', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/scriptaculous.js', array( 'prototype' ), '1.9.0' );

View File

@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
$wp_version = '6.5-alpha-57601';
$wp_version = '6.5-alpha-57602';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.