From 1e744fb2c44ec668fe560c8e26dd6a85fbd1ac8d Mon Sep 17 00:00:00 2001
From: Andrew Serong <14988353+andrewserong@users.noreply.github.com>
Date: Thu, 12 Oct 2023 12:22:47 +1100
Subject: [PATCH 1/4] useBlockPreview: Try alternative fix for displaying local
style overrides
---
.../src/components/block-preview/index.js | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/packages/block-editor/src/components/block-preview/index.js b/packages/block-editor/src/components/block-preview/index.js
index cf0937507be095..64ad0a65feb89d 100644
--- a/packages/block-editor/src/components/block-preview/index.js
+++ b/packages/block-editor/src/components/block-preview/index.js
@@ -16,6 +16,7 @@ import deprecated from '@wordpress/deprecated';
*/
import { ExperimentalBlockEditorProvider } from '../provider';
import AutoHeightBlockPreview from './auto';
+import EditorStyles from '../editor-styles';
import { store as blockEditorStore } from '../../store';
import { BlockListItems } from '../block-list';
@@ -92,6 +93,17 @@ export function BlockPreview( {
*/
export default memo( BlockPreview );
+function InnerStyles() {
+ const { styles } = useSelect( ( select ) => {
+ const settings = select( blockEditorStore ).getSettings();
+ return {
+ styles: settings.styles,
+ };
+ }, [] );
+
+ return ;
+}
+
/**
* This hook is used to lightly mark an element as a block preview wrapper
* element. Call this hook and pass the returned props to the element to mark as
@@ -128,6 +140,7 @@ export function useBlockPreview( { blocks, props = {}, layout } ) {
value={ renderedBlocks }
settings={ settings }
>
+
);
From 1d036833fd6b1d9761bcfcdce1e9985cb0e4ef0f Mon Sep 17 00:00:00 2001
From: Andrew Serong <14988353+andrewserong@users.noreply.github.com>
Date: Fri, 13 Oct 2023 12:26:56 +1100
Subject: [PATCH 2/4] Avoid duplicate styles, fix rendering issues in Safari
---
.../src/components/block-preview/index.js | 6 +++-
packages/block-editor/src/hooks/duotone.js | 33 +++++++++++++++++++
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/packages/block-editor/src/components/block-preview/index.js b/packages/block-editor/src/components/block-preview/index.js
index 64ad0a65feb89d..1cbb3513dbd8ba 100644
--- a/packages/block-editor/src/components/block-preview/index.js
+++ b/packages/block-editor/src/components/block-preview/index.js
@@ -125,7 +125,11 @@ export function useBlockPreview( { blocks, props = {}, layout } ) {
[]
);
const settings = useMemo(
- () => ( { ...originalSettings, __unstableIsPreviewMode: true } ),
+ () => ( {
+ ...originalSettings,
+ styles: undefined,
+ __unstableIsPreviewMode: true,
+ } ),
[ originalSettings ]
);
const disabledRef = useDisabled();
diff --git a/packages/block-editor/src/hooks/duotone.js b/packages/block-editor/src/hooks/duotone.js
index 2bbe18793fe558..39a8979782a0c6 100644
--- a/packages/block-editor/src/hooks/duotone.js
+++ b/packages/block-editor/src/hooks/duotone.js
@@ -37,11 +37,22 @@ import { scopeSelector } from '../components/global-styles/utils';
import { useBlockSettings } from './utils';
import { default as StylesFiltersPanel } from '../components/global-styles/filters-panel';
import { useBlockEditingMode } from '../components/block-editing-mode';
+import { __unstableUseBlockElement as useBlockElement } from '../components/block-list/use-block-props/use-block-refs';
import { store as blockEditorStore } from '../store';
import { unlock } from '../lock-unlock';
const EMPTY_ARRAY = [];
+// Safari does not always update the duotone filter when the duotone colors
+// are changed. This browser check is later used to force a re-render of the block
+// element to ensure the duotone filter is updated. The check is included at the
+// root of this file as it only needs to be run once per page load.
+const isSafari =
+ window?.navigator.userAgent &&
+ window.navigator.userAgent.includes( 'Safari' ) &&
+ ! window.navigator.userAgent.includes( 'Chrome' ) &&
+ ! window.navigator.userAgent.includes( 'Chromium' );
+
extend( [ namesPlugin ] );
function useMultiOriginPresets( { presetSetting, defaultSetting } ) {
@@ -223,6 +234,7 @@ const withDuotoneControls = createHigherOrderComponent(
);
function DuotoneStyles( {
+ clientId,
id: filterId,
selector: duotoneSelector,
attribute: duotoneAttr,
@@ -278,6 +290,8 @@ function DuotoneStyles( {
useDispatch( blockEditorStore )
);
+ const blockElement = useBlockElement( clientId );
+
useEffect( () => {
if ( ! isValidFilter ) return;
@@ -294,12 +308,30 @@ function DuotoneStyles( {
__unstableType: 'svgs',
} );
+ // Safari does not always update the duotone filter when the duotone colors
+ // are changed. When using Safari, force the block element to be repainted by
+ // the browser to ensure any changes are reflected visually. This logic matches
+ // that used on the site frontend in `block-supports/duotone.php`.
+ if ( blockElement && isSafari ) {
+ const display = blockElement.style.display;
+ // Switch to `inline-block` to force a repaint. In the editor, `inline-block`
+ // is used instead of `none` to ensure that scroll position is not affected,
+ // as `none` results in the editor scrolling to the top of the block.
+ blockElement.style.display = 'inline-block';
+ // Simply accessing el.offsetHeight flushes layout and style
+ // changes in WebKit without having to wait for setTimeout.
+ // eslint-disable-next-line no-unused-expressions
+ blockElement.offsetHeight;
+ blockElement.style.display = display;
+ }
+
return () => {
deleteStyleOverride( filterId );
deleteStyleOverride( `duotone-${ filterId }` );
};
}, [
isValidFilter,
+ blockElement,
colors,
selector,
filterId,
@@ -378,6 +410,7 @@ const withDuotoneStyles = createHigherOrderComponent(
<>
{ shouldRender && (
Date: Fri, 13 Oct 2023 15:46:07 +1100
Subject: [PATCH 3/4] Add more explanatory comments
---
packages/block-editor/src/components/block-preview/index.js | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/packages/block-editor/src/components/block-preview/index.js b/packages/block-editor/src/components/block-preview/index.js
index 1cbb3513dbd8ba..994347e5522673 100644
--- a/packages/block-editor/src/components/block-preview/index.js
+++ b/packages/block-editor/src/components/block-preview/index.js
@@ -95,6 +95,9 @@ export default memo( BlockPreview );
function InnerStyles() {
const { styles } = useSelect( ( select ) => {
+ // Retrieve settings (and styles) from the preview's block editor store.
+ // Since `useBlockPreview` has already cleared out the parent's styles,
+ // these styles should only contain styles generated by the preview.
const settings = select( blockEditorStore ).getSettings();
return {
styles: settings.styles,
@@ -127,7 +130,7 @@ export function useBlockPreview( { blocks, props = {}, layout } ) {
const settings = useMemo(
() => ( {
...originalSettings,
- styles: undefined,
+ styles: undefined, // Clear styles included by the parent settings, as they are already output by the parent's EditorStyles.
__unstableIsPreviewMode: true,
} ),
[ originalSettings ]
From f07605589cb301bfbf0bd3320c15efc75650f732 Mon Sep 17 00:00:00 2001
From: Andrew Serong <14988353+andrewserong@users.noreply.github.com>
Date: Mon, 16 Oct 2023 09:05:07 +1100
Subject: [PATCH 4/4] Remove additional check for styles within the block
preview, as it is not needed since EditorStyles handles its own style
overrides retrieval
---
.../src/components/block-preview/index.js | 16 +---------------
1 file changed, 1 insertion(+), 15 deletions(-)
diff --git a/packages/block-editor/src/components/block-preview/index.js b/packages/block-editor/src/components/block-preview/index.js
index 994347e5522673..0fb7f55b9955d2 100644
--- a/packages/block-editor/src/components/block-preview/index.js
+++ b/packages/block-editor/src/components/block-preview/index.js
@@ -93,20 +93,6 @@ export function BlockPreview( {
*/
export default memo( BlockPreview );
-function InnerStyles() {
- const { styles } = useSelect( ( select ) => {
- // Retrieve settings (and styles) from the preview's block editor store.
- // Since `useBlockPreview` has already cleared out the parent's styles,
- // these styles should only contain styles generated by the preview.
- const settings = select( blockEditorStore ).getSettings();
- return {
- styles: settings.styles,
- };
- }, [] );
-
- return ;
-}
-
/**
* This hook is used to lightly mark an element as a block preview wrapper
* element. Call this hook and pass the returned props to the element to mark as
@@ -147,7 +133,7 @@ export function useBlockPreview( { blocks, props = {}, layout } ) {
value={ renderedBlocks }
settings={ settings }
>
-
+
);