Skip to content

Commit 1c0d02f

Browse files
authored
Expose before filter hook in useSettings and the block metadata for CSS classes generation (#45089)
1 parent 68ee410 commit 1c0d02f

File tree

2 files changed

+112
-1
lines changed

2 files changed

+112
-1
lines changed

packages/block-editor/src/components/use-setting/index.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
__EXPERIMENTAL_PATHS_WITH_MERGE as PATHS_WITH_MERGE,
1212
hasBlockSupport,
1313
} from '@wordpress/blocks';
14+
import { applyFilters } from '@wordpress/hooks';
1415

1516
/**
1617
* Internal dependencies
@@ -122,7 +123,18 @@ export default function useSetting( path ) {
122123
return undefined;
123124
}
124125

125-
let result;
126+
// 0. Allow third parties to filter the block's settings at runtime.
127+
let result = applyFilters(
128+
'blockEditor.useSetting.before',
129+
undefined,
130+
path,
131+
clientId,
132+
blockName
133+
);
134+
135+
if ( undefined !== result ) {
136+
return result;
137+
}
126138

127139
const normalizedPath = removeCustomPrefixes( path );
128140

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/**
2+
* WordPress dependencies
3+
*/
4+
import { addFilter, removeFilter } from '@wordpress/hooks';
5+
import { useSelect } from '@wordpress/data';
6+
7+
/**
8+
* Internal dependencies
9+
*/
10+
import useSetting from '..';
11+
import * as BlockEditContext from '../../block-edit/context';
12+
13+
// Mock useSelect() functions used by useSetting()
14+
jest.mock( '@wordpress/data/src/components/use-select' );
15+
16+
let selectMock = {};
17+
const setupSelectMock = () => {
18+
selectMock = {
19+
getSettings: () => ( {} ),
20+
getBlockParents: () => [],
21+
getBlockName: () => '',
22+
};
23+
};
24+
25+
useSelect.mockImplementation( ( callback ) => callback( () => selectMock ) );
26+
27+
const mockSettings = ( settings ) => {
28+
selectMock.getSettings = () => ( {
29+
__experimentalFeatures: settings,
30+
} );
31+
};
32+
33+
const mockCurrentBlockContext = (
34+
blockContext = { name: '', isSelected: false }
35+
) => {
36+
jest.spyOn( BlockEditContext, 'useBlockEditContext' ).mockReturnValue(
37+
blockContext
38+
);
39+
};
40+
41+
describe( 'useSetting', () => {
42+
beforeEach( () => {
43+
setupSelectMock();
44+
mockCurrentBlockContext();
45+
} );
46+
47+
it( 'uses block setting', () => {
48+
mockSettings( {
49+
blocks: {
50+
'core/test-block': {
51+
layout: {
52+
contentSize: '840px',
53+
},
54+
},
55+
},
56+
} );
57+
58+
mockCurrentBlockContext( {
59+
name: 'core/test-block',
60+
} );
61+
62+
expect( useSetting( 'layout.contentSize' ) ).toBe( '840px' );
63+
} );
64+
65+
it( 'uses blockEditor.useSetting.before hook override', () => {
66+
mockSettings( {
67+
blocks: {
68+
'core/test-block': {
69+
layout: {
70+
contentSize: '840px',
71+
},
72+
},
73+
},
74+
} );
75+
76+
mockCurrentBlockContext( {
77+
name: 'core/test-block',
78+
} );
79+
80+
addFilter(
81+
'blockEditor.useSetting.before',
82+
'test/useSetting.before',
83+
( result, path, clientId, blockName ) => {
84+
if ( blockName === 'core/test-block' ) {
85+
return '960px';
86+
}
87+
88+
return result;
89+
}
90+
);
91+
92+
expect( useSetting( 'layout.contentSize' ) ).toBe( '960px' );
93+
94+
removeFilter(
95+
'blockEditor.useSetting.before',
96+
'test/useSetting.before'
97+
);
98+
} );
99+
} );

0 commit comments

Comments
 (0)