Reland Input type=text Shadow DOM With Performance Improvement (#37483)

Depends on #37427.

In addition to the changes introduced by
https://github.com/servo/servo/pull/37065, there are several performance
improvements and nits as follows:
- Use the internal pseudo element for style matching, this will reduce
the performance regression by ~66%.
- Manual construction of the `Text` node inside a text container. This
is followed by the modification of the inner `Text` node instead of
using `SetTextContent` which is more expensive.
- Use `implemented_pseudo_element` instead of
`text_control_inner_editor` `NodeFlag` to handle the special cases that
these elements should follow, specifically the:
  - focus delegation workaround;
  - selections; and
  - line height resolving.
- More documentation.

Servo's side of: https://github.com/servo/stylo/pull/217

Testing: No new unexpected WPT failure, except for the one introduced by
https://github.com/servo/servo/pull/37065/.
Fixes: #36307 #37205

---------

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>
This commit is contained in:
Jo Steven Novaryo 2025-07-23 17:08:24 +08:00 committed by GitHub
parent f523445fc3
commit 3cb16eb864
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 710 additions and 85 deletions

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",
@ -3575,19 +3655,6 @@
{}
]
],
"input_placeholder.html": [
"f74cec8d54c04755bf5277db2e127fb0a37f855e",
[
null,
[
[
"/_mozilla/css/input_placeholder_ref.html",
"=="
]
],
{}
]
],
"input_selection_a.html": [
"fbee15aed7bcbae55a2771e9af422ce105b96a60",
[
@ -8062,6 +8129,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",
@ -9195,10 +9294,6 @@
"f29e061cc35625fa039473e702f78dbc5a7d9c14",
[]
],
"input_placeholder_ref.html": [
"1caffed07f2cdd341ad26ab7489e02233a6ae26c",
[]
],
"input_selection_incremental_ref.html": [
"95b24db3c3d7d8e02a6e1a89a07c1182bcb832de",
[]

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;
}

View file

@ -1,5 +0,0 @@
<!doctype html>
<meta charset="utf-8">
<title></title>
<link rel="match" href="input_placeholder_ref.html">
<input type=text placeholder="foo bar"><input type=text placeholder="foo bar">

View file

@ -1,4 +0,0 @@
<!doctype html>
<meta charset="utf-8">
<title></title>
<input type=text value="foo bar"><input type=text value="foo bar">