Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom CSS: add deprecation warning for Start Fresh option #37193

Merged
merged 13 commits into from
Jun 26, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ import {
userCanConnectSite,
userIsSubscriber,
getConnectionErrors,
getSiteAdminUrl,
} from 'state/initial-state';
import { getLicensingError, clearLicensingError } from 'state/licensing';
import { getModule } from 'state/modules';
import { getSiteDataErrors } from 'state/site';
import { StartFreshDeprecationWarning } from '../../writing/custom-css';
import DismissableNotices from './dismissable';
import JetpackConnectionErrors from './jetpack-connection-errors';
import PlanConflictWarning from './plan-conflict-warning';
Expand Down Expand Up @@ -234,6 +237,11 @@ class JetpackNotices extends React.Component {
onDismissClick={ this.props.clearLicensingError }
/>
) }
{ this.props.startFreshEnabled && (
<SimpleNotice status="is-warning" showDismiss={ false }>
<StartFreshDeprecationWarning siteAdminUrl={ this.props.siteAdminUrl } />
</SimpleNotice>
) }
</div>
);
}
Expand All @@ -258,6 +266,8 @@ export default connect(
isReconnectingSite: isReconnectingSite( state ),
licensingError: getLicensingError( state ),
hasConnectedOwner: hasConnectedOwner( state ),
siteAdminUrl: getSiteAdminUrl( state ),
startFreshEnabled: !! getModule( state, 'custom-css' )?.options?.replace,
};
},
dispatch => {
Expand Down
48 changes: 36 additions & 12 deletions projects/plugins/jetpack/_inc/client/writing/custom-css.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getRedirectUrl } from '@automattic/jetpack-components';
import { ExternalLink } from '@wordpress/components';
import { ExternalLink, Notice } from '@wordpress/components';
import { createInterpolateElement } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import Button from 'components/button';
Expand Down Expand Up @@ -29,6 +29,30 @@ const trackVisitCustomizer = () => {
} );
};

const CustomizerLink = ( { children, siteAdminUrl } ) => (
<a
onClick={ trackVisitCustomizer }
href={ `${ siteAdminUrl }customize.php?autofocus%5Bsection%5D=custom_css` }
title={ __( 'Edit and add CSS directly on your site from the Customizer.', 'jetpack' ) }
>
{ children }
</a>
);

export const StartFreshDeprecationWarning = ( { siteAdminUrl } ) =>
createInterpolateElement(
__(
"The <i>Start Fresh</i> option in the <a1>CSS customization panel</a1> is enabled, which means the theme's original CSS is not applied. <b>This option will no longer be supported after August 6, 2024.</b> <a2>See how to keep your site intact</a2>.",
'jetpack'
),
{
i: <i />,
b: <b />,
a1: <CustomizerLink siteAdminUrl={ siteAdminUrl } />,
a2: <ExternalLink href={ getRedirectUrl( 'jetpack-support-custom-css' ) } />,
}
);

