diff --git a/packages/rich-text/src/normalise-formats.js b/packages/rich-text/src/normalise-formats.js index 349540df9dc256..24690f089b4c76 100644 --- a/packages/rich-text/src/normalise-formats.js +++ b/packages/rich-text/src/normalise-formats.js @@ -17,7 +17,7 @@ export function normaliseFormats( { formats, text, start, end } ) { newFormats.forEach( ( formatsAtIndex, index ) => { const lastFormatsAtIndex = newFormats[ index - 1 ]; - if ( lastFormatsAtIndex ) { + if ( lastFormatsAtIndex && formatsAtIndex ) { const newFormatsAtIndex = formatsAtIndex.slice( 0 ); newFormatsAtIndex.forEach( ( format, formatIndex ) => { @@ -29,6 +29,8 @@ export function normaliseFormats( { formats, text, start, end } ) { } ); newFormats[ index ] = newFormatsAtIndex; + } else if ( ! formatsAtIndex ) { + delete newFormats[ index ]; } } ); diff --git a/packages/rich-text/src/test/normalise-formats.js b/packages/rich-text/src/test/normalise-formats.js index 8984bcb17771b8..f0a1b827d264d5 100644 --- a/packages/rich-text/src/test/normalise-formats.js +++ b/packages/rich-text/src/test/normalise-formats.js @@ -13,19 +13,36 @@ import { getSparseArrayLength } from './helpers'; describe( 'normaliseFormats', () => { const strong = { type: 'strong' }; const em = { type: 'em' }; + const record = deepFreeze( { + formats: [ , [ em ], [ { ...em }, { ...strong } ], [ em, strong ], , , ], + text: 'one two', + } ); - it( 'should normalise formats', () => { - const record = { - formats: [ , [ em ], [ { ...em }, { ...strong } ], [ em, strong ] ], - text: 'one two three', - }; - const result = normaliseFormats( deepFreeze( record ) ); - - expect( result ).toEqual( record ); - expect( result ).not.toBe( record ); + function isNormalised( result ) { expect( getSparseArrayLength( result.formats ) ).toBe( 3 ); expect( result.formats[ 1 ][ 0 ] ).toBe( result.formats[ 2 ][ 0 ] ); expect( result.formats[ 1 ][ 0 ] ).toBe( result.formats[ 3 ][ 0 ] ); expect( result.formats[ 2 ][ 1 ] ).toBe( result.formats[ 3 ][ 1 ] ); + } + + it( 'should normalise formats', () => { + const result = normaliseFormats( record ); + + expect( result ).toEqual( record ); + expect( result ).not.toBe( record ); + isNormalised( result ); + } ); + + it( 'should be serializable', () => { + const result = normaliseFormats( record ); + expect( JSON.stringify( record ) ).toBe( JSON.stringify( result ) ); + } ); + + it( 'should normalise serialized formats', () => { + const deserialized = JSON.parse( JSON.stringify( record ) ); + const result = normaliseFormats( deserialized ); + + expect( result ).toEqual( record ); + isNormalised( result ); } ); } ); diff --git a/packages/rich-text/src/test/to-html-string.js b/packages/rich-text/src/test/to-html-string.js index a65c3cb772447d..eaef8f2f651b62 100644 --- a/packages/rich-text/src/test/to-html-string.js +++ b/packages/rich-text/src/test/to-html-string.js @@ -78,4 +78,15 @@ describe( 'toHTMLString', () => { expect( toHTMLString( create( { element } ) ) ).toEqual( expectedHTML ); } ); + + it( 'should be able to work from serialized value (without references)', () => { + expect( toHTMLString( { + text: 'abc', + formats: [ + null, + [ { type: 'strong' } ], + null, + ], + } ) ).toEqual( 'abc' ); + } ); } ); diff --git a/packages/rich-text/src/to-tree.js b/packages/rich-text/src/to-tree.js index c1ced44a16c6b1..0681de01e35f27 100644 --- a/packages/rich-text/src/to-tree.js +++ b/packages/rich-text/src/to-tree.js @@ -3,6 +3,7 @@ */ import { split } from './split'; +import { normaliseFormats } from './normalise-formats'; export function toTree( value, multilineTag, settings ) { if ( multilineTag ) { @@ -35,7 +36,7 @@ export function toTree( value, multilineTag, settings ) { onEndIndex, onEmpty, } = settings; - const { formats, text, start, end } = value; + const { formats, text, start, end } = normaliseFormats( value ); const formatsLength = formats.length + 1; const tree = createEmpty( tag );