mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-28 11:49:44 +00:00
LibWeb/HTML: Correctly reset selection on type change
The selection now gets reset to the beginning of the control if the type changes from an unselectable type to a selectable type.
This commit is contained in:
parent
84e29f791c
commit
5f75558646
Notes:
github-actions[bot]
2025-04-23 06:21:13 +00:00
Author: https://github.com/skyz1
Commit: 5f75558646
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4410
Reviewed-by: https://github.com/tcl3 ✅
3 changed files with 552 additions and 0 deletions
|
@ -1470,6 +1470,7 @@ void HTMLInputElement::type_attribute_changed(TypeAttributeState old_state, Type
|
|||
// 9. If previouslySelectable is false and nowSelectable is true, set the element's text entry cursor position to the
|
||||
// beginning of the text control, and set its selection direction to "none".
|
||||
if (!previously_selectable && now_selectable) {
|
||||
set_the_selection_range(0, 0);
|
||||
set_selection_direction(OptionalNone {});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,385 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 380 tests
|
||||
|
||||
380 Pass
|
||||
Pass change state from hidden to text
|
||||
Pass change state from hidden to search
|
||||
Pass change state from hidden to tel
|
||||
Pass change state from hidden to url
|
||||
Pass change state from hidden to email
|
||||
Pass change state from hidden to password
|
||||
Pass change state from hidden to datetime-local
|
||||
Pass change state from hidden to date
|
||||
Pass change state from hidden to time
|
||||
Pass change state from hidden to number
|
||||
Pass change state from hidden to range
|
||||
Pass change state from hidden to color
|
||||
Pass change state from hidden to checkbox
|
||||
Pass change state from hidden to radio
|
||||
Pass change state from hidden to file
|
||||
Pass change state from hidden to submit
|
||||
Pass change state from hidden to image
|
||||
Pass change state from hidden to reset
|
||||
Pass change state from hidden to button
|
||||
Pass change state from text to hidden
|
||||
Pass change state from text to search
|
||||
Pass change state from text to tel
|
||||
Pass change state from text to url
|
||||
Pass change state from text to email
|
||||
Pass change state from text to password
|
||||
Pass change state from text to datetime-local
|
||||
Pass change state from text to date
|
||||
Pass change state from text to time
|
||||
Pass change state from text to number
|
||||
Pass change state from text to range
|
||||
Pass change state from text to color
|
||||
Pass change state from text to checkbox
|
||||
Pass change state from text to radio
|
||||
Pass change state from text to file
|
||||
Pass change state from text to submit
|
||||
Pass change state from text to image
|
||||
Pass change state from text to reset
|
||||
Pass change state from text to button
|
||||
Pass change state from search to hidden
|
||||
Pass change state from search to text
|
||||
Pass change state from search to tel
|
||||
Pass change state from search to url
|
||||
Pass change state from search to email
|
||||
Pass change state from search to password
|
||||
Pass change state from search to datetime-local
|
||||
Pass change state from search to date
|
||||
Pass change state from search to time
|
||||
Pass change state from search to number
|
||||
Pass change state from search to range
|
||||
Pass change state from search to color
|
||||
Pass change state from search to checkbox
|
||||
Pass change state from search to radio
|
||||
Pass change state from search to file
|
||||
Pass change state from search to submit
|
||||
Pass change state from search to image
|
||||
Pass change state from search to reset
|
||||
Pass change state from search to button
|
||||
Pass change state from tel to hidden
|
||||
Pass change state from tel to text
|
||||
Pass change state from tel to search
|
||||
Pass change state from tel to url
|
||||
Pass change state from tel to email
|
||||
Pass change state from tel to password
|
||||
Pass change state from tel to datetime-local
|
||||
Pass change state from tel to date
|
||||
Pass change state from tel to time
|
||||
Pass change state from tel to number
|
||||
Pass change state from tel to range
|
||||
Pass change state from tel to color
|
||||
Pass change state from tel to checkbox
|
||||
Pass change state from tel to radio
|
||||
Pass change state from tel to file
|
||||
Pass change state from tel to submit
|
||||
Pass change state from tel to image
|
||||
Pass change state from tel to reset
|
||||
Pass change state from tel to button
|
||||
Pass change state from url to hidden
|
||||
Pass change state from url to text
|
||||
Pass change state from url to search
|
||||
Pass change state from url to tel
|
||||
Pass change state from url to email
|
||||
Pass change state from url to password
|
||||
Pass change state from url to datetime-local
|
||||
Pass change state from url to date
|
||||
Pass change state from url to time
|
||||
Pass change state from url to number
|
||||
Pass change state from url to range
|
||||
Pass change state from url to color
|
||||
Pass change state from url to checkbox
|
||||
Pass change state from url to radio
|
||||
Pass change state from url to file
|
||||
Pass change state from url to submit
|
||||
Pass change state from url to image
|
||||
Pass change state from url to reset
|
||||
Pass change state from url to button
|
||||
Pass change state from email to hidden
|
||||
Pass change state from email to text
|
||||
Pass change state from email to search
|
||||
Pass change state from email to tel
|
||||
Pass change state from email to url
|
||||
Pass change state from email to password
|
||||
Pass change state from email to datetime-local
|
||||
Pass change state from email to date
|
||||
Pass change state from email to time
|
||||
Pass change state from email to number
|
||||
Pass change state from email to range
|
||||
Pass change state from email to color
|
||||
Pass change state from email to checkbox
|
||||
Pass change state from email to radio
|
||||
Pass change state from email to file
|
||||
Pass change state from email to submit
|
||||
Pass change state from email to image
|
||||
Pass change state from email to reset
|
||||
Pass change state from email to button
|
||||
Pass change state from password to hidden
|
||||
Pass change state from password to text
|
||||
Pass change state from password to search
|
||||
Pass change state from password to tel
|
||||
Pass change state from password to url
|
||||
Pass change state from password to email
|
||||
Pass change state from password to datetime-local
|
||||
Pass change state from password to date
|
||||
Pass change state from password to time
|
||||
Pass change state from password to number
|
||||
Pass change state from password to range
|
||||
Pass change state from password to color
|
||||
Pass change state from password to checkbox
|
||||
Pass change state from password to radio
|
||||
Pass change state from password to file
|
||||
Pass change state from password to submit
|
||||
Pass change state from password to image
|
||||
Pass change state from password to reset
|
||||
Pass change state from password to button
|
||||
Pass change state from datetime-local to hidden
|
||||
Pass change state from datetime-local to text
|
||||
Pass change state from datetime-local to search
|
||||
Pass change state from datetime-local to tel
|
||||
Pass change state from datetime-local to url
|
||||
Pass change state from datetime-local to email
|
||||
Pass change state from datetime-local to password
|
||||
Pass change state from datetime-local to date
|
||||
Pass change state from datetime-local to time
|
||||
Pass change state from datetime-local to number
|
||||
Pass change state from datetime-local to range
|
||||
Pass change state from datetime-local to color
|
||||
Pass change state from datetime-local to checkbox
|
||||
Pass change state from datetime-local to radio
|
||||
Pass change state from datetime-local to file
|
||||
Pass change state from datetime-local to submit
|
||||
Pass change state from datetime-local to image
|
||||
Pass change state from datetime-local to reset
|
||||
Pass change state from datetime-local to button
|
||||
Pass change state from date to hidden
|
||||
Pass change state from date to text
|
||||
Pass change state from date to search
|
||||
Pass change state from date to tel
|
||||
Pass change state from date to url
|
||||
Pass change state from date to email
|
||||
Pass change state from date to password
|
||||
Pass change state from date to datetime-local
|
||||
Pass change state from date to time
|
||||
Pass change state from date to number
|
||||
Pass change state from date to range
|
||||
Pass change state from date to color
|
||||
Pass change state from date to checkbox
|
||||
Pass change state from date to radio
|
||||
Pass change state from date to file
|
||||
Pass change state from date to submit
|
||||
Pass change state from date to image
|
||||
Pass change state from date to reset
|
||||
Pass change state from date to button
|
||||
Pass change state from time to hidden
|
||||
Pass change state from time to text
|
||||
Pass change state from time to search
|
||||
Pass change state from time to tel
|
||||
Pass change state from time to url
|
||||
Pass change state from time to email
|
||||
Pass change state from time to password
|
||||
Pass change state from time to datetime-local
|
||||
Pass change state from time to date
|
||||
Pass change state from time to number
|
||||
Pass change state from time to range
|
||||
Pass change state from time to color
|
||||
Pass change state from time to checkbox
|
||||
Pass change state from time to radio
|
||||
Pass change state from time to file
|
||||
Pass change state from time to submit
|
||||
Pass change state from time to image
|
||||
Pass change state from time to reset
|
||||
Pass change state from time to button
|
||||
Pass change state from number to hidden
|
||||
Pass change state from number to text
|
||||
Pass change state from number to search
|
||||
Pass change state from number to tel
|
||||
Pass change state from number to url
|
||||
Pass change state from number to email
|
||||
Pass change state from number to password
|
||||
Pass change state from number to datetime-local
|
||||
Pass change state from number to date
|
||||
Pass change state from number to time
|
||||
Pass change state from number to range
|
||||
Pass change state from number to color
|
||||
Pass change state from number to checkbox
|
||||
Pass change state from number to radio
|
||||
Pass change state from number to file
|
||||
Pass change state from number to submit
|
||||
Pass change state from number to image
|
||||
Pass change state from number to reset
|
||||
Pass change state from number to button
|
||||
Pass change state from range to hidden
|
||||
Pass change state from range to text
|
||||
Pass change state from range to search
|
||||
Pass change state from range to tel
|
||||
Pass change state from range to url
|
||||
Pass change state from range to email
|
||||
Pass change state from range to password
|
||||
Pass change state from range to datetime-local
|
||||
Pass change state from range to date
|
||||
Pass change state from range to time
|
||||
Pass change state from range to number
|
||||
Pass change state from range to color
|
||||
Pass change state from range to checkbox
|
||||
Pass change state from range to radio
|
||||
Pass change state from range to file
|
||||
Pass change state from range to submit
|
||||
Pass change state from range to image
|
||||
Pass change state from range to reset
|
||||
Pass change state from range to button
|
||||
Pass change state from color to hidden
|
||||
Pass change state from color to text
|
||||
Pass change state from color to search
|
||||
Pass change state from color to tel
|
||||
Pass change state from color to url
|
||||
Pass change state from color to email
|
||||
Pass change state from color to password
|
||||
Pass change state from color to datetime-local
|
||||
Pass change state from color to date
|
||||
Pass change state from color to time
|
||||
Pass change state from color to number
|
||||
Pass change state from color to range
|
||||
Pass change state from color to checkbox
|
||||
Pass change state from color to radio
|
||||
Pass change state from color to file
|
||||
Pass change state from color to submit
|
||||
Pass change state from color to image
|
||||
Pass change state from color to reset
|
||||
Pass change state from color to button
|
||||
Pass change state from checkbox to hidden
|
||||
Pass change state from checkbox to text
|
||||
Pass change state from checkbox to search
|
||||
Pass change state from checkbox to tel
|
||||
Pass change state from checkbox to url
|
||||
Pass change state from checkbox to email
|
||||
Pass change state from checkbox to password
|
||||
Pass change state from checkbox to datetime-local
|
||||
Pass change state from checkbox to date
|
||||
Pass change state from checkbox to time
|
||||
Pass change state from checkbox to number
|
||||
Pass change state from checkbox to range
|
||||
Pass change state from checkbox to color
|
||||
Pass change state from checkbox to radio
|
||||
Pass change state from checkbox to file
|
||||
Pass change state from checkbox to submit
|
||||
Pass change state from checkbox to image
|
||||
Pass change state from checkbox to reset
|
||||
Pass change state from checkbox to button
|
||||
Pass change state from radio to hidden
|
||||
Pass change state from radio to text
|
||||
Pass change state from radio to search
|
||||
Pass change state from radio to tel
|
||||
Pass change state from radio to url
|
||||
Pass change state from radio to email
|
||||
Pass change state from radio to password
|
||||
Pass change state from radio to datetime-local
|
||||
Pass change state from radio to date
|
||||
Pass change state from radio to time
|
||||
Pass change state from radio to number
|
||||
Pass change state from radio to range
|
||||
Pass change state from radio to color
|
||||
Pass change state from radio to checkbox
|
||||
Pass change state from radio to file
|
||||
Pass change state from radio to submit
|
||||
Pass change state from radio to image
|
||||
Pass change state from radio to reset
|
||||
Pass change state from radio to button
|
||||
Pass change state from file to hidden
|
||||
Pass change state from file to text
|
||||
Pass change state from file to search
|
||||
Pass change state from file to tel
|
||||
Pass change state from file to url
|
||||
Pass change state from file to email
|
||||
Pass change state from file to password
|
||||
Pass change state from file to datetime-local
|
||||
Pass change state from file to date
|
||||
Pass change state from file to time
|
||||
Pass change state from file to number
|
||||
Pass change state from file to range
|
||||
Pass change state from file to color
|
||||
Pass change state from file to checkbox
|
||||
Pass change state from file to radio
|
||||
Pass change state from file to submit
|
||||
Pass change state from file to image
|
||||
Pass change state from file to reset
|
||||
Pass change state from file to button
|
||||
Pass change state from submit to hidden
|
||||
Pass change state from submit to text
|
||||
Pass change state from submit to search
|
||||
Pass change state from submit to tel
|
||||
Pass change state from submit to url
|
||||
Pass change state from submit to email
|
||||
Pass change state from submit to password
|
||||
Pass change state from submit to datetime-local
|
||||
Pass change state from submit to date
|
||||
Pass change state from submit to time
|
||||
Pass change state from submit to number
|
||||
Pass change state from submit to range
|
||||
Pass change state from submit to color
|
||||
Pass change state from submit to checkbox
|
||||
Pass change state from submit to radio
|
||||
Pass change state from submit to file
|
||||
Pass change state from submit to image
|
||||
Pass change state from submit to reset
|
||||
Pass change state from submit to button
|
||||
Pass change state from image to hidden
|
||||
Pass change state from image to text
|
||||
Pass change state from image to search
|
||||
Pass change state from image to tel
|
||||
Pass change state from image to url
|
||||
Pass change state from image to email
|
||||
Pass change state from image to password
|
||||
Pass change state from image to datetime-local
|
||||
Pass change state from image to date
|
||||
Pass change state from image to time
|
||||
Pass change state from image to number
|
||||
Pass change state from image to range
|
||||
Pass change state from image to color
|
||||
Pass change state from image to checkbox
|
||||
Pass change state from image to radio
|
||||
Pass change state from image to file
|
||||
Pass change state from image to submit
|
||||
Pass change state from image to reset
|
||||
Pass change state from image to button
|
||||
Pass change state from reset to hidden
|
||||
Pass change state from reset to text
|
||||
Pass change state from reset to search
|
||||
Pass change state from reset to tel
|
||||
Pass change state from reset to url
|
||||
Pass change state from reset to email
|
||||
Pass change state from reset to password
|
||||
Pass change state from reset to datetime-local
|
||||
Pass change state from reset to date
|
||||
Pass change state from reset to time
|
||||
Pass change state from reset to number
|
||||
Pass change state from reset to range
|
||||
Pass change state from reset to color
|
||||
Pass change state from reset to checkbox
|
||||
Pass change state from reset to radio
|
||||
Pass change state from reset to file
|
||||
Pass change state from reset to submit
|
||||
Pass change state from reset to image
|
||||
Pass change state from reset to button
|
||||
Pass change state from button to hidden
|
||||
Pass change state from button to text
|
||||
Pass change state from button to search
|
||||
Pass change state from button to tel
|
||||
Pass change state from button to url
|
||||
Pass change state from button to email
|
||||
Pass change state from button to password
|
||||
Pass change state from button to datetime-local
|
||||
Pass change state from button to date
|
||||
Pass change state from button to time
|
||||
Pass change state from button to number
|
||||
Pass change state from button to range
|
||||
Pass change state from button to color
|
||||
Pass change state from button to checkbox
|
||||
Pass change state from button to radio
|
||||
Pass change state from button to file
|
||||
Pass change state from button to submit
|
||||
Pass change state from button to image
|
||||
Pass change state from button to reset
|
|
@ -0,0 +1,166 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Input element's type attribute changes state</title>
|
||||
<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
|
||||
<link rel=help href="https://html.spec.whatwg.org/multipage/#the-input-element">
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
|
||||
const INITIAL_VALUE = " foo\rbar ";
|
||||
|
||||
// Sanitize algorithm implementations only for values used in this test.
|
||||
function sanitizeText(value) {
|
||||
switch (value) {
|
||||
case INITIAL_VALUE: return " foobar ";
|
||||
case " foobar ": return value;
|
||||
case "foobar": return value;
|
||||
case "50": return value;
|
||||
case "#000000": return value;
|
||||
case "": return value;
|
||||
default: throw new DOMException(`Internal Error: Should add support of "${value}"`, "NotSupportedError");
|
||||
}
|
||||
}
|
||||
function sanitizeEmailOrUrl(value) {
|
||||
switch (value) {
|
||||
case INITIAL_VALUE: return "foobar";
|
||||
case " foobar ": return "foobar";
|
||||
case "foobar": return value;
|
||||
case "50": return value;
|
||||
case "#000000": return value;
|
||||
case "": return value;
|
||||
default: throw new DOMException(`Internal Error: Should add support of "${value}"`, "NotSupportedError");
|
||||
}
|
||||
}
|
||||
function sanitizeTemporal(value) {
|
||||
// We have no test cases using valid temporal values.
|
||||
return "";
|
||||
}
|
||||
function sanitizeNumber(value) {
|
||||
switch (value) {
|
||||
case "50": return value;
|
||||
default:
|
||||
// We have no test cases using valid numbers other than "50".
|
||||
return "";
|
||||
}
|
||||
}
|
||||
function sanitizeRange(value) {
|
||||
// We have no test cases using valid numbers other than "50".
|
||||
return "50";
|
||||
}
|
||||
function sanitizeColor(value) {
|
||||
// We have no test cases using valid colors other than "#000000".
|
||||
return "#000000";
|
||||
}
|
||||
function browserSupportsInputTypeOf(inputType) {
|
||||
var inputTest = document.createElement("input");
|
||||
inputTest.type = inputType;
|
||||
return (inputTest.type === inputType);
|
||||
}
|
||||
|
||||
|
||||
var types = [
|
||||
{ type: "hidden" },
|
||||
{ type: "text", sanitizer: sanitizeText },
|
||||
{ type: "search", sanitizer: sanitizeText },
|
||||
{ type: "tel", sanitizer: sanitizeText },
|
||||
{ type: "url", sanitizer: sanitizeEmailOrUrl },
|
||||
{ type: "email", sanitizer: sanitizeEmailOrUrl },
|
||||
{ type: "password", sanitizer: sanitizeText },
|
||||
{ type: "datetime-local", sanitizer: sanitizeTemporal },
|
||||
{ type: "date", sanitizer: sanitizeTemporal },
|
||||
{ type: "time", sanitizer: sanitizeTemporal },
|
||||
{ type: "number", sanitizer: sanitizeNumber },
|
||||
{ type: "range", sanitizer: sanitizeRange },
|
||||
{ type: "color", sanitizer: sanitizeColor },
|
||||
{ type: "checkbox", defaultValue: "on" },
|
||||
{ type: "radio", defaultValue: "on" },
|
||||
{ type: "file" },
|
||||
{ type: "submit" },
|
||||
{ type: "image" },
|
||||
{ type: "reset" },
|
||||
{ type: "button" }
|
||||
];
|
||||
|
||||
const selectionStart = 2;
|
||||
const selectionEnd = 5;
|
||||
const selectionDirection = "backward";
|
||||
|
||||
// Obtain selectionDirection after setting it to "none".
|
||||
// Some platforms don't support "none" direction, and "forward" is returned
|
||||
// in such platforms.
|
||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#set-the-selection-direction
|
||||
function testNoneDirection() {
|
||||
const input = document.createElement("input");
|
||||
input.selectionDirection = "none";
|
||||
return input.selectionDirection;
|
||||
}
|
||||
const noneDirectionResult = testNoneDirection();
|
||||
|
||||
for (var i = 0; i < types.length; i++) {
|
||||
for (var j = 0; j < types.length; j++) {
|
||||
if (types[i] != types[j]) {
|
||||
test(function() {
|
||||
assert_implements(browserSupportsInputTypeOf(types[i].type), "Support for input type " + types[i].type + " is required for this test.");
|
||||
assert_implements(browserSupportsInputTypeOf(types[j].type), "Support for input type " + types[j].type + " is required for this test.");
|
||||
var input = document.createElement("input");
|
||||
var expected = INITIAL_VALUE;
|
||||
input.type = types[i].type;
|
||||
if (types[i].type === "file") {
|
||||
assert_throws_dom("INVALID_STATE_ERR", function() {
|
||||
input.value = expected;
|
||||
});
|
||||
assert_equals(input.value, "");
|
||||
} else if (types[j].type === "file") {
|
||||
input.value = expected;
|
||||
input.type = types[j].type; // change state
|
||||
assert_equals(input.value, "");
|
||||
} else {
|
||||
input.value = expected;
|
||||
expected = input.value;
|
||||
|
||||
const previouslySelectable = (input.selectionStart !== null);
|
||||
|
||||
if (previouslySelectable) {
|
||||
input.setSelectionRange(selectionStart, selectionEnd, selectionDirection);
|
||||
}
|
||||
|
||||
input.type = types[j].type; // change state
|
||||
|
||||
var preSanitizeValue = expected;
|
||||
// type[j] sanitization
|
||||
if (types[j].sanitizer) {
|
||||
expected = types[j].sanitizer(expected);
|
||||
}
|
||||
|
||||
// type[j] defaultValue
|
||||
if (expected === "" && types[j].defaultValue) {
|
||||
expected = types[j].defaultValue;
|
||||
}
|
||||
|
||||
assert_equals(input.value, expected, "input.value should be '" + expected + "' after change of state");
|
||||
|
||||
const nowSelectable = (input.selectionStart !== null);
|
||||
|
||||
if (nowSelectable) {
|
||||
if (previouslySelectable) {
|
||||
// Value might change after sanitization. The following checks are only valid when the value stays the same.
|
||||
if (preSanitizeValue === expected) {
|
||||
assert_equals(input.selectionStart, selectionStart, "selectionStart should be unchanged");
|
||||
assert_equals(input.selectionEnd, selectionEnd, "selectionEnd should be unchanged");
|
||||
assert_equals(input.selectionDirection, selectionDirection, "selectionDirection should be unchanged");
|
||||
}
|
||||
} else {
|
||||
assert_equals(input.selectionStart, 0, "selectionStart should be 0");
|
||||
assert_equals(input.selectionEnd, 0, "selectionEnd should be 0");
|
||||
assert_equals(input.selectionDirection, noneDirectionResult,
|
||||
`selectionDirection should be '{noneDirectionResult}'`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, "change state from " + types[i].type + " to " + types[j].type);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue