aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_2020/dom_traversal.rs
diff options
context:
space:
mode:
authorDK Liao <dklassic@gmail.com>2025-04-11 15:51:52 +0900
committerGitHub <noreply@github.com>2025-04-11 06:51:52 +0000
commit5df4c760d36d056292161eef221165c9f41c6125 (patch)
tree613d03d19e9094b24cfc1210cbf4c74915e1674a /components/layout_2020/dom_traversal.rs
parent972ca77ce1bd2c08b809b7d54ec716213519fe1e (diff)
downloadservo-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.rs7
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());
}