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 (WordPress#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 <[email protected]>
Co-authored-by: aaronrobertshaw <[email protected]>
Co-authored-by: andrewserong <[email protected]>
Co-authored-by: t-hamano <[email protected]>
Co-authored-by: kevin940726 <[email protected]>
  • Loading branch information
6 people authored and karthick-murugan committed Nov 13, 2024
1 parent 4a18c69 commit 8028ca0
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

0 comments on commit 8028ca0

Please sign in to comment.