From 2fa81163e0f99291a8bb116d709f173b76520aa5 Mon Sep 17 00:00:00 2001 From: Tom Cafferkey Date: Fri, 31 May 2024 11:38:01 +0100 Subject: [PATCH 1/4] Run validateBlock against fixedBlock --- packages/blocks/src/api/parser/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/blocks/src/api/parser/index.js b/packages/blocks/src/api/parser/index.js index f8ff0c68964dc..14a88f602987a 100644 --- a/packages/blocks/src/api/parser/index.js +++ b/packages/blocks/src/api/parser/index.js @@ -178,7 +178,7 @@ function applyBlockValidation( unvalidatedBlock, blockType ) { ); // Attempt to validate the block once again after the built-in fixes. const [ isFixedValid, validationIssues ] = validateBlock( - unvalidatedBlock, + fixedBlock, blockType ); From 982e93440e5c2495e9933be6f9e63a5c77be76cf Mon Sep 17 00:00:00 2001 From: Tom Cafferkey Date: Tue, 4 Jun 2024 15:00:08 +0100 Subject: [PATCH 2/4] Unit test for block validation applying customClassNames --- packages/blocks/src/api/parser/test/index.js | 31 ++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/packages/blocks/src/api/parser/test/index.js b/packages/blocks/src/api/parser/test/index.js index 85e51e9d0af02..66769fc46602e 100644 --- a/packages/blocks/src/api/parser/test/index.js +++ b/packages/blocks/src/api/parser/test/index.js @@ -50,6 +50,37 @@ describe( 'block parser', () => { } ); describe( 'parseRawBlock', () => { + it( 'should apply className block validation fixes', () => { + registerBlockType( 'core/test-block', { + ...defaultBlockSettings, + attributes: { + fruit: { + type: 'string', + source: 'text', + selector: 'div', + }, + }, + save: ( { attributes } ) => ( + // eslint-disable-next-line react/no-unknown-property +
+ { attributes.fruit } +
+ ), + } ); + + const block = parseRawBlock( { + blockName: 'core/test-block', + innerHTML: '
Bananas
', + attrs: { fruit: 'Bananas' }, + } ); + + expect( block.name ).toEqual( 'core/test-block' ); + expect( block.attributes ).toEqual( { + fruit: 'Bananas', + className: 'custom-class', + } ); + } ); + it( 'should create the requested block if it exists', () => { registerBlockType( 'core/test-block', defaultBlockSettings ); From c18c7dba53f5edf78f970ddfe9557bf17956f40d Mon Sep 17 00:00:00 2001 From: Tom Cafferkey Date: Tue, 4 Jun 2024 15:01:42 +0100 Subject: [PATCH 3/4] Add another custom class to the unit test --- packages/blocks/src/api/parser/test/index.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/blocks/src/api/parser/test/index.js b/packages/blocks/src/api/parser/test/index.js index 66769fc46602e..42923a7d3eeb3 100644 --- a/packages/blocks/src/api/parser/test/index.js +++ b/packages/blocks/src/api/parser/test/index.js @@ -70,14 +70,15 @@ describe( 'block parser', () => { const block = parseRawBlock( { blockName: 'core/test-block', - innerHTML: '
Bananas
', + innerHTML: + '
Bananas
', attrs: { fruit: 'Bananas' }, } ); expect( block.name ).toEqual( 'core/test-block' ); expect( block.attributes ).toEqual( { fruit: 'Bananas', - className: 'custom-class', + className: 'custom-class another-custom-class', } ); } ); From 246eb14005e3fdfa6451aacce88d255bebb3f5d9 Mon Sep 17 00:00:00 2001 From: Tom Cafferkey Date: Tue, 4 Jun 2024 15:43:48 +0100 Subject: [PATCH 4/4] Avoid mutating blockAttributes --- .../src/api/parser/fix-custom-classname.js | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/packages/blocks/src/api/parser/fix-custom-classname.js b/packages/blocks/src/api/parser/fix-custom-classname.js index d72065cd59222..78f04ea4a00fa 100644 --- a/packages/blocks/src/api/parser/fix-custom-classname.js +++ b/packages/blocks/src/api/parser/fix-custom-classname.js @@ -42,27 +42,30 @@ export function getHTMLRootElementClasses( innerHTML ) { * @return {Object} Filtered block attributes. */ export function fixCustomClassname( blockAttributes, blockType, innerHTML ) { - if ( hasBlockSupport( blockType, 'customClassName', true ) ) { - // To determine difference, serialize block given the known set of - // attributes, with the exception of `className`. This will determine - // the default set of classes. From there, any difference in innerHTML - // can be considered as custom classes. - const { className: omittedClassName, ...attributesSansClassName } = - blockAttributes; - const serialized = getSaveContent( blockType, attributesSansClassName ); - const defaultClasses = getHTMLRootElementClasses( serialized ); - const actualClasses = getHTMLRootElementClasses( innerHTML ); + if ( ! hasBlockSupport( blockType, 'customClassName', true ) ) { + return blockAttributes; + } + + const modifiedBlockAttributes = { ...blockAttributes }; + // To determine difference, serialize block given the known set of + // attributes, with the exception of `className`. This will determine + // the default set of classes. From there, any difference in innerHTML + // can be considered as custom classes. + const { className: omittedClassName, ...attributesSansClassName } = + modifiedBlockAttributes; + const serialized = getSaveContent( blockType, attributesSansClassName ); + const defaultClasses = getHTMLRootElementClasses( serialized ); + const actualClasses = getHTMLRootElementClasses( innerHTML ); - const customClasses = actualClasses.filter( - ( className ) => ! defaultClasses.includes( className ) - ); + const customClasses = actualClasses.filter( + ( className ) => ! defaultClasses.includes( className ) + ); - if ( customClasses.length ) { - blockAttributes.className = customClasses.join( ' ' ); - } else if ( serialized ) { - delete blockAttributes.className; - } + if ( customClasses.length ) { + modifiedBlockAttributes.className = customClasses.join( ' ' ); + } else if ( serialized ) { + delete modifiedBlockAttributes.className; } - return blockAttributes; + return modifiedBlockAttributes; }