Skip to content

Commit

Permalink
General: Add an option to configure the site icon in general settings.
Browse files Browse the repository at this point in the history
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.



git-svn-id: https://develop.svn.wordpress.org/trunk@57602 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information
aaronjorbin committed Feb 12, 2024
1 parent e1f0ce5 commit 35feae5
Show file tree
Hide file tree
Showing 8 changed files with 285 additions and 1 deletion.
1 change: 1 addition & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ module.exports = function(grunt) {
[ WORKING_DIR + 'wp-admin/js/tags-suggest.js' ]: [ './src/js/_enqueues/admin/tags-suggest.js' ],
[ WORKING_DIR + 'wp-admin/js/tags.js' ]: [ './src/js/_enqueues/admin/tags.js' ],
[ WORKING_DIR + 'wp-admin/js/site-health.js' ]: [ './src/js/_enqueues/admin/site-health.js' ],
[ WORKING_DIR + 'wp-admin/js/site-icon.js' ]: [ './src/js/_enqueues/admin/site-icon.js' ],
[ WORKING_DIR + 'wp-admin/js/privacy-tools.js' ]: [ './src/js/_enqueues/admin/privacy-tools.js' ],
[ WORKING_DIR + 'wp-admin/js/theme-plugin-editor.js' ]: [ './src/js/_enqueues/wp/theme-plugin-editor.js' ],
[ WORKING_DIR + 'wp-admin/js/theme.js' ]: [ './src/js/_enqueues/wp/theme.js' ],
Expand Down
138 changes: 138 additions & 0 deletions src/js/_enqueues/admin/site-icon.js
Original file line number Diff line number Diff line change
@@ -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));
36 changes: 36 additions & 0 deletions src/wp-admin/css/forms.css
Original file line number Diff line number Diff line change
Expand Up @@ -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
------------------------------------------------------------------------------*/
Expand Down
18 changes: 18 additions & 0 deletions src/wp-admin/css/site-icon.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
overflow: hidden;
position: relative;
max-width: 180px;
float: left;
}

.site-icon-preview .favicon,
Expand Down Expand Up @@ -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;
}
81 changes: 80 additions & 1 deletion src/wp-admin/options-general.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,86 @@
<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 = '';
Expand Down
1 change: 1 addition & 0 deletions src/wp-admin/options.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
'general' => array(
'blogname',
'blogdescription',
'site_icon',
'gmt_offset',
'date_format',
'time_format',
Expand Down
9 changes: 9 additions & 0 deletions src/wp-includes/css/media-views.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -2827,6 +2832,10 @@
position: fixed;
}

.options-general-php .crop-content.site-icon {
margin-right: 0;
}

.media-sidebar {
z-index: 1900;
max-width: 70%;
Expand Down
2 changes: 2 additions & 0 deletions src/wp-includes/script-loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -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' );
Expand Down

0 comments on commit 35feae5

Please sign in to comment.