Skip to content

Commit 333cdbb

Browse files
authored
HTML Block: Display notice when using restricted tags on WP.com Simple sites (#45819)
1 parent 055a417 commit 333cdbb

File tree

5 files changed

+163
-0
lines changed

5 files changed

+163
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: minor
2+
Type: added
3+
4+
Custom HTML Block: Add warning notice when using restricted HTML tags on WordPress.com Simple sites

projects/packages/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ public static function load_wpcom_user_features() {
321321
if ( ! class_exists( 'A8C\FSE\Help_Center' ) ) {
322322
require_once __DIR__ . '/features/help-center/class-help-center.php';
323323
}
324+
require_once __DIR__ . '/features/html-block-restricted-tags/html-block-restricted-tags.php';
324325
require_once __DIR__ . '/features/marketing/marketing.php';
325326
require_once __DIR__ . '/features/pages/pages.php';
326327
require_once __DIR__ . '/features/replace-site-visibility/replace-site-visibility.php';
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
/**
3+
* Displays a warning message when the user tries to insert a custom HTML block with restricted tags.
4+
*
5+
* @package automattic/jetpack-mu-wpcom
6+
*/
7+
8+
/**
9+
* Enqueue assets
10+
*/
11+
function wpcom_enqueue_html_block_restricted_tags_assets() {
12+
// Atomic sites don't have tags restrictions.
13+
if ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM ) {
14+
return;
15+
}
16+
17+
jetpack_mu_wpcom_enqueue_assets( 'html-block-restricted-tags', array( 'js' ) );
18+
}
19+
20+
add_action( 'enqueue_block_editor_assets', 'wpcom_enqueue_html_block_restricted_tags_assets' );
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import { localizeUrl } from '@automattic/i18n-utils';
2+
import { WpcomSupportLink } from '@automattic/jetpack-shared-extension-utils/components';
3+
import { useBlockProps } from '@wordpress/block-editor';
4+
import { Notice } from '@wordpress/components';
5+
import { createHigherOrderComponent } from '@wordpress/compose';
6+
import { createInterpolateElement, createPortal } from '@wordpress/element';
7+
import { addFilter } from '@wordpress/hooks';
8+
import { __, _n, sprintf } from '@wordpress/i18n';
9+
10+
/**
11+
* List of HTML tags that are restricted on Simple sites.
12+
*
13+
* @see https://wordpress.com/support/wordpress-editor/blocks/custom-html-block/#supported-code
14+
*/
15+
const RESTRICTED_TAGS = [
16+
'embed',
17+
'frame',
18+
'iframe',
19+
'form',
20+
'input',
21+
'object',
22+
'textarea',
23+
'script',
24+
'style',
25+
'link',
26+
];
27+
28+
/**
29+
* Detects if the content contains any restricted HTML tags.
30+
*
31+
* @param {string} content - The HTML content to check
32+
* @return {Array<string>} Array of detected restricted tag names
33+
*/
34+
const detectRestrictedTags = ( content: string ): string[] => {
35+
if ( ! content ) {
36+
return [];
37+
}
38+
39+
const detectedTags: string[] = [];
40+
const lowercaseContent = content.toLowerCase();
41+
42+
for ( const tag of RESTRICTED_TAGS ) {
43+
// Check for opening tags (e.g., <script or <script> or <script attr="value">)
44+
const tagPattern = new RegExp( `<${ tag }(?:\\s|>|/)`, 'i' );
45+
if ( tagPattern.test( lowercaseContent ) ) {
46+
detectedTags.push( tag );
47+
}
48+
}
49+
50+
return detectedTags;
51+
};
52+
53+
const RestrictedTagsNotice = ( { restrictedTags }: { restrictedTags: string[] } ) => {
54+
// Build a string with code placeholders for createInterpolateElement.
55+
const tagsString = restrictedTags.map( tag => `<code>${ tag }</code>` ).join( ', ' );
56+
57+
return (
58+
<Notice status="warning" isDismissible={ false }>
59+
<>
60+
{ createInterpolateElement(
61+
sprintf(
62+
/* translators: %s is a comma-separated list of HTML tag names wrapped in <code> elements */
63+
_n(
64+
'The %s tag is not supported on this site.',
65+
'The following tags are not supported on this site: %s.',
66+
restrictedTags.length,
67+
'jetpack-mu-wpcom'
68+
),
69+
tagsString
70+
),
71+
{
72+
code: <code />,
73+
}
74+
) }{ ' ' }
75+
<WpcomSupportLink
76+
supportLink={ localizeUrl(
77+
'https://wordpress.com/support/wordpress-editor/blocks/custom-html-block/#supported-code'
78+
) }
79+
>
80+
{ __( 'Learn more', 'jetpack-mu-wpcom' ) }
81+
</WpcomSupportLink>
82+
</>
83+
</Notice>
84+
);
85+
};
86+
87+
const htmlBlockRestrictedTags = createHigherOrderComponent( BlockEdit => {
88+
return props => {
89+
const content = props.attributes.content || '';
90+
const restrictedTags = detectRestrictedTags( content );
91+
const hasRestrictedTags = restrictedTags.length > 0;
92+
93+
const { id: blockId } = useBlockProps();
94+
const editor = window[ 'editor-canvas' ] ? window[ 'editor-canvas' ].document : document;
95+
const blockElement = editor.getElementById( blockId );
96+
97+
let noticeContainer = null;
98+
if ( blockElement ) {
99+
noticeContainer = blockElement.querySelector( '.wpcom-html-block-restricted-tags-notice' );
100+
101+
if ( ! noticeContainer ) {
102+
noticeContainer = editor.createElement( 'div' );
103+
noticeContainer.classList.add( 'wpcom-html-block-restricted-tags-notice' );
104+
noticeContainer.style.marginBottom = '8px';
105+
blockElement.prepend( noticeContainer );
106+
}
107+
}
108+
109+
return (
110+
<>
111+
<BlockEdit { ...props } />
112+
{ hasRestrictedTags &&
113+
noticeContainer &&
114+
createPortal(
115+
<RestrictedTagsNotice restrictedTags={ restrictedTags } />,
116+
noticeContainer
117+
) }
118+
</>
119+
);
120+
};
121+
}, 'HtmlBlockRestrictedTags' );
122+
123+
addFilter(
124+
'blocks.registerBlockType',
125+
'jetpack-mu-wpcom/html-block-restricted-tags',
126+
( settings, name ) => {
127+
if ( name !== 'core/html' ) {
128+
return settings;
129+
}
130+
131+
return {
132+
...settings,
133+
edit: htmlBlockRestrictedTags( settings.edit ),
134+
};
135+
}
136+
);

projects/packages/jetpack-mu-wpcom/webpack.config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ module.exports = async () => {
1919
'customizer-control': './src/features/custom-css/custom-css/css/customizer-control.css',
2020
'error-reporting': './src/features/error-reporting/index.js',
2121
'holiday-snow': './src/features/holiday-snow/holiday-snow.scss',
22+
'html-block-restricted-tags':
23+
'./src/features/html-block-restricted-tags/html-block-restricted-tags.tsx',
2224
'jetpack-global-styles': './src/features/jetpack-global-styles/index.js',
2325
'jetpack-global-styles-customizer-fonts':
2426
'./src/features/jetpack-global-styles/customizer-fonts/index.js',

0 commit comments

Comments
 (0)