Bug 1770729 - Fix IntersectionObserver overflow: clip on zero-sized elements. r=jwatt

I realized my fix in bug 1769512 (using IsEmpty()) wasn't quite correct
in this case, because IntersectionObserver preserves edge-inclusive
intersections.

Differential Revision: https://phabricator.services.mozilla.com/D147078
This commit is contained in:
Emilio Cobos Álvarez 2022-05-23 13:52:48 +00:00
parent 78d2f34bf1
commit fb32f0a2c2
4 changed files with 33 additions and 12 deletions

View File

@ -391,17 +391,18 @@ static Maybe<nsRect> ComputeTheIntersection(
// 3.2 TODO: Apply clip-path.
if (clipAxes != PhysicalAxes::None) {
// 3.1 Map intersectionRect to the coordinate space of container.
nsRect intersectionRectRelativeToContainer =
const nsRect intersectionRectRelativeToContainer =
nsLayoutUtils::TransformFrameRectToAncestor(
target, intersectionRect.value(), containerFrame);
OverflowAreas::ApplyOverflowClippingOnRect(
const nsRect clipRect = OverflowAreas::GetOverflowClipRect(
intersectionRectRelativeToContainer,
containerFrame->GetRectRelativeToSelf(), clipAxes,
containerFrame->OverflowClipMargin(clipAxes));
if (intersectionRectRelativeToContainer.IsEmpty()) {
intersectionRect = EdgeInclusiveIntersection(
intersectionRectRelativeToContainer, clipRect);
if (!intersectionRect) {
return Nothing();
}
intersectionRect = Some(intersectionRectRelativeToContainer);
target = containerFrame;
}
}

View File

@ -12,14 +12,13 @@
namespace mozilla {
/* static */
void OverflowAreas::ApplyOverflowClippingOnRect(nsRect& aOverflowRect,
const nsRect& aBounds,
PhysicalAxes aClipAxes,
const nsSize& aOverflowMargin) {
nsRect OverflowAreas::GetOverflowClipRect(const nsRect& aRectToClip,
const nsRect& aBounds,
PhysicalAxes aClipAxes,
const nsSize& aOverflowMargin) {
auto inflatedBounds = aBounds;
inflatedBounds.Inflate(aOverflowMargin);
auto clip = aOverflowRect;
auto clip = aRectToClip;
if (aClipAxes & PhysicalAxes::Vertical) {
clip.y = inflatedBounds.y;
clip.height = inflatedBounds.height;
@ -28,7 +27,16 @@ void OverflowAreas::ApplyOverflowClippingOnRect(nsRect& aOverflowRect,
clip.x = inflatedBounds.x;
clip.width = inflatedBounds.width;
}
aOverflowRect = aOverflowRect.Intersect(clip);
return clip;
}
/* static */
void OverflowAreas::ApplyOverflowClippingOnRect(nsRect& aOverflowRect,
const nsRect& aBounds,
PhysicalAxes aClipAxes,
const nsSize& aOverflowMargin) {
aOverflowRect = aOverflowRect.Intersect(
GetOverflowClipRect(aOverflowRect, aBounds, aClipAxes, aOverflowMargin));
}
void OverflowAreas::UnionWith(const OverflowAreas& aOther) {

View File

@ -89,6 +89,13 @@ struct OverflowAreas {
aOverflowMargin);
}
// Gets the overflow clipping rect for a given element given a rect to clip,
// the frame bounds, a set of axes, and the overflow margin.
static nsRect GetOverflowClipRect(const nsRect& aRectToClip,
const nsRect& aBounds,
PhysicalAxes aClipAxes,
const nsSize& aOverflowMargin);
// Applies the overflow clipping to a given overflow rect, given the frame
// bounds, and the physical axes on which to apply the overflow clip.
static void ApplyOverflowClippingOnRect(nsRect& aOverflowRect,

View File

@ -14,9 +14,14 @@ pre, #log {
width: 0px;
height: 0px;
}
#container {
overflow: clip;
}
</style>
<div id='target'></div>
<div id="container">
<div id='target'></div>
</div>
<script>
var entries = [];