From 78e73857d9d0a662a602fd0b611c5eea36c1d0bc Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 12 Jan 2021 11:41:43 +0100 Subject: [PATCH 1/2] Prevent link paste in RichText components in Button and Navigation blocks --- .../rich-text/src/component/format-edit.js | 34 +----------- packages/rich-text/src/component/index.js | 6 +-- .../rich-text/src/component/index.native.js | 18 ++++--- .../src/component/use-format-types.js | 53 +++++++++++++++++-- 4 files changed, 63 insertions(+), 48 deletions(-) diff --git a/packages/rich-text/src/component/format-edit.js b/packages/rich-text/src/component/format-edit.js index 893b0af9a5c2d..1867c1ef2e4f7 100644 --- a/packages/rich-text/src/component/format-edit.js +++ b/packages/rich-text/src/component/format-edit.js @@ -4,52 +4,20 @@ import { getActiveFormat } from '../get-active-format'; import { getActiveObject } from '../get-active-object'; -/** - * Set of all interactive content tags. - * - * @see https://html.spec.whatwg.org/multipage/dom.html#interactive-content - */ -const interactiveContentTags = new Set( [ - 'a', - 'audio', - 'button', - 'details', - 'embed', - 'iframe', - 'input', - 'label', - 'select', - 'textarea', - 'video', -] ); - export default function FormatEdit( { formatTypes, onChange, onFocus, value, - allowedFormats, - withoutInteractiveFormatting, forwardedRef, } ) { return formatTypes.map( ( settings ) => { - const { name, edit: Edit, tagName } = settings; + const { name, edit: Edit } = settings; if ( ! Edit ) { return null; } - if ( allowedFormats && allowedFormats.indexOf( name ) === -1 ) { - return null; - } - - if ( - withoutInteractiveFormatting && - interactiveContentTags.has( tagName ) - ) { - return null; - } - const activeFormat = getActiveFormat( value, name ); const isActive = activeFormat !== undefined; const activeObject = getActiveObject( value ); diff --git a/packages/rich-text/src/component/index.js b/packages/rich-text/src/component/index.js index 625da9012fd05..da2505228d1d1 100644 --- a/packages/rich-text/src/component/index.js +++ b/packages/rich-text/src/component/index.js @@ -174,6 +174,8 @@ function RichText( } = useFormatTypes( { clientId, identifier, + withoutInteractiveFormatting, + allowedFormats, } ); // For backward compatibility, fall back to tagName if it's a string. @@ -1102,10 +1104,6 @@ function RichText( <> { isSelected && ( { return text.replace( / | /gi, ' ' ); @@ -799,7 +799,6 @@ export class RichText extends Component { maxWidth, formatTypes, parentBlockStyles, - withoutInteractiveFormatting, accessibilityLabel, disableEditingMenu = false, } = this.props; @@ -953,9 +952,6 @@ export class RichText extends Component { {} } /> @@ -977,6 +973,16 @@ RichText.defaultProps = { tagName: 'div', }; +const withFormatTypes = ( WrappedComponent ) => ( props ) => { + const { formatTypes } = useFormatTypes( { + clientId: props.clientId, + identifier: props.identifier, + withoutInteractiveFormatting: props.withoutInteractiveFormatting, + } ); + + return ; +}; + export default compose( [ withSelect( ( select, { clientId } ) => { const { getBlockParents, getBlock, getSettings } = select( @@ -988,7 +994,6 @@ export default compose( [ get( parentBlock, [ 'attributes', 'childrenStyles' ] ) || {}; return { - formatTypes: select( richTextStore ).getFormatTypes(), areMentionsSupported: getSettings( 'capabilities' ).mentions === true, areXPostsSupported: getSettings( 'capabilities' ).xposts === true, @@ -996,4 +1001,5 @@ export default compose( [ }; } ), withPreferredColorScheme, + withFormatTypes, ] )( RichText ); diff --git a/packages/rich-text/src/component/use-format-types.js b/packages/rich-text/src/component/use-format-types.js index c1df61ac093c1..5406e51d68b0d 100644 --- a/packages/rich-text/src/component/use-format-types.js +++ b/packages/rich-text/src/component/use-format-types.js @@ -1,6 +1,7 @@ /** * WordPress dependencies */ +import { useMemo } from '@wordpress/element'; import { useSelect, useDispatch } from '@wordpress/data'; /** * Internal dependencies @@ -11,16 +12,58 @@ function formatTypesSelector( select ) { return select( richTextStore ).getFormatTypes(); } +/** + * Set of all interactive content tags. + * + * @see https://html.spec.whatwg.org/multipage/dom.html#interactive-content + */ +const interactiveContentTags = new Set( [ + 'a', + 'audio', + 'button', + 'details', + 'embed', + 'iframe', + 'input', + 'label', + 'select', + 'textarea', + 'video', +] ); + /** * This hook provides RichText with the `formatTypes` and its derived props from * experimental format type settings. * - * @param {Object} $0 Options - * @param {string} $0.clientId Block client ID. - * @param {string} $0.identifier Block attribute. + * @param {Object} $0 Options + * @param {string} $0.clientId Block client ID. + * @param {string} $0.identifier Block attribute. + * @param {boolean} $0.withoutInteractiveFormatting Whether to clean the interactive formattings or not. + * @param {Array} $0.allowedFormats Allowed formats */ -export function useFormatTypes( { clientId, identifier } ) { - const formatTypes = useSelect( formatTypesSelector, [] ); +export function useFormatTypes( { + clientId, + identifier, + withoutInteractiveFormatting, + allowedFormats, +} ) { + const allFormatTypes = useSelect( formatTypesSelector, [] ); + const formatTypes = useMemo( () => { + return allFormatTypes.filter( ( { name, tagName } ) => { + if ( allowedFormats && allowedFormats.includes( name ) ) { + return false; + } + + if ( + withoutInteractiveFormatting && + interactiveContentTags.has( tagName ) + ) { + return false; + } + + return true; + } ); + }, [ allFormatTypes, allowedFormats, interactiveContentTags ] ); const keyedSelected = useSelect( ( select ) => formatTypes.reduce( ( accumulator, type ) => { From 83714e65c68b2ecc17b3a1b69256d1a789eb8a33 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 12 Jan 2021 13:26:17 +0100 Subject: [PATCH 2/2] Fix import --- packages/rich-text/src/component/index.native.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rich-text/src/component/index.native.js b/packages/rich-text/src/component/index.native.js index 1222971a9d418..eadf904abaf8d 100644 --- a/packages/rich-text/src/component/index.native.js +++ b/packages/rich-text/src/component/index.native.js @@ -32,7 +32,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import useFormatTypes from './use-format-types'; +import { useFormatTypes } from './use-format-types'; import FormatEdit from './format-edit'; import { applyFormat } from '../apply-format'; import { getActiveFormat } from '../get-active-format';