Skip to content

Commit

Permalink
Bug 1830576 - Update textarea intrinsic height calculations r=dholbert
Browse files Browse the repository at this point in the history
This change adds a new layout.forms.textarea-sizing-excludes-auto-scrollbar.enabled pref that controls the height calculations for textareas.

With the pref enabled (the default) textareas only include the scrollbar size in the height calculations when overflow-x is scroll, this matches Chromium and WebKit.

Also adds a corresponding WPT for this.

Differential Revision: https://phabricator.services.mozilla.com/D210796
  • Loading branch information
lukewarlow committed May 18, 2024
1 parent 4241f99 commit 12a4e6f
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 5 deletions.
16 changes: 15 additions & 1 deletion layout/forms/nsTextControlFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,21 @@ LogicalSize nsTextControlFrame::CalcIntrinsicSize(gfxContext* aRenderingContext,
LogicalMargin scrollbarSizes(aWM,
scrollableFrame->GetDesiredScrollbarSizes());
intrinsicSize.ISize(aWM) += scrollbarSizes.IStartEnd(aWM);
intrinsicSize.BSize(aWM) += scrollbarSizes.BStartEnd(aWM);

// We only include scrollbar-thickness in our BSize if the scrollbar on
// that side is explicitly forced-to-be-present.
const bool includeScrollbarBSize = [&] {
if (!StaticPrefs::
layout_forms_textarea_sizing_excludes_auto_scrollbar_enabled()) {
return true;
}
auto overflow = aWM.IsVertical() ? StyleDisplay()->mOverflowY
: StyleDisplay()->mOverflowX;
return overflow == StyleOverflow::Scroll;
}();
if (includeScrollbarBSize) {
intrinsicSize.BSize(aWM) += scrollbarSizes.BStartEnd(aWM);
}
}
}
return intrinsicSize;
Expand Down
7 changes: 7 additions & 0 deletions modules/libpref/init/StaticPrefList.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9239,6 +9239,13 @@
value: true
mirror: always

# If enabled, textareas won't include 'overflow:auto' scrollbars in their
# block-axis size (usually height).
- name: layout.forms.textarea-sizing-excludes-auto-scrollbar.enabled
type: bool
value: true
mirror: always

# Pref to control browser frame rate, in Hz. A value <= 0 means choose
# automatically based on knowledge of the platform (or 60Hz if no platform-
# specific information is available).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
[textarea-placeholder-lineheight.html]
expected:
if (os == "android") and fission: [TIMEOUT, OK]
[Bounding rect height for textarea must be the same as line-height]
expected:
if os == "android": PASS
FAIL
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!DOCTYPE html>
<link rel="help" href="https://html.spec.whatwg.org/C/#the-textarea-element-2">
<title>Test textarea width and height accounting for scrollbars</title>
<meta name="author" title="Luke Warlow" href="mailto:lwarlow@igalia.com">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<textarea id="rows1" rows="1"></textarea>
<textarea id="rows1Hidden" rows="1" style="overflow-x: hidden"></textarea>
<textarea id="rows1Scroll" rows="1" style="overflow-x: scroll"></textarea>
<textarea id="cols3" cols="3"></textarea>
<textarea id="cols3Hidden" cols="3" style="overflow-y: hidden"></textarea>
<textarea id="cols3Scroll" cols="3" style="overflow-y: scroll"></textarea>
<div id="scrollableDiv" style="overflow:scroll"></div>

<script>
const scrollbarsHaveThickness = (scrollableDiv.offsetHeight != 0);
test(() => {
assert_equals(rows1.offsetWidth, rows1Hidden.offsetWidth);
assert_equals(rows1.offsetHeight, rows1Hidden.offsetHeight);
}, 'rows=1 doesnt include scrollbar thickness');

test(() => {
assert_equals(rows1.offsetWidth, rows1Scroll.offsetWidth);
if (scrollbarsHaveThickness) {
assert_less_than(rows1.offsetHeight, rows1Scroll.offsetHeight);
} else {
assert_equals(rows1.offsetHeight, rows1Scroll.offsetHeight);
}
}, 'rows=1 overflow scroll includes scrollbar thickness');

test(() => {
assert_equals(cols3.offsetWidth, cols3Scroll.offsetWidth);
if (scrollbarsHaveThickness) {
assert_greater_than(cols3.offsetWidth, cols3Hidden.offsetWidth);
} else {
assert_equals(cols3.offsetWidth, cols3Hidden.offsetWidth);
}
assert_equals(cols3.offsetHeight, cols3Scroll.offsetHeight);
assert_equals(cols3.offsetHeight, cols3Hidden.offsetHeight);
}, 'cols=3 includes scrollbar thickness');
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<link rel="help" href="https://html.spec.whatwg.org/C/#the-textarea-element-2">
<title>Test textarea width and height accounting for scrollbars, with vertical writing mode</title>
<meta name="author" title="Luke Warlow" href="mailto:lwarlow@igalia.com">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<style>textarea { writing-mode: vertical-lr }</style>
<textarea id="rows1" rows="1"></textarea>
<textarea id="rows1Hidden" rows="1" style="overflow-y: hidden"></textarea>
<textarea id="rows1Scroll" rows="1" style="overflow-y: scroll"></textarea>
<textarea id="cols3" cols="3"></textarea>
<textarea id="cols3Hidden" cols="3" style="overflow-x: hidden"></textarea>
<textarea id="cols3Scroll" cols="3" style="overflow-x: scroll"></textarea>
<div id="scrollableDiv" style="overflow:scroll"></div>

<script>
const scrollbarsHaveThickness = (scrollableDiv.offsetHeight != 0);
test(() => {
assert_equals(rows1.offsetHeight, rows1Hidden.offsetHeight);
assert_equals(rows1.offsetWidth, rows1Hidden.offsetWidth);
}, 'rows=1 doesnt include scrollbar thickness');

test(() => {
assert_equals(rows1.offsetHeight, rows1Scroll.offsetHeight);
if (scrollbarsHaveThickness) {
assert_less_than(rows1.offsetWidth, rows1Scroll.offsetWidth);
} else {
assert_equals(rows1.offsetWidth, rows1Scroll.offsetWidth);
}
}, 'rows=1 overflow scroll includes scrollbar thickness');

test(() => {
assert_equals(cols3.offsetHeight, cols3Scroll.offsetHeight);
if (scrollbarsHaveThickness) {
assert_greater_than(cols3.offsetHeight, cols3Hidden.offsetHeight);
} else {
assert_equals(cols3.offsetHeight, cols3Hidden.offsetHeight);
}
assert_equals(cols3.offsetWidth, cols3Scroll.offsetWidth);
assert_equals(cols3.offsetWidth, cols3Hidden.offsetWidth);
}, 'cols=3 includes scrollbar thickness');
</script>

0 comments on commit 12a4e6f

Please sign in to comment.