Bug 1715291 - Fix text in <input> is clipped by inline-end padding. r=emilio

The fix in Bug 1696885 is not correct when the width of the text in
<input> is shorter than the width of the <input>, but is long enough to
be covered by its inline-end padding.

This patch's idea is similar to the old code [1] before applying bug
1696885, but only tweak the scrollable overflow area in the inline axis.

[1] https://searchfox.org/mozilla-central/rev/c3ee9188d2f9020764db9daf8fa47a07fa3311c9/layout/generic/nsGfxScrollFrame.cpp#785-806

Differential Revision: https://phabricator.services.mozilla.com/D123244
This commit is contained in:
Ting-Yu Lin 2021-08-20 21:41:46 +00:00
parent 2078f9ba4e
commit 73a9108de9
5 changed files with 111 additions and 17 deletions

View File

@ -787,24 +787,22 @@ void nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowInput* aState,
auto* disp = StyleDisplay();
if (MOZ_UNLIKELY(disp->mOverflowClipBoxInline ==
StyleOverflowClipBox::ContentBox)) {
// If the scrolled frame can be scrolled in the inline axis, inflate its
// scrollable overflow areas with its inline-end padding to prevent its
// content from being clipped at scroll container's inline-end padding
// edge.
//
// Note: Inflating scrolled frame's overflow areas is generally wrong if the
// scrolled frame's children themselves has any scrollable overflow areas.
// However, we can only be here in production for <textarea> and <input>.
// Both elements can only have text children, which shouldn't have
// scrollable overflow areas themselves, so its fine.
// The scrolled frame is scrollable in the inline axis with
// `overflow-clip-box:content-box`. To prevent its content from being
// clipped at the scroll container's padding edges, we inflate its
// children's scrollable overflow area with its inline padding, and union
// its scrollable overflow area with its children's inflated scrollable
// overflow area.
OverflowAreas childOverflow;
mHelper.mScrolledFrame->UnionChildOverflow(childOverflow);
nsRect childScrollableOverflow = childOverflow.ScrollableOverflow();
const LogicalMargin inlinePadding =
padding.ApplySkipSides(LogicalSides(wm, eLogicalSideBitsBBoth));
childScrollableOverflow.Inflate(inlinePadding.GetPhysicalMargin(wm));
nsRect& so = aMetrics->ScrollableOverflow();
const nscoord soInlineSize = wm.IsVertical() ? so.Height() : so.Width();
if (soInlineSize > availISize) {
const LogicalMargin inlinePaddingEnd =
padding.ApplySkipSides(LogicalSides(wm, eLogicalSideBitsBBoth) |
LogicalSides(wm, eLogicalSideBitsIStart));
so.Inflate(inlinePaddingEnd.GetPhysicalMargin(wm));
}
so = so.UnionEdges(childScrollableOverflow);
}
aState->mContentsOverflowAreas = aMetrics->mOverflowAreas;

View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Overflow Reference: Test the text in an input is not clipped and reachable</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<link rel="stylesheet" href="/fonts/ahem.css">
<style>
input {
box-sizing: border-box;
width: 160px;
padding-inline: 40px 60px;
background: yellow;
font: 20px/1 Ahem;
border: 0;
}
</style>
<input value="XpX">

View File

@ -0,0 +1,28 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Overflow Test: Test the text in an input is not clipped and reachable</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://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=1715291">
<link rel="match" href="scrollable-overflow-input-001-ref.html">
<link rel="stylesheet" href="/fonts/ahem.css">
<style>
input {
box-sizing: border-box;
width: 160px;
padding-inline: 20px 60px;
background: yellow;
font: 20px/1 Ahem;
border: 0;
}
</style>
<!-- The total width of the text (120px) must be less than the <input>'s
width (160px) to reproduce this bug. -->
<input id="input" value="X XpX">
<script>
document.getElementById('input').scrollLeft = 1000;
</script>

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Overflow Reference: Test the text in an input is not clipped and reachable</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<link rel="stylesheet" href="/fonts/ahem.css">
<style>
input {
box-sizing: border-box;
width: 160px;
padding-inline: 40px 60px;
background: yellow;
font: 20px/1 Ahem;
border: 0;
direction: rtl;
}
</style>
<input value="XpX">

View File

@ -0,0 +1,29 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Overflow Test: Test the text in an input is not clipped and reachable</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://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=1715291">
<link rel="match" href="scrollable-overflow-input-002-ref.html">
<link rel="stylesheet" href="/fonts/ahem.css">
<style>
input {
box-sizing: border-box;
width: 160px;
padding-inline: 20px 60px;
background: yellow;
font: 20px/1 Ahem;
border: 0;
direction: rtl;
}
</style>
<!-- The total width of the text (120px) must be less than the <input>'s
width (160px) to reproduce this bug. -->
<input id="input2" value="XpX X">
<script>
document.getElementById('input2').scrollLeft = -1000;
</script>