diff options
author | DK Liao <dklassic@gmail.com> | 2025-04-11 15:51:52 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-11 06:51:52 +0000 |
commit | 5df4c760d36d056292161eef221165c9f41c6125 (patch) | |
tree | 613d03d19e9094b24cfc1210cbf4c74915e1674a /components/layout_2020/dom_traversal.rs | |
parent | 972ca77ce1bd2c08b809b7d54ec716213519fe1e (diff) | |
download | servo-5df4c760d36d056292161eef221165c9f41c6125.tar.gz servo-5df4c760d36d056292161eef221165c9f41c6125.zip |
fix: Crashing due to input element hack (#36461)
This PR addresses a crash in text input element due to a hack to prevent
text input being trimmed.
The updated behavior will only add `zero width space` unicode character
to the node if there's no text content instead of adding it constantly.
Also by adding the same `zero width space` unicode character to text
area when there's no text content within will allow text area element to
properly display caret.
<img width="197" alt="截圖 2025-04-11 中午12 51 00"
src="https://github.com/user-attachments/assets/10bc7314-9aa3-49df-baac-ef26d39a96d8"
/>
This PR also addresses issues with multiple glyph runs:
https://github.com/user-attachments/assets/658db56f-b166-47ec-bc77-c6c13114d669
Testing: This PR is tested using:
- `./mach run -d 'data:text/html,<input id="input_element"
value="xxxxxxxxxxxxxxxxxxxx">'`
- `./mach run -d 'data:text/html,<textarea id="input_element"
value="xxxxxxxxxxxxxxxxxxxx">'`
without causing crashes, while the results should be covered by WPT
tests
Fixes: https://github.com/servo/servo/issues/36449
---------
Signed-off-by: DK Liao <dklassic@gmail.com>
Diffstat (limited to 'components/layout_2020/dom_traversal.rs')
-rw-r--r-- | components/layout_2020/dom_traversal.rs | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/components/layout_2020/dom_traversal.rs b/components/layout_2020/dom_traversal.rs index 1b9258fb824..966cf83443a 100644 --- a/components/layout_2020/dom_traversal.rs +++ b/components/layout_2020/dom_traversal.rs @@ -212,12 +212,17 @@ fn traverse_children_of<'dom, Node>( if is_text_input_element || is_textarea_element { let info = NodeAndStyleInfo::new(parent_element, parent_element.style(context)); - if is_text_input_element { + if parent_element + .to_threadsafe() + .node_text_content() + .is_empty() + { // The addition of zero-width space here forces the text input to have an inline formatting // context that might otherwise be trimmed if there's no text. This is important to ensure // that the input element is at least as tall as the line gap of the caret: // <https://drafts.csswg.org/css-ui/#element-with-default-preferred-size>. // + // This is also used to ensure that the caret will still be rendered when the input is empty. // TODO: Is there a less hacky way to do this? handler.handle_text(&info, "\u{200B}".into()); } |