Skip to content
Permalink
Browse files
Fix :out-of-range pseudo class matching for empty input[type=number]
Fix :out-of-range pseudo class matching for empty input[type=number]
https://bugs.webkit.org/show_bug.cgi?id=249642

Reviewed by Aditya Keerthi.

This patch is to align WebKit behavior with Gecko / Firefox, Blink / Chromium and Web-Specification.

Merge - https://chromium.googlesource.com/chromium/blink/+/37a451a5e2b2b571871560111eb164ced3df1240

The definition of :out-of-range is 'either rangeUnderflow or rangeOverflow.'  If
an INPUT has no value, neither rangeUnderflow nor rangeOverflow is true.

* Source/WebCore/html/InputType.cpp:
(InputType::isInRange): Add comment for return value
(InputType::isOutOfRange): Add comment for return value and also change it to "false"
* LayoutTests/fast/css/pseudo-out-of-range.html: Updated
* LayoutTests/fast/css/pseudo-out-of-range-expected.txt: Ditto
* LayoutTests/fast/css/pseudo-in-range.html: Ditto
* LayoutTests/fast/css/pseudo-in-range-expected.txt: Ditto

Canonical link: https://commits.webkit.org/258165@main
  • Loading branch information
Ahmad-S792 authored and Ahmad Saleem committed Dec 20, 2022
1 parent 4a35ca3 commit c427ef22b3af7c014053c01382a8113d06e9f6e8
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 15 deletions.
@@ -3,6 +3,10 @@ Tests that we find controls if they have a range limitation and are in-range.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


==> :in-range should match to an INPUT without a value:
PASS document.querySelector("input[type=number]:in-range").id is "number1"

==> :in-range should match to an INPUT with an in-range value:
PASS document.querySelector("input[type=number]:in-range").id is "number1"
PASS document.querySelector("input[type=range]:in-range").id is "range1"
PASS document.querySelectorAll(":in-range").length is 2
@@ -1,20 +1,25 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
<script src="../../resources/js-test.js"></script>
</head>
<body>
<script>
description('Tests that we find controls if they have a range limitation and are in-range.');

var parentDiv = document.createElement('div');
document.body.appendChild(parentDiv);
parentDiv.innerHTML = '<input id="number1" type="number" min=0 max=10 value=5><input id="range1" type="range" min=0 max=10 value=5><input id="text1" type="text" min=0 max=10 value=5><input id="checkbox1" type="checkbox"> <input id="radio1" type="radio">';
parentDiv.innerHTML = '<input id="number1" type="number" min=0 max=10><input id="range1" type="range" min=0 max=10 value=5><input id="text1" type="text" min=0 max=10 value=5><input id="checkbox1" type="checkbox"> <input id="radio1" type="radio">';

shouldBe('document.querySelector("input[type=number]:in-range").id', '"number1"');
shouldBe('document.querySelector("input[type=range]:in-range").id', '"range1"');
debug('==> :in-range should match to an INPUT without a value:');
shouldBeEqualToString('document.querySelector("input[type=number]:in-range").id', 'number1');

debug('');
debug('==> :in-range should match to an INPUT with an in-range value:');
parentDiv.firstChild.value = '5';
shouldBeEqualToString('document.querySelector("input[type=number]:in-range").id', 'number1');
shouldBeEqualToString('document.querySelector("input[type=range]:in-range").id', 'range1');
shouldBe('document.querySelectorAll(":in-range").length', '2');
</script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
@@ -3,10 +3,14 @@ Tests that we find controls if they have a range limitation and are out-of-range
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


==> :out-of-range doesn't match to an INPUT without a value:
PASS document.querySelector("input[type=number]:out-of-range") is null

==> :out-of-range should match to an INPUT with an out-of-range value:
PASS document.querySelector("input[type=number]:out-of-range").id is "number1"
PASS document.querySelectorAll(":out-of-range").length is 1

When the value becomes in-range dynamically, we do not find the control anymore
==> When the value becomes in-range dynamically, we do not find the control anymore:
PASS document.querySelector("input[type=number]:out-of-range") is null
PASS document.querySelectorAll(":out-of-range").length is 0
PASS successfullyParsed is true
@@ -1,26 +1,31 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
<script src="../../resources/js-test.js"></script>
</head>
<body>
<script>
description('Tests that we find controls if they have a range limitation and are out-of-range.');

var parentDiv = document.createElement('div');
document.body.appendChild(parentDiv);
parentDiv.innerHTML = '<input id="number1" type="number" min=0 max=10 value=50><input id="text1" type="text" min=0 max=10 value=50><input id="checkbox1" type="checkbox"><input id="radio1" type="radio">';
parentDiv.innerHTML = '<input id="number1" type="number" min=0 max=10><input id="text1" type="text" min=0 max=10 value=50><input id="checkbox1" type="checkbox"><input id="radio1" type="radio">';

debug('==> :out-of-range doesn\'t match to an INPUT without a value:');
shouldBeNull('document.querySelector("input[type=number]:out-of-range")');

debug('');
debug('==> :out-of-range should match to an INPUT with an out-of-range value:');
parentDiv.firstChild.value = '50';
shouldBe('document.querySelector("input[type=number]:out-of-range").id', '"number1"');
shouldBe('document.querySelectorAll(":out-of-range").length', '1');

debug("");
debug("When the value becomes in-range dynamically, we do not find the control anymore");
debug('');
debug('==> When the value becomes in-range dynamically, we do not find the control anymore:');
document.getElementById("number1").value = 5;

shouldBe('document.querySelector("input[type=number]:out-of-range")', 'null');
shouldBe('document.querySelectorAll(":out-of-range").length', '0');
</script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
@@ -2,10 +2,10 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2004-2018 Apple Inc. All rights reserved.
* Copyright (C) 2004-2022 Apple Inc. All rights reserved.
* (C) 2006 Alexey Proskuryakov (ap@nypop.com)
* Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
* Copyright (C) 2009, 2010, 2011, 2012 Google Inc. All rights reserved.
* Copyright (C) 2009-2015 Google Inc. All rights reserved.
* Copyright (C) 2012 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -509,7 +509,9 @@ bool InputType::isInRange(const String& value) const
StepRange stepRange(createStepRange(AnyStepHandling::Reject));
if (!stepRange.hasRangeLimitations())
return false;


// This function should return true if both of validity.rangeUnderflow and
// validity.rangeOverflow are false. If the INPUT has no value, they are false.
const Decimal numericValue = parseToNumberOrNaN(value);
if (!numericValue.isFinite())
return true;
@@ -526,9 +528,11 @@ bool InputType::isOutOfRange(const String& value) const
if (!stepRange.hasRangeLimitations())
return false;

// This function should return true if both of validity.rangeUnderflow and
// validity.rangeOverflow are true. If the INPUT has no value, they are false.
const Decimal numericValue = parseToNumberOrNaN(value);
if (!numericValue.isFinite())
return true;
return false;

return numericValue < stepRange.minimum() || numericValue > stepRange.maximum();
}

0 comments on commit c427ef2

Please sign in to comment.