Skip to content

Commit 5a708d8

Browse files
committedSep 10, 2024
Bug 1917456 - Fix nsRangeFrame::GetValueAtEventPoint on themed range inputs with padding. r=dholbert
Other browsers agree with us on drawing at the border-box size when themed, so just fix the code to deal with it. Differential Revision: https://phabricator.services.mozilla.com/D221519
1 parent c08146b commit 5a708d8

File tree

2 files changed

+27
-13
lines changed

2 files changed

+27
-13
lines changed
 

‎dom/html/test/forms/test_input_range_mouse_and_touch_events.html

+19-7
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@
1919
* predict exactly what value the input should take on for events at
2020
* certain coordinates.)
2121
*/
22-
input { margin: 0 ! important; width: 200px ! important; }
22+
input { margin: 0 !important; width: 200px !important; padding-inline: 100px; }
2323
</style>
2424
</head>
2525
<body>
2626
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=846380">Mozilla Bug 846380</a>
2727
<p id="display"></p>
2828
<div id="content">
29-
<input id="range" type="range">
29+
<input id="range" type="range"><br>
30+
<input id="range-appearance-none" type="range" style="appearance: none">
3031
</div>
3132
<pre id="test">
3233
<script type="application/javascript">
@@ -40,10 +41,13 @@
4041
* This test checks how the value of <input type=range> changes in response to
4142
* various mouse and touch events.
4243
**/
44+
SimpleTest.expectAssertions(0, 2); // bug 1917867
4345
SimpleTest.waitForExplicitFinish();
4446
SimpleTest.waitForFocus(function() {
45-
test(synthesizeMouse, "click", "mousedown", "mousemove", "mouseup");
46-
test(synthesizeTouch, "tap", "touchstart", "touchmove", "touchend");
47+
for (let element of document.querySelectorAll("input[type=range]")) {
48+
test(element, synthesizeMouse, "click", "mousedown", "mousemove", "mouseup");
49+
test(element, synthesizeTouch, "tap", "touchstart", "touchmove", "touchend");
50+
}
4751
SimpleTest.finish();
4852
});
4953

@@ -62,8 +66,9 @@
6266
document.body.clientWidth;
6367
}
6468

65-
function test(synthesizeFunc, clickOrTap, startName, moveName, endName) {
66-
var elem = document.getElementById("range");
69+
function test(elem, synthesizeFunc, clickOrTap, startName, moveName, endName) {
70+
info(`Testing ${elem.id}`);
71+
6772
elem.focus();
6873
flush();
6974

@@ -74,6 +79,13 @@
7479
var paddingLeft = parseFloat(window.getComputedStyle(elem).paddingLeft);
7580
var paddingTop = parseFloat(window.getComputedStyle(elem).paddingTop);
7681

82+
// If themed then we use our border-box size.
83+
if (elem.style.appearance != "none") {
84+
width += borderLeft * 2 + paddingLeft * 2;
85+
borderLeft = 0;
86+
paddingLeft = 0;
87+
}
88+
7789
// Extrema for mouse/touch events:
7890
var midY = height / 2 + borderTop + paddingTop;
7991
var minX = borderLeft + paddingLeft;
@@ -206,7 +218,7 @@
206218
synthesizeKey("KEY_Home");
207219
// The KEY_Home tests are disabled until I can figure out why they fail on Android -jwatt
208220
//is(elem.value, MINIMUM_OF_RANGE, "Test KEY_Home during a drag sets the value to the minimum of the range");
209-
synthesizeFunc(elem, midX+100, midY, { type: moveName });
221+
synthesizeFunc(elem, maxX+100, midY, { type: moveName });
210222
is(elem.value, MAXIMUM_OF_RANGE, "Test " + moveName + " outside range after key press that occurred during a drag changes the value");
211223
synthesizeFunc(elem, midX, midY, { type: moveName });
212224
is(elem.value, MIDDLE_OF_RANGE, "Test " + moveName + " in middle of range");

‎layout/forms/nsRangeFrame.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -329,10 +329,11 @@ Decimal nsRangeFrame::GetValueAtEventPoint(WidgetGUIEvent* aEvent) {
329329
->GetValueAsDecimal();
330330
}
331331

332-
const nsRect rangeContentRect = GetContentRectRelativeToSelf();
332+
nsRect rangeRect;
333333
nsSize thumbSize;
334-
335334
if (IsThemed()) {
335+
// Themed ranges draw on the border-box rect.
336+
rangeRect = GetRectRelativeToSelf();
336337
// We need to get the size of the thumb from the theme.
337338
nsPresContext* pc = PresContext();
338339
LayoutDeviceIntSize size = pc->Theme()->GetMinimumWidgetSize(
@@ -348,6 +349,7 @@ Decimal nsRangeFrame::GetValueAtEventPoint(WidgetGUIEvent* aEvent) {
348349
(!IsHorizontal() && thumbSize.height > 0),
349350
"The thumb is expected to take up some slider space");
350351
} else {
352+
rangeRect = GetContentRectRelativeToSelf();
351353
nsIFrame* thumbFrame = mThumbDiv->GetPrimaryFrame();
352354
if (thumbFrame) { // diplay:none?
353355
thumbSize = thumbFrame->GetSize();
@@ -356,23 +358,23 @@ Decimal nsRangeFrame::GetValueAtEventPoint(WidgetGUIEvent* aEvent) {
356358

357359
Decimal fraction;
358360
if (IsHorizontal()) {
359-
nscoord traversableDistance = rangeContentRect.width - thumbSize.width;
361+
nscoord traversableDistance = rangeRect.width - thumbSize.width;
360362
if (traversableDistance <= 0) {
361363
return minimum;
362364
}
363-
nscoord posAtStart = rangeContentRect.x + thumbSize.width / 2;
365+
nscoord posAtStart = rangeRect.x + thumbSize.width / 2;
364366
nscoord posAtEnd = posAtStart + traversableDistance;
365367
nscoord posOfPoint = mozilla::clamped(point.x, posAtStart, posAtEnd);
366368
fraction = Decimal(posOfPoint - posAtStart) / Decimal(traversableDistance);
367369
if (IsRightToLeft()) {
368370
fraction = Decimal(1) - fraction;
369371
}
370372
} else {
371-
nscoord traversableDistance = rangeContentRect.height - thumbSize.height;
373+
nscoord traversableDistance = rangeRect.height - thumbSize.height;
372374
if (traversableDistance <= 0) {
373375
return minimum;
374376
}
375-
nscoord posAtStart = rangeContentRect.y + thumbSize.height / 2;
377+
nscoord posAtStart = rangeRect.y + thumbSize.height / 2;
376378
nscoord posAtEnd = posAtStart + traversableDistance;
377379
nscoord posOfPoint = mozilla::clamped(point.y, posAtStart, posAtEnd);
378380
// For a vertical range, the top (posAtStart) is the highest value, so we

0 commit comments

Comments
 (0)
Failed to load comments.