Implement Input type=text UA Shadow DOM (#37065)

Implement Shadow Tree construction for input `type=text`, adding a text
control inner editor container and placeholder container. Subsequently,
due to the changes of the DOM tree structure, the changes will add a new
NodeFlag `IS_TEXT_CONTROL_INNER_EDITOR` to handle the following cases.
- If a mouse click button event hits a text control inner editor, it
will redirect the focus target to its shadow host.
- In text run's construction, the text control inner editor container
queries the selection from its shadow host. This is later used to
resolve caret and selection painting in the display list.

This will be the first step of fixing input `type=text` and other
single-line text input element widgets. Such as, implementing
`::placeholder` selector.



Testing: Existing WPT test and new Servo specific appearance WPT.
Fixes: #36307

---------

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>
This commit is contained in:
Steven Novaryo 2025-05-30 20:02:10 +08:00 committed by GitHub
parent 578c52fe2b
commit 5580704438
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 635 additions and 36 deletions

View file

@ -0,0 +1,3 @@
[form-action-src-default-ignored.sub.html]
[Expecting logs: ["PASS","TEST COMPLETE"\]]
expected: FAIL

View file

@ -0,0 +1,2 @@
[spelling-markers-009.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[spelling-markers-010.html]
expected: FAIL

View file

@ -91,6 +91,86 @@
}
},
"reftest": {
"appearance": {
"input-text-definite-width.html": [
"fda46f8af9c14cef3911ec809054624204848b9d",
[
"appearance/input-text-definite-width.html",
[
[
"/_mozilla/appearance/input-text-definite-width-ref.html",
"=="
]
],
{}
]
],
"input-text-empty.html": [
"bd5f5f5a21ec0ce028922a6764de41dc904a1eb1",
[
"appearance/input-text-empty.html",
[
[
"/_mozilla/appearance/input-text-empty-ref.html",
"=="
]
],
{}
]
],
"input-text-nonempty-placeholder.html": [
"e075663cb6ae708b313b3cd5cd69f78c51b4bc1f",
[
"appearance/input-text-nonempty-placeholder.html",
[
[
"/_mozilla/appearance/input-text-nonempty-placeholder-ref.html",
"=="
]
],
{}
]
],
"input-text-overflow.html": [
"52db07c0f0274d2b7b086d7017982145c25918da",
[
"appearance/input-text-overflow.html",
[
[
"/_mozilla/appearance/input-text-overflow-ref.html",
"=="
]
],
{}
]
],
"input-text-placeholder-overflow.html": [
"c4d77ae2a22a5b7972f2798b8ca78742b81bacc4",
[
"appearance/input-text-placeholder-overflow.html",
[
[
"/_mozilla/appearance/input-text-placeholder-overflow-ref.html",
"=="
]
],
{}
]
],
"input-text-placeholder.html": [
"d75acade78038b14529135b1d63c0ac5a168a87b",
[
"appearance/input-text-placeholder.html",
[
[
"/_mozilla/appearance/input-text-placeholder-ref.html",
"=="
]
],
{}
]
]
},
"css": {
"abs-overflow-stackingcontext.html": [
"264df01aa64e0abe9ea3a75e57452c27d53a904f",
@ -8075,6 +8155,38 @@
"b485d435a63ada28eabe976b49a8a580725e7508",
[]
],
"appearance": {
"input-text-definite-width-ref.html": [
"86f7937755750261ed3b06dfe11e78a251b9d175",
[]
],
"input-text-empty-ref.html": [
"437c9988a13e094d870f67c8de0dd0becdeece76",
[]
],
"input-text-nonempty-placeholder-ref.html": [
"5415dfb2a4a88dc3bfed6ad04e23f288534351e4",
[]
],
"input-text-overflow-ref.html": [
"4cece657a2a09cfe3f1d91d49f0c9d76f5714516",
[]
],
"input-text-placeholder-overflow-ref.html": [
"0cccfff638c0d8687a3582310c73233b7d883b1a",
[]
],
"input-text-placeholder-ref.html": [
"fa5b60bdabdf2b9b818ebe66bfc7f2711173b88b",
[]
],
"supports": {
"input-text-ref.css": [
"8cf00d493138285e50aa510273abae98c099ae8b",
[]
]
}
},
"bluetooth": {
"bluetooth-helpers.js": [
"16a280cca298bcaa5796b36b48d331bfd15baae8",

View file

@ -0,0 +1,2 @@
[input_placeholder.html]
expected: FAIL

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<title>Appearance of an Input type=text With a Definite Width</title>
<link rel="stylesheet" href="./supports/input-text-ref.css">
</head>
<body>
Display of an input type=text should match the display generated by the CSS reference.
<div>
<div id="input" class="definite-width">
Foo
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Appearance of an Input type=text With a Definite Width</title>
<link rel="match" href="input-text-definite-width-ref.html">
<link rel="help" href="https://github.com/servo/servo/pull/37065">
</head>
<body>
Display of an input type=text should match the display generated by the CSS reference.
<div>
<input type="text" value="Foo" style="font-size: 1em !important; width: 100px;"></input>
</div>
</body>
</html>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<title>Appearance of an Empty Input type=text With a Definite Width</title>
<link rel="stylesheet" href="./supports/input-text-ref.css">
</head>
<body>
Display of an input type=text should match the display generated by the CSS reference.
<div>
<div id="input" class="definite-width">
<br>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Appearance of an Empty Input type=text With a Definite Width</title>
<link rel="match" href="input-text-empty-ref.html">
<link rel="help" href="https://github.com/servo/servo/pull/37065">
</head>
<body>
Display of an input type=text should match the display generated by the CSS reference.
<div>
<input type="text" style="font-size: 1em !important; width: 100px;"></input>
</div>
</body>
</html>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<title>Appearance of a Non-empty Input type=text With a Definite Width and a Placeholder</title>
<link rel="stylesheet" href="./supports/input-text-ref.css">
</head>
<body>
Display of an input type=text should match the display generated by the CSS reference.
<div>
<div id="input" class="definite-width">
Foo
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Appearance of a Non-empty Input type=text With a Definite Width and a Placeholder</title>
<link rel="match" href="input-text-nonempty-placeholder-ref.html">
<link rel="help" href="https://github.com/servo/servo/pull/37065">
</head>
<body>
Display of an input type=text should match the display generated by the CSS reference.
<div>
<input type="text" value="Foo" placeholder="Bar" style="font-size: 1em !important; width: 100px;"></input>
</div>
</body>
</html>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<title>Appearance of an Overflowing Input type=text With a Definite Width</title>
<link rel="stylesheet" href="./supports/input-text-ref.css">
</head>
<body>
Display of an input type=text should match the display generated by the CSS reference.
<div>
<div id="input" class="definite-width">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Appearance of an Overflowing Input type=text With a Definite Width</title>
<link rel="match" href="input-text-overflow-ref.html">
<link rel="help" href="https://github.com/servo/servo/pull/37065">
</head>
<body>
Display of an input type=text should match the display generated by the CSS reference.
<div>
<input type="text" value="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." style="font-size: 1em !important; width: 100px;"></input>
</div>
</body>
</html>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<title>Appearance of an Input type=text With a Definite Width and an Overflowing Placeholder</title>
<link rel="stylesheet" href="./supports/input-text-ref.css">
</head>
<body>
Display of an input type=text should match the display generated by the CSS reference.
<div>
<div id="input" class="definite-width placeholder-color">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Appearance of an Input type=text With a Definite Width and an Overflowing Placeholder</title>
<link rel="match" href="input-text-placeholder-overflow-ref.html">
<link rel="help" href="https://github.com/servo/servo/pull/37065">
</head>
<body>
Display of an input type=text should match the display generated by the CSS reference.
<div>
<input type="text" placeholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." style="font-size: 1em !important; width: 100px;"></input>
</div>
</body>
</html>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<title>Appearance of an Input type=text With a Definite Width and a Placeholder</title>
<link rel="stylesheet" href="./supports/input-text-ref.css">
</head>
<body>
Display of an input type=text should match the display generated by the CSS reference.
<div>
<div id="input" class="definite-width placeholder-color">
Bar
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Appearance of an Input type=text With a Definite Width and a Placeholder</title>
<link rel="match" href="input-text-placeholder-ref.html">
<link rel="help" href="https://github.com/servo/servo/pull/37065">
</head>
<body>
Display of an input type=text should match the display generated by the CSS reference.
<div>
<input type="text" placeholder="Bar" style="font-size: 1em !important; width: 100px;"></input>
</div>
</body>
</html>

View file

@ -0,0 +1,27 @@
/* Minimal stylesheet to mimic the appearence of an input type=text specific to Servo.
* This stylesheet is expected to be modified following the development of the
* Shadow DOM input type=text in Servo.
*/
#input {
display: inline-block;
background: white;
border: solid lightgrey 1px;
font-family: sans-serif;
font-size: 1em; /* We are using 1em here to reduce the effect of inconsistencies in layout */
overflow: hidden;
white-space: nowrap;
}
/* We are using definite width for most of the test to reduce the effect if calculating inline
* size of the input element. Which, will depends on the average character width of a font.
*
* <https://html.spec.whatwg.org/#converting-a-character-width-to-pixels>
*/
.definite-width {
width: 100px;
}
.placeholder-color {
color: grey;
}