Commit a57cdd05 authored by David Shin's avatar David Shin
Browse files

Bug 1800907 - Do not `UnionRect` empty rects in `OverflowAreas::Union*`. r=jwatt

Previously, when current overflow area has one axis at zero size, calling
`OverflowAreas::Union*` with a rect with both axes at zero would overwrite
the axis with non-zero size.

Differential Revision: https://phabricator.services.mozilla.com/D162245
parent 0515d6a0
Loading
Loading
Loading
Loading
+24 −3
Original line number Diff line number Diff line
@@ -11,6 +11,19 @@

namespace mozilla {

static bool IsValidOverflowRect(const nsRect& aRect) {
  // `IsEmpty` in the context of `nsRect` means "width OR height is zero."
  // However, in the context of overflow, the rect having one axis as zero is
  // NOT considered empty.
  if (MOZ_LIKELY(!aRect.IsEmpty())) {
    return true;
  }

  // Be defensive and consider rects with any negative size as invalid.
  return !aRect.IsEqualEdges(nsRect()) && aRect.Width() >= 0 &&
         aRect.Height() >= 0;
}

/* static */
nsRect OverflowAreas::GetOverflowClipRect(const nsRect& aRectToClip,
                                          const nsRect& aBounds,
@@ -40,12 +53,20 @@ void OverflowAreas::ApplyOverflowClippingOnRect(nsRect& aOverflowRect,
}

void OverflowAreas::UnionWith(const OverflowAreas& aOther) {
  if (IsValidOverflowRect(aOther.InkOverflow())) {
    InkOverflow().UnionRect(InkOverflow(), aOther.InkOverflow());
  }
  if (IsValidOverflowRect(aOther.ScrollableOverflow())) {
    ScrollableOverflow().UnionRect(ScrollableOverflow(),
                                   aOther.ScrollableOverflow());
  }
}

void OverflowAreas::UnionAllWith(const nsRect& aRect) {
  if (!IsValidOverflowRect(aRect)) {
    // Same as `UnionWith()` - avoid losing information.
    return;
  }
  InkOverflow().UnionRect(InkOverflow(), aRect);
  ScrollableOverflow().UnionRect(ScrollableOverflow(), aRect);
}
+59 −0
Original line number Diff line number Diff line
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Overflow: Scroll Length Calculated Correctly When One Axis Has Zero Length</title>
<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollable">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1800907">
<style>
.scroll {
  overflow: scroll;
}

.zero-h {
  width: 100px;
  height: 0px;
}

.zero-w {
  width: 0;
  height: 100px;
}

.flex-row {
  display: flex;
}

.flex-col {
  display: flex;
  flex-direction: column;
}

.grid {
  display: grid;
}
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<body onload="checkLayout('.scroll')">
<div class="scroll zero-h" data-expected-scroll-height="100">
  <div class="zero-w"></div>
</div>
<div class="scroll zero-w" data-expected-scroll-width="100">
  <div class="zero-h"></div>
</div>

<div class="scroll zero-h flex-row" data-expected-scroll-height="100">
  <div class="zero-w"></div>
</div>
<div class="scroll zero-w flex-col" data-expected-scroll-width="100">
  <div class="zero-h"></div>
</div>

<div class="scroll zero-h grid" data-expected-scroll-height="100">
  <div class="zero-w"></div>
</div>
<div class="scroll zero-w grid" data-expected-scroll-width="100">
  <div class="zero-h"></div>
</div>