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

Parser: Update validateBlock to use fixedBlock #62178

Merged
merged 4 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 22 additions & 19 deletions packages/blocks/src/api/parser/fix-custom-classname.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
2 changes: 1 addition & 1 deletion packages/blocks/src/api/parser/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
);

Expand Down
32 changes: 32 additions & 0 deletions packages/blocks/src/api/parser/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,38 @@ 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
<div class={ attributes.className }>
Copy link
Contributor

Choose a reason for hiding this comment

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

If I'm not wrong there's no need to use attributes.className here as it should be done automatically no?

Copy link
Contributor Author

@tjcafferkey tjcafferkey Jun 4, 2024

Choose a reason for hiding this comment

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

I thought so too, but apparently not.

{ attributes.fruit }
</div>
),
} );

const block = parseRawBlock( {
blockName: 'core/test-block',
innerHTML:
'<div class="custom-class another-custom-class">Bananas</div>',
attrs: { fruit: 'Bananas' },
} );

expect( block.name ).toEqual( 'core/test-block' );
expect( block.attributes ).toEqual( {
fruit: 'Bananas',
className: 'custom-class another-custom-class',
} );
} );

it( 'should create the requested block if it exists', () => {
registerBlockType( 'core/test-block', defaultBlockSettings );

Expand Down
Loading