diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js
index 91f5af1353..a23a130c0b 100644
--- a/src/wp-admin/js/customize-controls.js
+++ b/src/wp-admin/js/customize-controls.js
@@ -3333,7 +3333,7 @@
* @param {object} attachment
*/
setImageFromAttachment: function( attachment ) {
- var sizes = [ 'site_icon-32', 'thumbnail', 'full' ],
+ var sizes = [ 'site_icon-32', 'thumbnail', 'full' ], link,
icon;
_.each( sizes, function( size ) {
@@ -3347,8 +3347,13 @@
// Set the Customizer setting; the callback takes care of rendering.
this.setting( attachment.id );
+ if ( ! icon ) {
+ return;
+ }
+
// Update the icon in-browser.
- $( 'link[sizes="32x32"]' ).attr( 'href', icon.url );
+ link = $( 'link[rel="icon"][sizes="32x32"]' );
+ link.attr( 'href', icon.url );
},
/**
@@ -3365,7 +3370,7 @@
this.params.attachment = {};
this.setting( '' );
this.renderContent(); // Not bound to setting change when emptying.
- $( 'link[rel="icon"]' ).attr( 'href', '' );
+ $( 'link[rel="icon"][sizes="32x32"]' ).attr( 'href', '/favicon.ico' ); // Set to default.
}
});
diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php
index 5174936de1..8e58b5cf49 100644
--- a/src/wp-includes/general-template.php
+++ b/src/wp-includes/general-template.php
@@ -2776,12 +2776,26 @@ function wp_site_icon() {
return;
}
- $meta_tags = array(
- sprintf( '', esc_url( get_site_icon_url( 32 ) ) ),
- sprintf( '', esc_url( get_site_icon_url( 192 ) ) ),
- sprintf( '', esc_url( get_site_icon_url( 180 ) ) ),
- sprintf( '', esc_url( get_site_icon_url( 270 ) ) ),
- );
+ $meta_tags = array();
+ $icon_32 = get_site_icon_url( 32 );
+ if ( empty( $icon_32 ) && is_customize_preview() ) {
+ $icon_32 = '/favicon.ico'; // Serve default favicon URL in customizer so element can be updated for preview.
+ }
+ if ( $icon_32 ) {
+ $meta_tags[] = sprintf( '', esc_url( $icon_32 ) );
+ }
+ $icon_192 = get_site_icon_url( 192 );
+ if ( $icon_192 ) {
+ $meta_tags[] = sprintf( '', esc_url( $icon_192 ) );
+ }
+ $icon_180 = get_site_icon_url( 180 );
+ if ( $icon_180 ) {
+ $meta_tags[] = sprintf( '', esc_url( $icon_180 ) );
+ }
+ $icon_270 = get_site_icon_url( 270 );
+ if ( $icon_270 ) {
+ $meta_tags[] = sprintf( '', esc_url( $icon_270 ) );
+ }
/**
* Filters the site icon meta tags, so Plugins can add their own.
diff --git a/tests/phpunit/tests/general/template.php b/tests/phpunit/tests/general/template.php
index d650d1ddf2..16007cf9a9 100644
--- a/tests/phpunit/tests/general/template.php
+++ b/tests/phpunit/tests/general/template.php
@@ -23,7 +23,10 @@ class Tests_General_Template extends WP_UnitTestCase {
}
function tearDown() {
+ global $wp_customize;
$this->_remove_custom_logo();
+ $this->_remove_site_icon();
+ $wp_customize = null;
parent::tearDown();
}
@@ -51,7 +54,6 @@ class Tests_General_Template extends WP_UnitTestCase {
$this->_set_site_icon();
$this->expectOutputString( $this->site_icon_url );
site_icon_url();
- $this->_remove_site_icon();
}
/**
@@ -117,8 +119,6 @@ class Tests_General_Template extends WP_UnitTestCase {
$this->expectOutputString( $output );
wp_site_icon();
-
- $this->_remove_site_icon();
}
/**
@@ -143,8 +143,51 @@ class Tests_General_Template extends WP_UnitTestCase {
add_filter( 'site_icon_meta_tags', array( $this, '_custom_site_icon_meta_tag' ) );
wp_site_icon();
remove_filter( 'site_icon_meta_tags', array( $this, '_custom_site_icon_meta_tag' ) );
+ }
- $this->_remove_site_icon();
+ /**
+ * @group site_icon
+ * @ticket 38377
+ */
+ function test_customize_preview_wp_site_icon_empty() {
+ global $wp_customize;
+ wp_set_current_user( $this->factory()->user->create( array( 'role' => 'administrator' ) ) );
+
+ require_once ABSPATH . WPINC . '/class-wp-customize-manager.php';
+ $wp_customize = new WP_Customize_Manager();
+ $wp_customize->register_controls();
+ $wp_customize->start_previewing_theme();
+
+ $this->expectOutputString( '' . "\n" );
+ wp_site_icon();
+ }
+
+ /**
+ * @group site_icon
+ * @ticket 38377
+ */
+ function test_customize_preview_wp_site_icon_dirty() {
+ global $wp_customize;
+ wp_set_current_user( $this->factory()->user->create( array( 'role' => 'administrator' ) ) );
+
+ require_once ABSPATH . WPINC . '/class-wp-customize-manager.php';
+ $wp_customize = new WP_Customize_Manager();
+ $wp_customize->register_controls();
+ $wp_customize->start_previewing_theme();
+
+ $attachment_id = $this->_insert_attachment();
+ $wp_customize->set_post_value( 'site_icon', $attachment_id );
+ $wp_customize->get_setting( 'site_icon' )->preview();
+ $output = array(
+ sprintf( '', esc_url( wp_get_attachment_image_url( $attachment_id, 32 ) ) ),
+ sprintf( '', esc_url( wp_get_attachment_image_url( $attachment_id, 192 ) ) ),
+ sprintf( '', esc_url( wp_get_attachment_image_url( $attachment_id, 180 ) ) ),
+ sprintf( '', esc_url( wp_get_attachment_image_url( $attachment_id, 270 ) ) ),
+ '',
+ );
+ $output = implode( "\n", $output );
+ $this->expectOutputString( $output );
+ wp_site_icon();
}
/**