diff --git a/packages/core-data/src/entities.js b/packages/core-data/src/entities.js index f22010c58dddc6..c1783c85850b31 100644 --- a/packages/core-data/src/entities.js +++ b/packages/core-data/src/entities.js @@ -18,6 +18,8 @@ import { STORE_NAME } from './name'; export const DEFAULT_ENTITY_KEY = 'id'; +const POST_RAW_ATTRIBUTES = [ 'title', 'excerpt', 'content' ]; + export const defaultEntities = [ { label: __( 'Base' ), @@ -41,6 +43,7 @@ export const defaultEntities = [ key: 'slug', baseURL: '/wp/v2/types', baseURLParams: { context: 'edit' }, + rawAttributes: POST_RAW_ATTRIBUTES, }, { name: 'media', @@ -184,6 +187,7 @@ function* loadPostTypeEntities() { selection: true, }, mergedEdits: { meta: true }, + rawAttributes: POST_RAW_ATTRIBUTES, getTitle: ( record ) => record?.title?.rendered || record?.title || diff --git a/packages/core-data/src/selectors.js b/packages/core-data/src/selectors.js index a7bb82da615ab8..b3ab91d780960c 100644 --- a/packages/core-data/src/selectors.js +++ b/packages/core-data/src/selectors.js @@ -17,7 +17,7 @@ import deprecated from '@wordpress/deprecated'; import { STORE_NAME } from './name'; import { getQueriedItems } from './queried-data'; import { DEFAULT_ENTITY_KEY } from './entities'; -import { getNormalizedCommaSeparable } from './utils'; +import { getNormalizedCommaSeparable, isRawAttribute } from './utils'; /** * Shared reference to an empty array for cases where it is important to avoid @@ -205,14 +205,18 @@ export const getRawEntityRecord = createSelector( return ( record && Object.keys( record ).reduce( ( accumulator, _key ) => { - // Because edits are the "raw" attribute values, - // we return those from record selectors to make rendering, - // comparisons, and joins with edits easier. - accumulator[ _key ] = get( - record[ _key ], - 'raw', - record[ _key ] - ); + if ( isRawAttribute( getEntity( state, kind, name ), _key ) ) { + // Because edits are the "raw" attribute values, + // we return those from record selectors to make rendering, + // comparisons, and joins with edits easier. + accumulator[ _key ] = get( + record[ _key ], + 'raw', + record[ _key ] + ); + } else { + accumulator[ _key ] = record[ _key ]; + } return accumulator; }, {} ) ); diff --git a/packages/core-data/src/test/selectors.js b/packages/core-data/src/test/selectors.js index 586d39985e0c56..f76d60a09a4ab7 100644 --- a/packages/core-data/src/test/selectors.js +++ b/packages/core-data/src/test/selectors.js @@ -11,6 +11,7 @@ import { __experimentalGetEntityRecordNoResolver, hasEntityRecords, getEntityRecords, + getRawEntityRecord, __experimentalGetDirtyEntityRecords, __experimentalGetEntitiesBeingSaved, getEntityRecordNonTransientEdits, @@ -204,6 +205,76 @@ describe( 'hasEntityRecords', () => { } ); } ); +describe( 'getRawEntityRecord', () => { + const data = { + someKind: { + someName: { + queriedData: { + items: { + default: { + post: { + title: { + raw: { html: '

post

' }, + rendered: + '

rendered post

', + }, + }, + }, + }, + itemIsComplete: { + default: { + post: true, + }, + }, + queries: {}, + }, + }, + }, + }; + it( 'should preserve the structure of `raw` field by default', () => { + const state = deepFreeze( { + entities: { + config: [ + { + kind: 'someKind', + name: 'someName', + }, + ], + data: { ...data }, + }, + } ); + expect( + getRawEntityRecord( state, 'someKind', 'someName', 'post' ) + ).toEqual( { + title: { + raw: { html: '

post

' }, + rendered: '

rendered post

', + }, + } ); + } ); + it( 'should flatten the structure of `raw` field for entities configured with rawAttributes', () => { + const state = deepFreeze( { + entities: { + config: [ + { + kind: 'someKind', + name: 'someName', + rawAttributes: [ 'title' ], + }, + ], + data: { ...data }, + }, + } ); + expect( + getRawEntityRecord( state, 'someKind', 'someName', 'post' ) + ).toEqual( { + title: { + html: '

post

', + }, + } ); + } ); +} ); + describe( 'getEntityRecords', () => { it( 'should return null by default', () => { const state = deepFreeze( { diff --git a/packages/core-data/src/utils/index.js b/packages/core-data/src/utils/index.js index 05e8d73bf7630f..a4f4bf81373cd6 100644 --- a/packages/core-data/src/utils/index.js +++ b/packages/core-data/src/utils/index.js @@ -5,3 +5,4 @@ export { default as ifNotResolved } from './if-not-resolved'; export { default as onSubKey } from './on-sub-key'; export { default as replaceAction } from './replace-action'; export { default as withWeakMapCache } from './with-weak-map-cache'; +export { default as isRawAttribute } from './is-raw-attribute'; diff --git a/packages/core-data/src/utils/is-raw-attribute.js b/packages/core-data/src/utils/is-raw-attribute.js new file mode 100644 index 00000000000000..f8e8d4de359a43 --- /dev/null +++ b/packages/core-data/src/utils/is-raw-attribute.js @@ -0,0 +1,11 @@ +/** + * Checks whether the attribute is a "raw" attribute or not. + * + * @param {Object} entity Entity data. + * @param {string} attribute Attribute name. + * + * @return {boolean} Is the attribute raw + */ +export default function isRawAttribute( entity, attribute ) { + return ( entity.rawAttributes || [] ).includes( attribute ); +} diff --git a/packages/core-data/src/utils/test/is-raw-attribute.js b/packages/core-data/src/utils/test/is-raw-attribute.js new file mode 100644 index 00000000000000..545fd7c84286fc --- /dev/null +++ b/packages/core-data/src/utils/test/is-raw-attribute.js @@ -0,0 +1,22 @@ +/** + * Internal dependencies + */ +import { isRawAttribute } from '../'; + +describe( 'isRawAttribute', () => { + it( 'should correctly assess that the attribute is not raw', () => { + const entity = { + kind: 'someKind', + name: 'someName', + }; + expect( isRawAttribute( entity, 'title' ) ).toBe( false ); + } ); + it( 'should correctly assess that the attribute is raw', () => { + const entity = { + kind: 'someKind', + name: 'someName', + rawAttributes: [ 'title' ], + }; + expect( isRawAttribute( entity, 'title' ) ).toBe( true ); + } ); +} ); diff --git a/packages/editor/src/components/provider/index.native.js b/packages/editor/src/components/provider/index.native.js index 470a8fdf729ef7..6cdf848cfe69fb 100644 --- a/packages/editor/src/components/provider/index.native.js +++ b/packages/editor/src/components/provider/index.native.js @@ -54,6 +54,7 @@ const postTypeEntities = [ mergedEdits: { meta: true, }, + rawAttributes: [ 'title', 'excerpt', 'content' ], } ) ); import { EditorHelpTopics } from '@wordpress/editor';