Skip to content

Commit

Permalink
Merge pull request #698 from GoogleChromeLabs/feature/304-makable-ico…
Browse files Browse the repository at this point in the history
…n-setting

Add maskable icon checkbox in customizer settings
  • Loading branch information
westonruter authored Feb 24, 2022
2 parents 9f4171b + c82d070 commit 9806304
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 2 deletions.
3 changes: 3 additions & 0 deletions pwa.php
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@ function _pwa_check_disabled_navigation_preload() {
/** Patch behavior in class-wp-query.php */
require_once PWA_PLUGIN_DIR . '/wp-includes/class-wp-query.php';

/** Function to register maskable icon setting in customizer */
require_once PWA_PLUGIN_DIR . '/wp-includes/class-wp-customize-manager.php';

/** Hooks to add for when accessing admin. */
require_once PWA_PLUGIN_DIR . '/wp-admin/admin.php';

Expand Down
71 changes: 71 additions & 0 deletions tests/test-class-wp-customize-manager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php
/**
* Tests for customizer settings.
*
* @package PWA
*/

use Yoast\WPTestUtils\WPIntegration\TestCase;

/**
* Tests for class WP_Customize_Manager.
*/
class Test_WP_Customize_Manager extends TestCase {

/**
* Tested instance.
*
* @var WP_Customize_Manager
*/
public $wp_customize;

/**
* Setup.
*
* @inheritdoc
*/
public function setUp() {
parent::setUp();
$this->user_id = self::factory()->user->create( array( 'role' => 'administrator' ) );
wp_set_current_user( $this->user_id );

require_once ABSPATH . WPINC . '/class-wp-customize-manager.php';
// @codingStandardsIgnoreStart
$GLOBALS['wp_customize'] = new WP_Customize_Manager();
// @codingStandardsIgnoreStop
$this->wp_customize = $GLOBALS['wp_customize'];
}

/**
* Tear down.
*/
public function tearDown() {
$this->wp_customize = null;
unset( $GLOBALS['wp_customize'] );
parent::tearDown();
}

/**
* @covers ::pwa_customize_register_site_icon_maskable
*/
public function test_pwa_customize_register_site_icon_maskable() {
do_action( 'customize_register', $this->wp_customize );
pwa_customize_register_site_icon_maskable( $this->wp_customize );

$this->assertEquals( 1000, has_action( 'customize_register', 'pwa_customize_register_site_icon_maskable' ) );
$this->assertInstanceOf( 'WP_Customize_Setting', $this->wp_customize->get_setting( 'site_icon_maskable' ) );
$this->assertInstanceOf( 'WP_Customize_Control', $this->wp_customize->get_control( 'site_icon_maskable' ) );
}

/**
* @covers ::pwa_customize_controls_enqueue_site_icon_maskable_script
*/
public function test_pwa_customize_controls_enqueue_site_icon_maskable_script() {
pwa_customize_controls_enqueue_site_icon_maskable_script();

$this->assertEquals( 10, has_action( 'customize_controls_enqueue_scripts', 'pwa_customize_controls_enqueue_site_icon_maskable_script' ) );
$this->assertTrue( wp_script_is( 'customize-controls', 'enqueued' ) );
$this->assertTrue( wp_script_is( 'customize-controls-site-icon-maskable', 'enqueued' ) );
}

}
12 changes: 12 additions & 0 deletions tests/test-class-wp-web-app-manifest.php
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,18 @@ public function test_get_manifest() {
);
$this->assertEquals( $expected_manifest, $actual_manifest );

// Check that icon purpose is `any maskable` if site icon is maskable.
update_option( 'site_icon_maskable', true );
$actual_manifest = $this->instance->get_manifest();
$expected_manifest['icons'] = array_map(
function ( $icon ) {
$icon['purpose'] = 'any maskable';
return $icon;
},
$expected_manifest['icons']
);
$this->assertEquals( $expected_manifest, $actual_manifest );

// Check that long names do not automatically copy to short name.
$blogname = str_repeat( 'x', 13 );
update_option( 'blogname', $blogname );
Expand Down
57 changes: 57 additions & 0 deletions wp-admin/js/customize-controls-site-icon-maskable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
wp.customize(
'site_icon',
'site_icon_maskable',
(siteIconSetting, siteIconMaskableSetting) => {
wp.customize.control(
'site_icon',
'site_icon_maskable',
(siteIconControl, siteIconMaskableControl) => {
/**
* Determine whether the site_icon setting has been set.
*
* @return {boolean} Whether set.
*/
const hasSiteIcon = () => {
const siteIconValue = siteIconSetting();
return (
typeof siteIconValue === 'number' && siteIconValue > 0
);
};

/**
* Toggle site icon maskable active state based on whether the site icon is set.
*/
const updateActive = () => {
siteIconMaskableControl.active(hasSiteIcon());
};

// Set initial active state.
updateActive();

// Update active state whenever the site_icon setting changes.
siteIconSetting.bind(updateActive);

/**
* Update the icon styling based on whether the site icon maskable is enabled.
*/
const updateIconStyle = () => {
siteIconControl.container
.find('img.app-icon-preview')
.css(
'clipPath',
siteIconMaskableSetting()
? 'inset(10% round 50%)'
: ''
);
};

// Set initial style.
updateIconStyle();

// Update style whenever the site_icon or the site_icon_maskable changes.
siteIconSetting.bind(updateIconStyle);
siteIconMaskableSetting.bind(updateIconStyle);
}
);
}
);
67 changes: 67 additions & 0 deletions wp-includes/class-wp-customize-manager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php
/**
* Add hooks to amend behavior of the WP_Customize_Manager class.
*
* @package PWA
* @subpackage Customize
* @since 0.7
*/

/**
* Register site_icon_maskable setting and control.
*
* Core merge note: This will go into the `WP_Customize_Manager::register_controls()` method or else the control logic
* itself may be made part of WP_Customize_Site_Icon_Control.
*
* @see WP_Customize_Manager::register_controls()
* @see WP_Customize_Site_Icon_Control
* @since 0.7
*
* @param WP_Customize_Manager $wp_customize Customizer manager object.
*/
function pwa_customize_register_site_icon_maskable( WP_Customize_Manager $wp_customize ) {
$wp_customize->add_setting(
'site_icon_maskable',
array(
'capability' => 'manage_options',
'type' => 'option',
'default' => false,
'transport' => 'postMessage',
)
);

$site_icon_control = $wp_customize->get_control( 'site_icon' );
if ( $site_icon_control ) {
$wp_customize->add_control(
'site_icon_maskable',
array(
'type' => 'checkbox',
'section' => 'title_tagline',
'label' => __( 'Maskable icon', 'pwa' ),
'priority' => $site_icon_control->priority + 1,
)
);
}
}

add_action( 'customize_register', 'pwa_customize_register_site_icon_maskable', 1000 );

/**
* Enqueue script for site_icon_maskable control.
*
* This may end up making sense being enqueued as part of WP_Customize_Site_Icon_Control or just added to logic in
* <src/js/_enqueues/wp/customize/controls.js>.
*
* @see WP_Customize_Site_Icon_Control::enqueue()
*/
function pwa_customize_controls_enqueue_site_icon_maskable_script() {
wp_enqueue_script(
'customize-controls-site-icon-maskable',
plugins_url( 'wp-admin/js/customize-controls-site-icon-maskable.js', PWA_PLUGIN_FILE ),
array( 'customize-controls' ),
PWA_VERSION,
true
);
}

add_action( 'customize_controls_enqueue_scripts', 'pwa_customize_controls_enqueue_site_icon_maskable_script' );
15 changes: 13 additions & 2 deletions wp-includes/class-wp-web-app-manifest.php
Original file line number Diff line number Diff line change
Expand Up @@ -396,16 +396,27 @@ public function get_icons() {
return array();
}

$icons = array();
$mime_type = get_post_mime_type( $site_icon_id );
if ( ! $mime_type ) {
return array();
}

$icons = array();
$maskable = get_option( 'site_icon_maskable', false );
foreach ( $this->default_manifest_icon_sizes as $size ) {
$src = get_site_icon_url( $size );
if ( $src ) {
$icons[] = array(
$icon = array(
'src' => $src,
'sizes' => sprintf( '%1$dx%1$d', $size ),
'type' => $mime_type,
);

if ( $maskable ) {
$icon['purpose'] = 'any maskable';
}

$icons[] = $icon;
}
}
return $icons;
Expand Down

0 comments on commit 9806304

Please sign in to comment.