Skip to content

Commit 662697a

Browse files
authored
useBlockPreview: Try outputting EditorStyles to ensure local style overrides are rendered (#55288)
* useBlockPreview: Try alternative fix for displaying local style overrides * Avoid duplicate styles, fix rendering issues in Safari * Add more explanatory comments * Remove additional check for styles within the block preview, as it is not needed since EditorStyles handles its own style overrides retrieval
1 parent b1b2974 commit 662697a

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

packages/block-editor/src/components/block-preview/index.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import deprecated from '@wordpress/deprecated';
1616
*/
1717
import { ExperimentalBlockEditorProvider } from '../provider';
1818
import AutoHeightBlockPreview from './auto';
19+
import EditorStyles from '../editor-styles';
1920
import { store as blockEditorStore } from '../../store';
2021
import { BlockListItems } from '../block-list';
2122

@@ -113,7 +114,11 @@ export function useBlockPreview( { blocks, props = {}, layout } ) {
113114
[]
114115
);
115116
const settings = useMemo(
116-
() => ( { ...originalSettings, __unstableIsPreviewMode: true } ),
117+
() => ( {
118+
...originalSettings,
119+
styles: undefined, // Clear styles included by the parent settings, as they are already output by the parent's EditorStyles.
120+
__unstableIsPreviewMode: true,
121+
} ),
117122
[ originalSettings ]
118123
);
119124
const disabledRef = useDisabled();
@@ -128,6 +133,7 @@ export function useBlockPreview( { blocks, props = {}, layout } ) {
128133
value={ renderedBlocks }
129134
settings={ settings }
130135
>
136+
<EditorStyles />
131137
<BlockListItems renderAppender={ false } layout={ layout } />
132138
</ExperimentalBlockEditorProvider>
133139
);

packages/block-editor/src/hooks/duotone.js

+33
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,22 @@ import { scopeSelector } from '../components/global-styles/utils';
3737
import { useBlockSettings } from './utils';
3838
import { default as StylesFiltersPanel } from '../components/global-styles/filters-panel';
3939
import { useBlockEditingMode } from '../components/block-editing-mode';
40+
import { __unstableUseBlockElement as useBlockElement } from '../components/block-list/use-block-props/use-block-refs';
4041
import { store as blockEditorStore } from '../store';
4142
import { unlock } from '../lock-unlock';
4243

4344
const EMPTY_ARRAY = [];
4445

46+
// Safari does not always update the duotone filter when the duotone colors
47+
// are changed. This browser check is later used to force a re-render of the block
48+
// element to ensure the duotone filter is updated. The check is included at the
49+
// root of this file as it only needs to be run once per page load.
50+
const isSafari =
51+
window?.navigator.userAgent &&
52+
window.navigator.userAgent.includes( 'Safari' ) &&
53+
! window.navigator.userAgent.includes( 'Chrome' ) &&
54+
! window.navigator.userAgent.includes( 'Chromium' );
55+
4556
extend( [ namesPlugin ] );
4657

4758
function useMultiOriginPresets( { presetSetting, defaultSetting } ) {
@@ -223,6 +234,7 @@ const withDuotoneControls = createHigherOrderComponent(
223234
);
224235

225236
function DuotoneStyles( {
237+
clientId,
226238
id: filterId,
227239
selector: duotoneSelector,
228240
attribute: duotoneAttr,
@@ -278,6 +290,8 @@ function DuotoneStyles( {
278290
useDispatch( blockEditorStore )
279291
);
280292

293+
const blockElement = useBlockElement( clientId );
294+
281295
useEffect( () => {
282296
if ( ! isValidFilter ) return;
283297

@@ -294,12 +308,30 @@ function DuotoneStyles( {
294308
__unstableType: 'svgs',
295309
} );
296310

311+
// Safari does not always update the duotone filter when the duotone colors
312+
// are changed. When using Safari, force the block element to be repainted by
313+
// the browser to ensure any changes are reflected visually. This logic matches
314+
// that used on the site frontend in `block-supports/duotone.php`.
315+
if ( blockElement && isSafari ) {
316+
const display = blockElement.style.display;
317+
// Switch to `inline-block` to force a repaint. In the editor, `inline-block`
318+
// is used instead of `none` to ensure that scroll position is not affected,
319+
// as `none` results in the editor scrolling to the top of the block.
320+
blockElement.style.display = 'inline-block';
321+
// Simply accessing el.offsetHeight flushes layout and style
322+
// changes in WebKit without having to wait for setTimeout.
323+
// eslint-disable-next-line no-unused-expressions
324+
blockElement.offsetHeight;
325+
blockElement.style.display = display;
326+
}
327+
297328
return () => {
298329
deleteStyleOverride( filterId );
299330
deleteStyleOverride( `duotone-${ filterId }` );
300331
};
301332
}, [
302333
isValidFilter,
334+
blockElement,
303335
colors,
304336
selector,
305337
filterId,
@@ -378,6 +410,7 @@ const withDuotoneStyles = createHigherOrderComponent(
378410
<>
379411
{ shouldRender && (
380412
<DuotoneStyles
413+
clientId={ props.clientId }
381414
id={ filterClass }
382415
selector={ selector }
383416
attribute={ attribute }

0 commit comments

Comments
 (0)