/**
* Custom CSS settings component.
*
Expand All @@ -38,7 +62,7 @@ const trackVisitCustomizer = () => {
function CustomCss( props ) {
const {
customCssActive,
customCssModule: { name, description, module },
customCssModule: { name, description, module, options },
isBlockThemeActive,
isSavingAnyOption,
siteAdminUrl,
Expand Down Expand Up @@ -92,16 +116,7 @@ function CustomCss( props ) {
'jetpack'
),
{
a: (
<a
onClick={ trackVisitCustomizer }
href={ `${ siteAdminUrl }customize.php?autofocus%5Bsection%5D=custom_css` }
title={ __(
'Edit and add CSS directly on your site from the Customizer.',
'jetpack'
) }
/>
),
a: <CustomizerLink siteAdminUrl={ siteAdminUrl } />,
}
) }
</div>
Expand Down Expand Up @@ -144,6 +159,15 @@ function CustomCss( props ) {
return (
<SettingsGroup module={ { module } } support={ supportText() }>
<FormLegend className="jp-form-label-wide">{ name }</FormLegend>
{ options?.replace && (
<Notice
className="jp-custom-css__deprecation-warning"
isDismissible={ false }
status="warning"
>
<StartFreshDeprecationWarning siteAdminUrl={ siteAdminUrl } />{ ' ' }
</Notice>
) }
{ isBlockThemeActive && recommendSiteEditor() }
{ ! isBlockThemeActive && customizerLink() }
{ toggleModule() }
Expand Down
4 changes: 4 additions & 0 deletions projects/plugins/jetpack/_inc/client/writing/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,7 @@
padding: rem(16px) 0 0;
}
}

.jp-custom-css__deprecation-warning {
margin-bottom: 1rem;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: other

Custom CSS: add deprecation warning for Start Fresh option
174 changes: 167 additions & 7 deletions projects/plugins/jetpack/modules/custom-css/custom-css.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed -- TODO: Move classes to appropriately-named class files.

use Automattic\Jetpack\Assets;
use Automattic\Jetpack\Redirect;

/**
* Alternate Custom CSS source for 4.7 compat.
Expand Down Expand Up @@ -30,6 +31,8 @@ public static function add_hooks() {
add_action( 'load-revision.php', array( __CLASS__, 'load_revision_php' ) );

add_action( 'wp_enqueue_scripts', array( __CLASS__, 'wp_enqueue_scripts' ) );
add_action( 'admin_footer', array( __CLASS__, 'update_initial_state' ) );
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if that's the most appropriate hook to use. Let me know if there's a more suited one.

add_action( 'wp_body_open', array( __CLASS__, 'display_frontend_warning' ) );

// Handle Sass/LESS.
add_filter( 'customize_value_custom_css', array( __CLASS__, 'customize_value_custom_css' ), 10, 2 );
Expand Down Expand Up @@ -351,10 +354,14 @@ public static function customizer_link( $args = array() ) {
* Handle the enqueueing and localizing for scripts to be used in the Customizer.
*/
public static function customize_controls_enqueue_scripts() {
global $wp_customize;

wp_enqueue_style( 'jetpack-customizer-css' );
wp_enqueue_script( 'jetpack-customizer-css' );

$setting = $wp_customize->get_setting( 'jetpack_custom_css[replace]' );
$content_help = __( 'Set a different media width for full size images.', 'jetpack' );

if ( ! empty( $GLOBALS['content_width'] ) ) {
$content_help .= sprintf(
// translators: the theme name and then the default width.
Expand All @@ -371,14 +378,16 @@ public static function customize_controls_enqueue_scripts() {
/** This filter is documented in modules/custom-css/custom-css.php */
'useRichEditor' => ! jetpack_is_mobile() && apply_filters( 'safecss_use_ace', true ),
'areThereCssRevisions' => self::are_there_css_revisions(),
'startFresh' => isset( $setting ) && $setting->value(),
'revisionsUrl' => self::get_revisions_url(),
'cssHelpUrl' => '//en.support.wordpress.com/custom-design/editing-css/',
'l10n' => array(
'mode' => __( 'Start Fresh', 'jetpack' ),
'mobile' => __( 'On Mobile', 'jetpack' ),
'contentWidth' => $content_help,
'revisions' => _x( 'See full history', 'Toolbar button to see full CSS revision history', 'jetpack' ),
'css_help_title' => _x( 'Help', 'Toolbar button to get help with custom CSS', 'jetpack' ),
'mode' => __( 'Start Fresh (deprecated)', 'jetpack' ),
'mobile' => __( 'On Mobile', 'jetpack' ),
'contentWidth' => $content_help,
'revisions' => _x( 'See full history', 'Toolbar button to see full CSS revision history', 'jetpack' ),
'css_help_title' => _x( 'Help', 'Toolbar button to get help with custom CSS', 'jetpack' ),
'startFreshCustomizerWarning' => __( "The Start Fresh option in the Additional CSS panel is enabled, which means the theme's original CSS is not applied. This option will no longer be supported after August 6, 2024.", 'jetpack' ),
),
)
);
Expand Down Expand Up @@ -743,7 +752,7 @@ public static function customize_register( $wp_customize ) {
'wpcom_custom_css_content_width_control',
array(
'type' => 'text',
'label' => __( 'Media Width', 'jetpack' ),
'label' => __( 'Media Width (deprecated)', 'jetpack' ),
'section' => 'custom_css',
'settings' => 'jetpack_custom_css[content_width]',
)
Expand Down Expand Up @@ -786,7 +795,7 @@ public static function customize_register( $wp_customize ) {
array(
'type' => 'select',
'choices' => $preprocessor_choices,
'label' => __( 'Preprocessor', 'jetpack' ),
'label' => __( 'Preprocessor (deprecated)', 'jetpack' ),
'section' => 'custom_css',
'settings' => 'jetpack_custom_css[preprocessor]',
)
Expand Down Expand Up @@ -998,6 +1007,157 @@ public static function jetpack_content_width( $content_width ) {
return $content_width;
}

/**
* Return whether the Start Fresh option of the CSS editor is enabled.
*
* @return boolean
*/
public static function is_start_fresh_option_enabled() {
if ( wp_is_block_theme() ) {
return false;
}

$start_fresh = null;

// $wp_customize is not available here. Let's get the value of the `replace` option from the last
// customize_changeset posts.
$posts = get_posts(
array(
'post_type' => 'customize_changeset',
'post_status' => 'trash',
'order_by' => 'post_modified',
'order' => 'DESC',
)
);

// Bail as soon as we find a post that defines the `replace` option.
foreach ( $posts as $post ) {
$content = $post->post_content;

if ( empty( $content ) ) {
continue;
}

$parsed_content = json_decode( $content, true );

if ( empty( $parsed_content ) ) {
continue;
}

foreach ( $parsed_content as $key => $data ) {
if ( str_ends_with( $key, '::jetpack_custom_css[replace]' ) ) {
$start_fresh = $data['value'];
break;
}
}

if ( isset( $start_fresh ) ) {
break;
}
}

return $start_fresh;
}

/**
* Display a deprecation warning on the frontend for site admins only
*/
public static function display_frontend_warning() {
if ( ! current_user_can( 'edit_themes' ) || ! current_user_can( 'edit_theme_options' ) || ! self::is_start_fresh_option_enabled() ) {
return;
}

$notice = '';
$notice .= '<style>';
$notice .= '
.jp-custom-css__deprecation-warning {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline styles is good enough given the lifespan of this piece of code.

position: absolute;
top: 2.5rem;
left: 50%;
z-index: 99999;
transform: translateX( -50% );

display: flex;
align-items: flex-start;
width: 80ch;

background-color: #fef8ee;
border: solid 1px #ccc;
border-left: solid 5px #f0b849;
box-shadow: 0 0 4px 4px rgba( 0, 0, 0, 0.1 );

font-size: 1rem;
}

.jp-custom-css__deprecation-warning p {
margin: 0;
padding: 1em;
}

.jp-custom-css__deprecation-warning button {
min-width: 48px;
min-height: 48px;

border-color: transparent;
background-color: transparent;

font-size: 1.25rem;
font-weight: bold;
}
';
$notice .= '</style>';
$notice .= '<div class="jp-custom-css__deprecation-warning">';
$notice .= '<p>' . wp_kses(
sprintf(
// translators: 1: URL to the CSS customization panel, 2: URL to the theme stylesheet documentation.
__(
'The <i>Start Fresh</i> option in the <a href="%1$s">CSS customization panel</a> is enabled, which means the theme\'s original CSS is not applied. <b>This option will no longer be supported after August 6, 2024.</b> <a href="%2$s">See how to keep your site intact.</a>',
'jetpack'
),
esc_url( admin_url( 'customize.php?autofocus%5Bsection%5D=custom_css' ) ),
esc_url( Redirect::get_url( 'jetpack-support-custom-css' ) )
),
array(
'i' => array(),
'b' => array(),
'a' => array(
'href' => array(),
'target' => array(),
),
)
) . '</p>';
$notice .= '<button aria-label="' . esc_html__( 'Dismiss', 'jetpack' ) . '">&times;</button>';
$notice .= '</div>';
$notice .= '<script>';
$notice .= 'document.querySelector(".jp-custom-css__deprecation-warning button").addEventListener("click", (e) => e.currentTarget.parentNode.remove() );';
$notice .= '</script>';

// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $notice;
}

/**
* Update the initial state to include the `replace` option (Start Fresh) in the module data.
*/
public static function update_initial_state() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is only meant to be useful in the Jetpack dashboard, I think we should limit it to that page. We don't want to run a posts query on dashboard pages where it won't be used.

Hooking into admin_enqueue_scripts instead of admin_footer should give you more control there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

admin_enqueue_scripts won't work: the call to wp_add_inline_script in the callback will fail. But I could check the current page and bail out early if it's not the Jetpack dashboard.

if ( 'toplevel_page_jetpack' !== get_current_screen()->base ) {
return;
}

$val = self::is_start_fresh_option_enabled() ? 'true' : 'false';

wp_add_inline_script(
'react-plugin',
"
try {
var options = window.Initial_State?.getModules?.['custom-css']?.options || {};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems the most straightforward way to make the value of the Start Fresh option available to client pages (the Customizer case is handled separately).

options.replace = $val;
} catch (e) {}
",
'after'
);
}

/**
* Currently this filter function gets called on
* 'template_redirect' action and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@
}).prependTo( '#css-help-links' );
}

// Show deprecation warning if Start Fresh option is enabled
if ( !! window._jp_css_settings.startFresh && window._currentSiteType !== 'atomic' ) {
customize.notifications.add( new customize.Notification( 'start-fresh-warning', {
message: window._jp_css_settings.l10n.startFreshCustomizerWarning,
type: 'warning',
} ) );
}

customize( 'jetpack_custom_css[preprocessor]', function( preprocessorSetting ) {
preprocessorSetting.bind( function( curr ) {
var preprocessor_modes = {
Expand Down
Loading