Skip to content

Commit

Permalink
Block toolbar: account for scrollable blocks that affect the position…
Browse files Browse the repository at this point in the history
… of the block toolbar (#66188)

The rect bounds of blocvk child elements, specifically the x and y values, change when the element is scrolled. This change attempts to correct the overflow so the scrollable children do not influence the x,y values of the block toolbar popover.

Co-authored-by: ramonjd <ramonopoly@git.wordpress.org>
Co-authored-by: aaronrobertshaw <aaronrobertshaw@git.wordpress.org>
Co-authored-by: andrewserong <andrewserong@git.wordpress.org>
Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: kevin940726 <kevin940726@git.wordpress.org>
  • Loading branch information
6 people authored and gutenbergplugin committed Oct 21, 2024
1 parent b1ace05 commit a3c0d3c
Showing 1 changed file with 22 additions and 2 deletions.
24 changes: 22 additions & 2 deletions packages/block-editor/src/utils/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,22 @@ function isElementVisible( element ) {
return true;
}

/**
* Checks if the element is scrollable.
*
* @param {Element} element Element.
* @return {boolean} True if the element is scrollable.
*/
function isScrollable( element ) {
const style = window.getComputedStyle( element );
return (
style.overflowX === 'auto' ||
style.overflowX === 'scroll' ||
style.overflowY === 'auto' ||
style.overflowY === 'scroll'
);
}

/**
* Returns the rect of the element including all visible nested elements.
*
Expand All @@ -136,19 +152,23 @@ function isElementVisible( element ) {
*/
export function getVisibleElementBounds( element ) {
const viewport = element.ownerDocument.defaultView;

if ( ! viewport ) {
return new window.DOMRectReadOnly();
}

let bounds = element.getBoundingClientRect();

const stack = [ element ];
let currentElement;

while ( ( currentElement = stack.pop() ) ) {
for ( const child of currentElement.children ) {
if ( isElementVisible( child ) ) {
const childBounds = child.getBoundingClientRect();
let childBounds = child.getBoundingClientRect();
// If the parent is scrollable, use parent's scrollable bounds.
if ( isScrollable( currentElement ) ) {
childBounds = currentElement.getBoundingClientRect();
}
bounds = rectUnion( bounds, childBounds );
stack.push( child );
}
Expand Down

1 comment on commit a3c0d3c

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flaky tests detected in a3c0d3c.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/11449638120
📝 Reported issues:

Please sign in to comment.