diff --git a/packages/dom/src/dom/clean-node-list.js b/packages/dom/src/dom/clean-node-list.js index c6ef7f658f2b98..8d1e0e9dfac4d7 100644 --- a/packages/dom/src/dom/clean-node-list.js +++ b/packages/dom/src/dom/clean-node-list.js @@ -52,9 +52,14 @@ export default function cleanNodeList( nodeList, doc, schema, inline ) { } = schema[ tag ]; // If the node is empty and it's supposed to have children, - // remove the node. + // remove the node. For phrasing content, unwrap instead to + // preserve any whitespace content (e.g. between words). if ( children && ! allowEmpty && isEmpty( node ) ) { - remove( node ); + if ( isPhrasingContent( node ) ) { + unwrap( node ); + } else { + remove( node ); + } return; } diff --git a/packages/dom/src/dom/test/clean-node-list.js b/packages/dom/src/dom/test/clean-node-list.js new file mode 100644 index 00000000000000..8ab38492525db3 --- /dev/null +++ b/packages/dom/src/dom/test/clean-node-list.js @@ -0,0 +1,59 @@ +/** + * Internal dependencies + */ +import removeInvalidHTML from '../remove-invalid-html'; + +describe( 'cleanNodeList', () => { + it( 'should preserve whitespace when unwrapping empty phrasing elements', () => { + const schema = { + p: { children: { '#text': {} } }, + }; + // Whitespace inside should be preserved when is unwrapped. + const input = '
some text more text
'; + const output = 'some text more text
'; + expect( removeInvalidHTML( input, schema, false ) ).toEqual( output ); + } ); + + it( 'should preserve whitespace in various phrasing elements', () => { + const schema = { + p: { children: { '#text': {} } }, + }; + // Test with different phrasing elements. + expect( + removeInvalidHTML( + 'hello world
', + schema, + false + ) + ).toEqual( 'hello world
' ); + expect( + removeInvalidHTML( 'hello world
', schema, false ) + ).toEqual( 'hello world
' ); + expect( + removeInvalidHTML( 'hello world
', schema, false ) + ).toEqual( 'hello world
' ); + } ); + + it( 'should remove truly empty elements without whitespace', () => { + const schema = { + p: { children: { '#text': {} } }, + }; + const input = 'some textmore text
'; + const output = 'some textmore text
'; + expect( removeInvalidHTML( input, schema, false ) ).toEqual( output ); + } ); + + it( 'should remove empty block elements entirely (not unwrap)', () => { + const schema = { + figure: { + children: { + img: {}, + }, + }, + }; + // Block elements like figure should be removed, not unwrapped. + const input = '