Skip to content

Commit

Permalink
Fix legacy widget height overflow (#33191)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin940726 authored Jul 5, 2021
1 parent bded4ae commit fea614a
Showing 1 changed file with 55 additions and 27 deletions.
82 changes: 55 additions & 27 deletions packages/widgets/src/blocks/legacy-widget/edit/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,36 +13,54 @@ import { Placeholder, Spinner, Disabled } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

export default function Preview( { idBase, instance, isVisible } ) {
const [ iframeHeight, setIframeHeight ] = useState();
const [ isLoaded, setIsLoaded ] = useState( false );

// Resize the iframe on either the load event, or when the iframe becomes visible.
const ref = useRefEffect( ( iframe ) => {
function onChange() {
const boundingRect = iframe?.contentDocument?.body?.getBoundingClientRect();
if ( boundingRect ) {
// Include `top` in the height calculation to avoid the bottom
// of widget previews being cut-off. Most widgets have a
// heading at the top that has top margin, and the `height`
// alone doesn't take that margin into account.
setIframeHeight( boundingRect.top + boundingRect.height );
}
}
const ref = useRefEffect(
( iframe ) => {
// Only set height if the iframe is loaded,
// or it will grow to an unexpected large height in Safari if it's hidden initially.
if ( isLoaded ) {
// If the preview frame has another origin then this won't work.
// One possible solution is to add custom script to call `postMessage` in the preview frame.
// Or, better yet, we migrate away from iframe.
function setHeight() {
// Pick the maximum of these two values to account for margin collapsing.
const height = Math.max(
iframe.contentDocument.documentElement.offsetHeight,
iframe.contentDocument.body.offsetHeight
);
iframe.style.height = `${ height }px`;
}

const { IntersectionObserver } = iframe.ownerDocument.defaultView;
const {
IntersectionObserver,
} = iframe.ownerDocument.defaultView;

// Observe for intersections that might cause a change in the height of
// the iframe, e.g. a Widget Area becoming expanded.
const intersectionObserver = new IntersectionObserver( onChange, {
threshold: 1,
} );
intersectionObserver.observe( iframe );
// Observe for intersections that might cause a change in the height of
// the iframe, e.g. a Widget Area becoming expanded.
const intersectionObserver = new IntersectionObserver(
( [ entry ] ) => {
if ( entry.isIntersecting ) {
setHeight();
}
},
{
threshold: 1,
}
);
intersectionObserver.observe( iframe );

iframe.addEventListener( 'load', onChange );
iframe.addEventListener( 'load', setHeight );

return () => {
iframe.removeEventListener( 'load', onChange );
};
}, [] );
return () => {
intersectionObserver.disconnect();
iframe.removeEventListener( 'load', setHeight );
};
}
},
[ isLoaded ]
);

return (
<>
Expand All @@ -53,7 +71,7 @@ export default function Preview( { idBase, instance, isVisible } ) {
move the iframe off-screen instead of hiding it because web browsers
will not trigger onLoad if the iframe is hidden.
*/ }
{ isVisible && iframeHeight === null && (
{ isVisible && ! isLoaded && (
<Placeholder>
<Spinner />
</Placeholder>
Expand All @@ -62,7 +80,7 @@ export default function Preview( { idBase, instance, isVisible } ) {
className={ classnames(
'wp-block-legacy-widget__edit-preview',
{
'is-offscreen': ! isVisible || iframeHeight === null,
'is-offscreen': ! isVisible || ! isLoaded,
}
) }
>
Expand All @@ -84,7 +102,17 @@ export default function Preview( { idBase, instance, isVisible } ) {
instance,
},
} ) }
height={ iframeHeight || 100 }
onLoad={ ( event ) => {
// To hide the scrollbars of the preview frame for some edge cases,
// such as negative margins in the Gallery Legacy Widget.
// It can't be scrolled anyway.
// TODO: Ideally, this should be fixed in core.
event.target.contentDocument.body.style.overflow =
'hidden';

setIsLoaded( true );
} }
height={ 100 }
/>
</Disabled>
</div>
Expand Down

0 comments on commit fea614a

Please sign in to comment.