Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Omit edit-only behaviors from Iframe in previews #69132

Draft
wants to merge 5 commits into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions packages/block-editor/src/components/block-canvas/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,16 @@ export function ExperimentalBlockCanvas( {
children = <BlockList />,
styles,
contentRef: contentRefProp,
iframeProps,
iframeProps = {},
} ) {
useBlockCommands();
const isTabletViewport = useViewportMatch( 'medium', '<' );
const resetTypingRef = useMouseMoveTypingReset();
const clearerRef = useBlockSelectionClearer();
const localRef = useRef();
const contentRef = useMergeRefs( [ contentRefProp, clearerRef, localRef ] );
const { ref: iframeRefProp, ...restIframeProps } = iframeProps;
const iframeRef = useMergeRefs( [ iframeRefProp, resetTypingRef ] );
const zoomLevel = useSelect(
( select ) => unlock( select( blockEditorStore ) ).getZoomLevel(),
[]
Expand Down Expand Up @@ -82,9 +84,9 @@ export function ExperimentalBlockCanvas( {
style={ { height, display: 'flex' } }
>
<Iframe
{ ...iframeProps }
{ ...restIframeProps }
{ ...zoomOutIframeProps }
ref={ resetTypingRef }
ref={ iframeRef }
contentRef={ contentRef }
style={ {
...iframeProps?.style,
Expand Down
46 changes: 22 additions & 24 deletions packages/block-editor/src/components/iframe/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ function useBubbleEvents( iframeDocument ) {
function Iframe( {
contentRef,
children,
tabIndex = 0,
tabIndex,
scale = 1,
frameSize = 0,
readonly,
Expand All @@ -119,8 +119,6 @@ function Iframe( {
/** @type {[Document, import('react').Dispatch<Document>]} */
const [ iframeDocument, setIframeDocument ] = useState();
const [ bodyClasses, setBodyClasses ] = useState( [] );
const clearerRef = useBlockSelectionClearer();
const [ before, writingFlowRef, after ] = useWritingFlow();

const setRef = useRefEffect( ( node ) => {
node._load = () => {
Expand Down Expand Up @@ -163,13 +161,11 @@ function Iframe( {
compatStyle.cloneNode( true )
);

if ( ! isPreviewMode ) {
// eslint-disable-next-line no-console
console.warn(
`${ compatStyle.id } was added to the iframe incorrectly. Please use block.json or enqueue_block_assets to add styles to the iframe.`,
compatStyle
);
}
// eslint-disable-next-line no-console
console.warn(
`${ compatStyle.id } was added to the iframe incorrectly. Please use block.json or enqueue_block_assets to add styles to the iframe.`,
compatStyle
);
}

iFrameDocument.addEventListener(
Expand Down Expand Up @@ -227,15 +223,6 @@ function Iframe( {
iframeDocument,
} );

const disabledRef = useDisabled( { isDisabled: ! readonly } );
const bodyRef = useMergeRefs( [
useBubbleEvents( iframeDocument ),
contentRef,
clearerRef,
writingFlowRef,
disabledRef,
] );

// Correct doctype is required to enable rendering in standards
// mode. Also preload the styles to avoid a flash of unstyled
// content.
Expand Down Expand Up @@ -275,13 +262,24 @@ function Iframe( {

useEffect( () => cleanup, [ cleanup ] );

// Make sure to not render the before and after focusable div elements in view
// mode. They're only needed to capture focus in edit mode.
const shouldRenderFocusCaptureElements = tabIndex >= 0 && ! isPreviewMode;
const clearerRef = useBlockSelectionClearer();
const [ before, writingFlowRef, after ] = useWritingFlow();
const bubbleEventsRef = useBubbleEvents( iframeDocument );
// Some refs are only needed if editing is enabled.
const isEditable = ! ( isPreviewMode || readonly );
const bodyRef = useMergeRefs( [
contentRef,
useDisabled( { isDisabled: ! readonly } ),
isEditable ? bubbleEventsRef : null,
isEditable ? clearerRef : null,
isEditable ? writingFlowRef : null,
] );
// The before and after elements are only needed if editable.
const [ usedBefore, usedAfter ] = isEditable ? [ before, after ] : [];

const iframe = (
<>
{ shouldRenderFocusCaptureElements && before }
{ usedBefore }
{ /* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */ }
<iframe
{ ...props }
Expand Down Expand Up @@ -349,7 +347,7 @@ function Iframe( {
iframeDocument.documentElement
) }
</iframe>
{ shouldRenderFocusCaptureElements && after }
{ usedAfter }
</>
);

Expand Down
7 changes: 7 additions & 0 deletions packages/block-editor/src/components/writing-flow/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ export function useWritingFlow() {
},
[ hasMultiSelection ]
),
useRefEffect(
( node ) => () => {
node.removeAttribute( 'tabindex' );
node.removeAttribute( 'contenteditable' );
},
[]
),
] ),
after,
];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
/**
* External dependencies
*/
import clsx from 'clsx';

/**
* WordPress dependencies
*/
import { useRefEffect } from '@wordpress/compose';
import { useSelect } from '@wordpress/data';
import { ENTER, SPACE } from '@wordpress/keycodes';
import { useState, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { store as editorStore } from '@wordpress/editor';
import { privateApis as routerPrivateApis } from '@wordpress/router';
Expand All @@ -31,13 +26,25 @@ export default function useEditorIframeProps() {
'trash'
);
}, [] );
const [ isFocused, setIsFocused ] = useState( false );

useEffect( () => {
if ( canvas === 'edit' ) {
setIsFocused( false );
}
}, [ canvas ] );
const isEdit = canvas === 'edit';

const effectFocus = useRefEffect(
( node ) => {
const toggleClass = ( { type } ) =>
node.classList.toggle( 'is-focused', type === 'focus' );
node.contentWindow.addEventListener( 'focus', toggleClass );
node.contentWindow.addEventListener( 'blur', toggleClass );
return () => {
node.contentWindow.removeEventListener( 'focus', toggleClass );
node.contentWindow.removeEventListener( 'blur', toggleClass );
if ( ! isEdit ) {
node.classList.remove( 'is-focused' );
}
};
},
[ isEdit ]
);

// In view mode, make the canvas iframe be perceived and behave as a button
// to switch to edit mode, with a meaningful label and no title attribute.
Expand All @@ -46,9 +53,6 @@ export default function useEditorIframeProps() {
'aria-disabled': currentPostIsTrashed,
title: null,
role: 'button',
tabIndex: 0,
onFocus: () => setIsFocused( true ),
onBlur: () => setIsFocused( false ),
onKeyDown: ( event ) => {
const { keyCode } = event;
if (
Expand All @@ -71,13 +75,12 @@ export default function useEditorIframeProps() {
event.stopPropagation();
}
},
ref: effectFocus,
readonly: true,
};

return {
className: clsx( 'edit-site-visual-editor__editor-canvas', {
'is-focused': isFocused && canvas === 'view',
} ),
className: 'edit-site-visual-editor__editor-canvas',
...( canvas === 'view' ? viewModeIframeProps : {} ),
};
}
Loading