From cd78f319198874ff06f3e96c53c127403dc58c79 Mon Sep 17 00:00:00 2001
From: Andrew Serong <14988353+andrewserong@users.noreply.github.com>
Date: Fri, 22 Oct 2021 17:11:43 +1100
Subject: [PATCH 1/9] Post Content Block: try rendering read only content as
blocks to preserve block supports styles
---
packages/block-library/src/post-content/edit.js | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/packages/block-library/src/post-content/edit.js b/packages/block-library/src/post-content/edit.js
index 4a0c277a1f5cfe..ec76a81264dba6 100644
--- a/packages/block-library/src/post-content/edit.js
+++ b/packages/block-library/src/post-content/edit.js
@@ -2,9 +2,10 @@
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
+import { parse } from '@wordpress/blocks';
import { useSelect } from '@wordpress/data';
-import { RawHTML } from '@wordpress/element';
import {
+ BlockPreview,
useBlockProps,
useInnerBlocksProps,
useSetting,
@@ -27,13 +28,20 @@ function ReadOnlyContent( { userCanEdit, postType, postId } ) {
postId
);
const blockProps = useBlockProps();
+
+ let blocks;
+
+ if ( content?.raw ) {
+ blocks = parse( content.raw );
+ }
+
return content?.protected && ! userCanEdit ? (
{ __( 'This content is password protected.' ) }
) : (
- { content?.rendered }
+
);
}
From 9a680bd8b4c4bdf25c37f759c398de54d313ec60 Mon Sep 17 00:00:00 2001
From: Andrew Serong <14988353+andrewserong@users.noreply.github.com>
Date: Mon, 25 Oct 2021 16:23:48 +1100
Subject: [PATCH 2/9] Prevent post content inner from being tabbable, fix
disabled styles, hide placeholders
---
.../src/components/block-preview/index.js | 6 +++++-
.../src/components/block-preview/live.js | 4 ++--
packages/block-library/src/editor.scss | 1 +
.../block-library/src/post-content/edit.js | 19 +++++++++++-------
.../src/post-content/editor.scss | 20 +++++++++++++++++++
5 files changed, 40 insertions(+), 10 deletions(-)
create mode 100644 packages/block-library/src/post-content/editor.scss
diff --git a/packages/block-editor/src/components/block-preview/index.js b/packages/block-editor/src/components/block-preview/index.js
index cea2e8ee9b62c0..2abe8636039e69 100644
--- a/packages/block-editor/src/components/block-preview/index.js
+++ b/packages/block-editor/src/components/block-preview/index.js
@@ -20,6 +20,7 @@ import { store as blockEditorStore } from '../../store';
export function BlockPreview( {
blocks,
__experimentalPadding = 0,
+ tabIndex = 0,
viewportWidth = 1200,
__experimentalLive = false,
__experimentalOnClick,
@@ -40,7 +41,10 @@ export function BlockPreview( {
return (
{ __experimentalLive ? (
-
+
) : (
{
+ return rawContent ? parse( rawContent ) : [];
+ }, [ rawContent ] );
return content?.protected && ! userCanEdit ? (
@@ -41,7 +41,12 @@ function ReadOnlyContent( { userCanEdit, postType, postId } ) {
) : (
-
+
);
}
diff --git a/packages/block-library/src/post-content/editor.scss b/packages/block-library/src/post-content/editor.scss
new file mode 100644
index 00000000000000..1b8570f28a1a24
--- /dev/null
+++ b/packages/block-library/src/post-content/editor.scss
@@ -0,0 +1,20 @@
+.wp-block-post-content {
+ &.is-readonly {
+ // Hide the block appender within the block, as the block is not editable in this context.
+ .block-list-appender {
+ display: none;
+ }
+
+ // Revert button disable styles to ensure that button styles render as they will on the
+ // front end of the site. For example, this ensures that Social Links icons display correctly.
+ .components-button:disabled {
+ opacity: initial;
+ }
+
+ // Hide placeholders.
+ .components-placeholder,
+ .block-editor-block-list__block[data-empty="true"] {
+ display: none;
+ }
+ }
+}
From 4a296d5489fe0e3a7f4e523319ae3af752870228 Mon Sep 17 00:00:00 2001
From: Andrew Serong <14988353+andrewserong@users.noreply.github.com>
Date: Wed, 27 Oct 2021 14:08:37 +1100
Subject: [PATCH 3/9] Remove tabIndex prop, replace with
__experimentalAsButton, move CSS styles to block-preview
---
.../src/components/block-preview/index.js | 4 ++--
.../src/components/block-preview/live.js | 21 +++++++++++++------
.../src/components/block-preview/style.scss | 19 +++++++++++++++++
packages/block-library/src/editor.scss | 1 -
.../block-library/src/post-content/edit.js | 1 +
.../src/post-content/editor.scss | 20 ------------------
6 files changed, 37 insertions(+), 29 deletions(-)
delete mode 100644 packages/block-library/src/post-content/editor.scss
diff --git a/packages/block-editor/src/components/block-preview/index.js b/packages/block-editor/src/components/block-preview/index.js
index 2abe8636039e69..ad1843da4cece2 100644
--- a/packages/block-editor/src/components/block-preview/index.js
+++ b/packages/block-editor/src/components/block-preview/index.js
@@ -20,8 +20,8 @@ import { store as blockEditorStore } from '../../store';
export function BlockPreview( {
blocks,
__experimentalPadding = 0,
- tabIndex = 0,
viewportWidth = 1200,
+ __experimentalAsButton = true,
__experimentalLive = false,
__experimentalOnClick,
} ) {
@@ -42,8 +42,8 @@ export function BlockPreview( {
{ __experimentalLive ? (
) : (
+
+
+ );
+
+ return __experimentalAsButton ? (
-
-
-
+ { blockList }
+ ) : (
+ <>{ blockList }>
);
}
diff --git a/packages/block-editor/src/components/block-preview/style.scss b/packages/block-editor/src/components/block-preview/style.scss
index 71ca31e9bc221b..6f6465dd1f387e 100644
--- a/packages/block-editor/src/components/block-preview/style.scss
+++ b/packages/block-editor/src/components/block-preview/style.scss
@@ -36,3 +36,22 @@
}
}
}
+
+.block-editor-block-preview__live-content {
+ // Hide the block appender, as the block is not editable in this context.
+ .block-list-appender {
+ display: none;
+ }
+
+ // Revert button disable styles to ensure that button styles render as they will on the
+ // front end of the site. For example, this ensures that Social Links icons display correctly.
+ .components-button:disabled {
+ opacity: initial;
+ }
+
+ // Hide placeholders.
+ .components-placeholder,
+ .block-editor-block-list__block[data-empty="true"] {
+ display: none;
+ }
+}
diff --git a/packages/block-library/src/editor.scss b/packages/block-library/src/editor.scss
index 7e01efe66a33fa..7aebaf17a09cb1 100644
--- a/packages/block-library/src/editor.scss
+++ b/packages/block-library/src/editor.scss
@@ -22,7 +22,6 @@
@import "./nextpage/editor.scss";
@import "./page-list/editor.scss";
@import "./paragraph/editor.scss";
-@import "./post-content/editor.scss";
@import "./post-excerpt/editor.scss";
@import "./pullquote/editor.scss";
@import "./rss/editor.scss";
diff --git a/packages/block-library/src/post-content/edit.js b/packages/block-library/src/post-content/edit.js
index bf7097a2f3d122..2c9212e8684073 100644
--- a/packages/block-library/src/post-content/edit.js
+++ b/packages/block-library/src/post-content/edit.js
@@ -44,6 +44,7 @@ function ReadOnlyContent( { userCanEdit, postType, postId } ) {
diff --git a/packages/block-library/src/post-content/editor.scss b/packages/block-library/src/post-content/editor.scss
deleted file mode 100644
index 1b8570f28a1a24..00000000000000
--- a/packages/block-library/src/post-content/editor.scss
+++ /dev/null
@@ -1,20 +0,0 @@
-.wp-block-post-content {
- &.is-readonly {
- // Hide the block appender within the block, as the block is not editable in this context.
- .block-list-appender {
- display: none;
- }
-
- // Revert button disable styles to ensure that button styles render as they will on the
- // front end of the site. For example, this ensures that Social Links icons display correctly.
- .components-button:disabled {
- opacity: initial;
- }
-
- // Hide placeholders.
- .components-placeholder,
- .block-editor-block-list__block[data-empty="true"] {
- display: none;
- }
- }
-}
From 6c039894886744c28149a8d2e0ed1ca24646bf33 Mon Sep 17 00:00:00 2001
From: Andrew Serong <14988353+andrewserong@users.noreply.github.com>
Date: Wed, 27 Oct 2021 14:11:05 +1100
Subject: [PATCH 4/9] Remove tabIndex prop from post-content edit
---
packages/block-library/src/post-content/edit.js | 1 -
1 file changed, 1 deletion(-)
diff --git a/packages/block-library/src/post-content/edit.js b/packages/block-library/src/post-content/edit.js
index 2c9212e8684073..d6cd4f42788217 100644
--- a/packages/block-library/src/post-content/edit.js
+++ b/packages/block-library/src/post-content/edit.js
@@ -43,7 +43,6 @@ function ReadOnlyContent( { userCanEdit, postType, postId } ) {
Date: Fri, 29 Oct 2021 17:35:13 +1100
Subject: [PATCH 5/9] Add useDisabled hook, pass layout with alignments, use
BlockListItems
---
.../src/components/block-preview/index.js | 1 +
.../src/components/block-preview/live.js | 31 +++++--
.../src/components/block-preview/style.scss | 4 +
.../block-library/src/post-content/edit.js | 20 +++-
.../src/post-content/use-disabled.js | 92 +++++++++++++++++++
5 files changed, 139 insertions(+), 9 deletions(-)
create mode 100644 packages/block-library/src/post-content/use-disabled.js
diff --git a/packages/block-editor/src/components/block-preview/index.js b/packages/block-editor/src/components/block-preview/index.js
index ad1843da4cece2..8fff2adfa1a83e 100644
--- a/packages/block-editor/src/components/block-preview/index.js
+++ b/packages/block-editor/src/components/block-preview/index.js
@@ -44,6 +44,7 @@ export function BlockPreview( {
) : (
-
-
- );
+ let blockList;
+
+ if ( __experimentalAsButton ) {
+ blockList = (
+
+
+
+ );
+ } else {
+ const props = {};
+ if ( themeSupportsLayout ) {
+ props.__experimentalLayout = layout;
+ }
+ blockList = ;
+ }
return __experimentalAsButton ? (
{
@@ -40,12 +55,11 @@ function ReadOnlyContent( { userCanEdit, postType, postId } ) {
{ __( 'This content is password protected.' ) }
) : (
-
+
);
diff --git a/packages/block-library/src/post-content/use-disabled.js b/packages/block-library/src/post-content/use-disabled.js
new file mode 100644
index 00000000000000..9a017bd797085e
--- /dev/null
+++ b/packages/block-library/src/post-content/use-disabled.js
@@ -0,0 +1,92 @@
+/**
+ * External dependencies
+ */
+import { includes, debounce } from 'lodash';
+
+/**
+ * WordPress dependencies
+ */
+import { useCallback, useLayoutEffect, useRef } from '@wordpress/element';
+import { focus } from '@wordpress/dom';
+
+/**
+ * Names of control nodes which qualify for disabled behavior.
+ *
+ * See WHATWG HTML Standard: 4.10.18.5: "Enabling and disabling form controls: the disabled attribute".
+ *
+ * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#enabling-and-disabling-form-controls:-the-disabled-attribute
+ *
+ * @type {string[]}
+ */
+const DISABLED_ELIGIBLE_NODE_NAMES = [
+ 'BUTTON',
+ 'FIELDSET',
+ 'INPUT',
+ 'OPTGROUP',
+ 'OPTION',
+ 'SELECT',
+ 'TEXTAREA',
+];
+
+export function useDisabled() {
+ /** @type {import('react').RefObject
} */
+ const node = useRef( null );
+
+ const disable = () => {
+ if ( ! node.current ) {
+ return;
+ }
+
+ focus.focusable.find( node.current ).forEach( ( focusable ) => {
+ if (
+ includes( DISABLED_ELIGIBLE_NODE_NAMES, focusable.nodeName )
+ ) {
+ focusable.setAttribute( 'disabled', '' );
+ }
+
+ if ( focusable.nodeName === 'A' ) {
+ focusable.setAttribute( 'tabindex', '-1' );
+ }
+
+ const tabIndex = focusable.getAttribute( 'tabindex' );
+ if ( tabIndex !== null && tabIndex !== '-1' ) {
+ focusable.removeAttribute( 'tabindex' );
+ }
+
+ if ( focusable.hasAttribute( 'contenteditable' ) ) {
+ focusable.setAttribute( 'contenteditable', 'false' );
+ }
+ } );
+ };
+
+ // Debounce re-disable since disabling process itself will incur
+ // additional mutations which should be ignored.
+ const debouncedDisable = useCallback(
+ debounce( disable, undefined, { leading: true } ),
+ []
+ );
+
+ useLayoutEffect( () => {
+ disable();
+
+ /** @type {MutationObserver | undefined} */
+ let observer;
+ if ( node.current ) {
+ observer = new window.MutationObserver( debouncedDisable );
+ observer.observe( node.current, {
+ childList: true,
+ attributes: true,
+ subtree: true,
+ } );
+ }
+
+ return () => {
+ if ( observer ) {
+ observer.disconnect();
+ }
+ debouncedDisable.cancel();
+ };
+ }, [] );
+
+ return node;
+}
From b06b3741bf2036bf87fe1903984074a6628a71e4 Mon Sep 17 00:00:00 2001
From: Andrew Serong <14988353+andrewserong@users.noreply.github.com>
Date: Wed, 3 Nov 2021 17:26:44 +1100
Subject: [PATCH 6/9] Refactor block preview behaviour to a useBlockPreview
hook for the post content block
---
packages/block-editor/README.md | 17 ++++
.../src/components/block-preview/index.js | 67 ++++++++++++--
.../src/components/block-preview/live.js | 40 ++------
packages/block-editor/src/components/index.js | 2 +-
.../block-library/src/post-content/edit.js | 42 ++++-----
.../compose/src/hooks/use-disabled/index.js | 92 +++++++++++++++++++
packages/compose/src/index.js | 1 +
7 files changed, 195 insertions(+), 66 deletions(-)
create mode 100644 packages/compose/src/hooks/use-disabled/index.js
diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md
index 5c8f30a5802ce5..63315ada1be699 100644
--- a/packages/block-editor/README.md
+++ b/packages/block-editor/README.md
@@ -660,6 +660,23 @@ _Returns_
Undocumented declaration.
+### useBlockPreview
+
+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
+a block preview wrapper, automatically rendering inner blocks as children. If
+you define a ref for the element, it is important to pass the ref to this
+hook, which the hook in turn will pass to the component through the props it
+returns. Optionally, you can also pass any other props through this hook, and
+they will be merged and returned.
+
+_Parameters_
+
+- _props_ `Object`: Optional. Props to pass to the element. Must contain the ref if one is defined.
+- _options_ `Object`: Preview options.
+- _options.blocks_ `WPBlock[]`: Block objects.
+- _options.\_\_experimentalLayout_ `Object`: Layout settings to be used in the preview.
+
### useBlockProps
This hook is used to lightly mark an element as a block element. The element
diff --git a/packages/block-editor/src/components/block-preview/index.js b/packages/block-editor/src/components/block-preview/index.js
index 8fff2adfa1a83e..c3002e9045be03 100644
--- a/packages/block-editor/src/components/block-preview/index.js
+++ b/packages/block-editor/src/components/block-preview/index.js
@@ -2,10 +2,15 @@
* External dependencies
*/
import { castArray } from 'lodash';
+import classnames from 'classnames';
/**
* WordPress dependencies
*/
+import {
+ __experimentalUseDisabled as useDisabled,
+ useMergeRefs,
+} from '@wordpress/compose';
import { useSelect } from '@wordpress/data';
import { memo, useMemo } from '@wordpress/element';
@@ -16,12 +21,12 @@ import BlockEditorProvider from '../provider';
import LiveBlockPreview from './live';
import AutoHeightBlockPreview from './auto';
import { store as blockEditorStore } from '../../store';
+import { BlockListItems } from '../block-list';
export function BlockPreview( {
blocks,
__experimentalPadding = 0,
viewportWidth = 1200,
- __experimentalAsButton = true,
__experimentalLive = false,
__experimentalOnClick,
} ) {
@@ -41,11 +46,7 @@ export function BlockPreview( {
return (
{ __experimentalLive ? (
-
+
) : (
select( blockEditorStore ).getSettings(),
+ []
+ );
+ const disabledRef = useDisabled();
+ const ref = useMergeRefs( [ props.ref, disabledRef ] );
+ const settings = useMemo( () => {
+ const _settings = { ...originalSettings };
+ _settings.__experimentalBlockPatterns = [];
+ return _settings;
+ }, [ originalSettings ] );
+ const renderedBlocks = useMemo( () => castArray( blocks ), [ blocks ] );
+
+ const children = (
+
+
+
+ );
+
+ return {
+ ...props,
+ ref,
+ className: classnames(
+ props.className,
+ 'block-editor-block-preview__live-content',
+ 'components-disabled'
+ ),
+ children: blocks?.length ? children : null,
+ };
+}
diff --git a/packages/block-editor/src/components/block-preview/live.js b/packages/block-editor/src/components/block-preview/live.js
index 8b946c00b56292..792740bb2c02b6 100644
--- a/packages/block-editor/src/components/block-preview/live.js
+++ b/packages/block-editor/src/components/block-preview/live.js
@@ -6,47 +6,19 @@ import { Disabled } from '@wordpress/components';
/**
* Internal dependencies
*/
-import { BlockListItems } from '../block-list';
+import BlockList from '../block-list';
-const DEFAULT_CONTROLS = [ 'none', 'left', 'center', 'right', 'wide', 'full' ];
-const WIDE_CONTROLS = [ 'wide', 'full' ];
-
-const layout = {
- type: 'default',
- alignments: [ ...DEFAULT_CONTROLS, ...WIDE_CONTROLS ],
-};
-
-export default function LiveBlockPreview( {
- onClick,
- __experimentalAsButton = true,
- themeSupportsLayout = false,
-} ) {
- let blockList;
-
- if ( __experimentalAsButton ) {
- blockList = (
-
-
-
- );
- } else {
- const props = {};
- if ( themeSupportsLayout ) {
- props.__experimentalLayout = layout;
- }
- blockList = ;
- }
-
- return __experimentalAsButton ? (
+export default function LiveBlockPreview( { onClick } ) {
+ return (
- { blockList }
+
+
+
- ) : (
- <>{ blockList }>
);
}
diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js
index dcccb216217e30..a2e4b5c3a02db8 100644
--- a/packages/block-editor/src/components/index.js
+++ b/packages/block-editor/src/components/index.js
@@ -103,7 +103,7 @@ export { default as BlockList } from './block-list';
export { useBlockProps } from './block-list/use-block-props';
export { LayoutStyle as __experimentalLayoutStyle } from './block-list/layout';
export { default as BlockMover } from './block-mover';
-export { default as BlockPreview } from './block-preview';
+export { default as BlockPreview, useBlockPreview } from './block-preview';
export {
default as BlockSelectionClearer,
useBlockSelectionClearer as __unstableUseBlockSelectionClearer,
diff --git a/packages/block-library/src/post-content/edit.js b/packages/block-library/src/post-content/edit.js
index 625d704462bf35..da5ce6f4175d57 100644
--- a/packages/block-library/src/post-content/edit.js
+++ b/packages/block-library/src/post-content/edit.js
@@ -1,8 +1,3 @@
-/**
- * External dependencies
- */
-import classnames from 'classnames';
-
/**
* WordPress dependencies
*/
@@ -10,7 +5,7 @@ import { __ } from '@wordpress/i18n';
import { parse } from '@wordpress/blocks';
import { useSelect } from '@wordpress/data';
import {
- BlockPreview,
+ useBlockPreview,
useBlockProps,
useInnerBlocksProps,
useSetting,
@@ -19,49 +14,45 @@ import {
Warning,
} from '@wordpress/block-editor';
import { useEntityProp, useEntityBlockEditor } from '@wordpress/core-data';
-import { useMergeRefs } from '@wordpress/compose';
import { useMemo } from '@wordpress/element';
/**
* Internal dependencies
*/
import { useCanEditEntity } from '../utils/hooks';
-import { useDisabled } from './use-disabled';
-function ReadOnlyContent( { userCanEdit, postType, postId } ) {
+function ReadOnlyContent( { layout, userCanEdit, postType, postId } ) {
const [ , , content ] = useEntityProp(
'postType',
postType,
'content',
postId
);
- const { ref, ...blockProps } = useBlockProps( {
- className: classnames(
- 'components-disabled',
- 'block-editor-block-preview__live-content'
- ),
- } );
- const node = useDisabled();
+ const blockProps = useBlockProps();
- const mergedRefs = useMergeRefs( [ ref, node ] );
+ const themeSupportsLayout = useSelect( ( select ) => {
+ const { getSettings } = select( blockEditorStore );
+ return getSettings()?.supportsLayout;
+ }, [] );
+ const defaultLayout = useSetting( 'layout' ) || {};
+ const usedLayout = !! layout && layout.inherit ? defaultLayout : layout;
const rawContent = content?.raw;
const blocks = useMemo( () => {
return rawContent ? parse( rawContent ) : [];
}, [ rawContent ] );
+ const blockPreviewProps = useBlockPreview( blockProps, {
+ blocks,
+ __experimentalLayout: themeSupportsLayout ? usedLayout : undefined,
+ } );
+
return content?.protected && ! userCanEdit ? (
{ __( 'This content is password protected.' ) }
) : (
-
-
-
+
);
}
@@ -92,7 +83,7 @@ function EditableContent( { layout, context = {} } ) {
}
function Content( props ) {
- const { context: { queryId, postType, postId } = {} } = props;
+ const { context: { queryId, postType, postId } = {}, layout } = props;
const isDescendentOfQueryLoop = !! queryId;
const userCanEdit = useCanEditEntity( 'postType', postType, postId );
const isEditable = userCanEdit && ! isDescendentOfQueryLoop;
@@ -101,6 +92,7 @@ function Content( props ) {
) : (
} */
+ const node = useRef( null );
+
+ const disable = () => {
+ if ( ! node.current ) {
+ return;
+ }
+
+ focus.focusable.find( node.current ).forEach( ( focusable ) => {
+ if (
+ includes( DISABLED_ELIGIBLE_NODE_NAMES, focusable.nodeName )
+ ) {
+ focusable.setAttribute( 'disabled', '' );
+ }
+
+ if ( focusable.nodeName === 'A' ) {
+ focusable.setAttribute( 'tabindex', '-1' );
+ }
+
+ const tabIndex = focusable.getAttribute( 'tabindex' );
+ if ( tabIndex !== null && tabIndex !== '-1' ) {
+ focusable.removeAttribute( 'tabindex' );
+ }
+
+ if ( focusable.hasAttribute( 'contenteditable' ) ) {
+ focusable.setAttribute( 'contenteditable', 'false' );
+ }
+ } );
+ };
+
+ // Debounce re-disable since disabling process itself will incur
+ // additional mutations which should be ignored.
+ const debouncedDisable = useCallback(
+ debounce( disable, undefined, { leading: true } ),
+ []
+ );
+
+ useLayoutEffect( () => {
+ disable();
+
+ /** @type {MutationObserver | undefined} */
+ let observer;
+ if ( node.current ) {
+ observer = new window.MutationObserver( debouncedDisable );
+ observer.observe( node.current, {
+ childList: true,
+ attributes: true,
+ subtree: true,
+ } );
+ }
+
+ return () => {
+ if ( observer ) {
+ observer.disconnect();
+ }
+ debouncedDisable.cancel();
+ };
+ }, [] );
+
+ return node;
+}
diff --git a/packages/compose/src/index.js b/packages/compose/src/index.js
index 2ce3a2ab33f6fb..2bfc7c7f5f8488 100644
--- a/packages/compose/src/index.js
+++ b/packages/compose/src/index.js
@@ -17,6 +17,7 @@ export { default as useConstrainedTabbing } from './hooks/use-constrained-tabbin
export { default as useCopyOnClick } from './hooks/use-copy-on-click';
export { default as useCopyToClipboard } from './hooks/use-copy-to-clipboard';
export { default as __experimentalUseDialog } from './hooks/use-dialog';
+export { default as __experimentalUseDisabled } from './hooks/use-disabled';
export { default as __experimentalUseDragging } from './hooks/use-dragging';
export { default as useFocusOnMount } from './hooks/use-focus-on-mount';
export { default as __experimentalUseFocusOutside } from './hooks/use-focus-outside';
From 2a5a2462eca58fb15e4eeb7049327425c418da09 Mon Sep 17 00:00:00 2001
From: Andrew Serong <14988353+andrewserong@users.noreply.github.com>
Date: Wed, 3 Nov 2021 17:29:03 +1100
Subject: [PATCH 7/9] Remove useDisabled hook from post content now that it has
been moved to the compose package
---
.../src/post-content/use-disabled.js | 92 -------------------
1 file changed, 92 deletions(-)
delete mode 100644 packages/block-library/src/post-content/use-disabled.js
diff --git a/packages/block-library/src/post-content/use-disabled.js b/packages/block-library/src/post-content/use-disabled.js
deleted file mode 100644
index 9a017bd797085e..00000000000000
--- a/packages/block-library/src/post-content/use-disabled.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * External dependencies
- */
-import { includes, debounce } from 'lodash';
-
-/**
- * WordPress dependencies
- */
-import { useCallback, useLayoutEffect, useRef } from '@wordpress/element';
-import { focus } from '@wordpress/dom';
-
-/**
- * Names of control nodes which qualify for disabled behavior.
- *
- * See WHATWG HTML Standard: 4.10.18.5: "Enabling and disabling form controls: the disabled attribute".
- *
- * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#enabling-and-disabling-form-controls:-the-disabled-attribute
- *
- * @type {string[]}
- */
-const DISABLED_ELIGIBLE_NODE_NAMES = [
- 'BUTTON',
- 'FIELDSET',
- 'INPUT',
- 'OPTGROUP',
- 'OPTION',
- 'SELECT',
- 'TEXTAREA',
-];
-
-export function useDisabled() {
- /** @type {import('react').RefObject} */
- const node = useRef( null );
-
- const disable = () => {
- if ( ! node.current ) {
- return;
- }
-
- focus.focusable.find( node.current ).forEach( ( focusable ) => {
- if (
- includes( DISABLED_ELIGIBLE_NODE_NAMES, focusable.nodeName )
- ) {
- focusable.setAttribute( 'disabled', '' );
- }
-
- if ( focusable.nodeName === 'A' ) {
- focusable.setAttribute( 'tabindex', '-1' );
- }
-
- const tabIndex = focusable.getAttribute( 'tabindex' );
- if ( tabIndex !== null && tabIndex !== '-1' ) {
- focusable.removeAttribute( 'tabindex' );
- }
-
- if ( focusable.hasAttribute( 'contenteditable' ) ) {
- focusable.setAttribute( 'contenteditable', 'false' );
- }
- } );
- };
-
- // Debounce re-disable since disabling process itself will incur
- // additional mutations which should be ignored.
- const debouncedDisable = useCallback(
- debounce( disable, undefined, { leading: true } ),
- []
- );
-
- useLayoutEffect( () => {
- disable();
-
- /** @type {MutationObserver | undefined} */
- let observer;
- if ( node.current ) {
- observer = new window.MutationObserver( debouncedDisable );
- observer.observe( node.current, {
- childList: true,
- attributes: true,
- subtree: true,
- } );
- }
-
- return () => {
- if ( observer ) {
- observer.disconnect();
- }
- debouncedDisable.cancel();
- };
- }, [] );
-
- return node;
-}
From 284ded1f7e22da7a970332e51ad04601719571d5 Mon Sep 17 00:00:00 2001
From: Andrew Serong <14988353+andrewserong@users.noreply.github.com>
Date: Thu, 4 Nov 2021 17:18:12 +1100
Subject: [PATCH 8/9] Combine props into options param of useBlockPreview
---
packages/block-editor/README.md | 2 +-
.../src/components/block-preview/index.js | 11 ++++++-----
packages/block-library/src/post-content/edit.js | 3 ++-
3 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md
index 63315ada1be699..1736d857763dfe 100644
--- a/packages/block-editor/README.md
+++ b/packages/block-editor/README.md
@@ -672,9 +672,9 @@ they will be merged and returned.
_Parameters_
-- _props_ `Object`: Optional. Props to pass to the element. Must contain the ref if one is defined.
- _options_ `Object`: Preview options.
- _options.blocks_ `WPBlock[]`: Block objects.
+- _options.props_ `Object`: Optional. Props to pass to the element. Must contain the ref if one is defined.
- _options.\_\_experimentalLayout_ `Object`: Layout settings to be used in the preview.
### useBlockProps
diff --git a/packages/block-editor/src/components/block-preview/index.js b/packages/block-editor/src/components/block-preview/index.js
index c3002e9045be03..e8ea15edf9271e 100644
--- a/packages/block-editor/src/components/block-preview/index.js
+++ b/packages/block-editor/src/components/block-preview/index.js
@@ -79,17 +79,18 @@ export default memo( BlockPreview );
* returns. Optionally, you can also pass any other props through this hook, and
* they will be merged and returned.
*
- * @param {Object} props Optional. Props to pass to the element. Must contain
- * the ref if one is defined.
* @param {Object} options Preview options.
* @param {WPBlock[]} options.blocks Block objects.
+ * @param {Object} options.props Optional. Props to pass to the element. Must contain
+ * the ref if one is defined.
* @param {Object} options.__experimentalLayout Layout settings to be used in the preview.
*
*/
-export function useBlockPreview(
+export function useBlockPreview( {
+ blocks,
props = {},
- { blocks, __experimentalLayout }
-) {
+ __experimentalLayout,
+} ) {
const originalSettings = useSelect(
( select ) => select( blockEditorStore ).getSettings(),
[]
diff --git a/packages/block-library/src/post-content/edit.js b/packages/block-library/src/post-content/edit.js
index da5ce6f4175d57..573fc17dec5bfa 100644
--- a/packages/block-library/src/post-content/edit.js
+++ b/packages/block-library/src/post-content/edit.js
@@ -42,8 +42,9 @@ function ReadOnlyContent( { layout, userCanEdit, postType, postId } ) {
return rawContent ? parse( rawContent ) : [];
}, [ rawContent ] );
- const blockPreviewProps = useBlockPreview( blockProps, {
+ const blockPreviewProps = useBlockPreview( {
blocks,
+ props: blockProps,
__experimentalLayout: themeSupportsLayout ? usedLayout : undefined,
} );
From 89fba21c75b1337de9aaf2d84bdc6c75a6dbae03 Mon Sep 17 00:00:00 2001
From: Andrew Serong <14988353+andrewserong@users.noreply.github.com>
Date: Thu, 4 Nov 2021 17:35:34 +1100
Subject: [PATCH 9/9] Combine layout logic
---
.../block-library/src/post-content/edit.js | 41 ++++++++++---------
1 file changed, 22 insertions(+), 19 deletions(-)
diff --git a/packages/block-library/src/post-content/edit.js b/packages/block-library/src/post-content/edit.js
index 573fc17dec5bfa..fa4eb899739798 100644
--- a/packages/block-library/src/post-content/edit.js
+++ b/packages/block-library/src/post-content/edit.js
@@ -21,7 +21,12 @@ import { useMemo } from '@wordpress/element';
*/
import { useCanEditEntity } from '../utils/hooks';
-function ReadOnlyContent( { layout, userCanEdit, postType, postId } ) {
+function ReadOnlyContent( {
+ __experimentalLayout,
+ postId,
+ postType,
+ userCanEdit,
+} ) {
const [ , , content ] = useEntityProp(
'postType',
postType,
@@ -30,13 +35,6 @@ function ReadOnlyContent( { layout, userCanEdit, postType, postId } ) {
);
const blockProps = useBlockProps();
- const themeSupportsLayout = useSelect( ( select ) => {
- const { getSettings } = select( blockEditorStore );
- return getSettings()?.supportsLayout;
- }, [] );
- const defaultLayout = useSetting( 'layout' ) || {};
- const usedLayout = !! layout && layout.inherit ? defaultLayout : layout;
-
const rawContent = content?.raw;
const blocks = useMemo( () => {
return rawContent ? parse( rawContent ) : [];
@@ -45,7 +43,7 @@ function ReadOnlyContent( { layout, userCanEdit, postType, postId } ) {
const blockPreviewProps = useBlockPreview( {
blocks,
props: blockProps,
- __experimentalLayout: themeSupportsLayout ? usedLayout : undefined,
+ __experimentalLayout,
} );
return content?.protected && ! userCanEdit ? (
@@ -57,14 +55,8 @@ function ReadOnlyContent( { layout, userCanEdit, postType, postId } ) {
);
}
-function EditableContent( { layout, context = {} } ) {
+function EditableContent( { __experimentalLayout, context = {} } ) {
const { postType, postId } = context;
- const themeSupportsLayout = useSelect( ( select ) => {
- const { getSettings } = select( blockEditorStore );
- return getSettings()?.supportsLayout;
- }, [] );
- const defaultLayout = useSetting( 'layout' ) || {};
- const usedLayout = !! layout && layout.inherit ? defaultLayout : layout;
const [ blocks, onInput, onChange ] = useEntityBlockEditor(
'postType',
postType,
@@ -77,7 +69,7 @@ function EditableContent( { layout, context = {} } ) {
value: blocks,
onInput,
onChange,
- __experimentalLayout: themeSupportsLayout ? usedLayout : undefined,
+ __experimentalLayout,
}
);
return ;
@@ -89,11 +81,22 @@ function Content( props ) {
const userCanEdit = useCanEditEntity( 'postType', postType, postId );
const isEditable = userCanEdit && ! isDescendentOfQueryLoop;
+ const themeSupportsLayout = useSelect( ( select ) => {
+ const { getSettings } = select( blockEditorStore );
+ return getSettings()?.supportsLayout;
+ }, [] );
+ const defaultLayout = useSetting( 'layout' ) || {};
+ const usedLayout = !! layout && layout.inherit ? defaultLayout : layout;
+ const __experimentalLayout = themeSupportsLayout ? usedLayout : undefined;
+
return isEditable ? (
-
+
) : (