layout: Add very basic support for showing text in input boxes (#32365)

This only paints text in input fields. Selection and cursor are still
not painted.

In addition to adding this feature, the change also updates the
user-agent.css with the latest from the HTML specification. Extra
padding and extraneous settings (such as a bogus line-height and
min-height) are also removed from servo.css. This leads to some new
passes.

There are some new passes, this introduces failures as inserting text
reveals issues that were hidden before. Notably:

- failures in `/html/editing/editing-0/spelling-and-grammar-checking/`:
  We do not support spell-checking.
- Most of the rest of the new failures are missing features of input
  boxes that are also missing in legacy layout.
This commit is contained in:
Martin Robinson 2024-06-20 12:13:50 +02:00 committed by GitHub
parent 3d6accbbe3
commit 44064b1439
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
65 changed files with 225 additions and 204 deletions

View file

@ -7,6 +7,7 @@ use std::borrow::Cow;
use html5ever::{local_name, LocalName};
use log::warn;
use script_layout_interface::wrapper_traits::{ThreadSafeLayoutElement, ThreadSafeLayoutNode};
use script_layout_interface::{LayoutElementType, LayoutNodeType};
use servo_arc::Arc as ServoArc;
use style::properties::ComputedValues;
use style::selector_parser::PseudoElement;
@ -33,7 +34,7 @@ pub(crate) struct NodeAndStyleInfo<Node> {
pub style: ServoArc<ComputedValues>,
}
impl<Node> NodeAndStyleInfo<Node> {
impl<'dom, Node: NodeExt<'dom>> NodeAndStyleInfo<Node> {
fn new_with_pseudo(
node: Node,
pseudo_element_type: WhichPseudoElement,
@ -53,6 +54,12 @@ impl<Node> NodeAndStyleInfo<Node> {
style,
}
}
pub(crate) fn is_single_line_text_input(&self) -> bool {
self.node.map_or(false, |node| {
node.type_id() == LayoutNodeType::Element(LayoutElementType::HTMLInputElement)
})
}
}
impl<Node: Clone> NodeAndStyleInfo<Node> {
@ -172,6 +179,23 @@ fn traverse_children_of<'dom, Node>(
}
}
if matches!(
parent_element.type_id(),
LayoutNodeType::Element(LayoutElementType::HTMLInputElement)
) {
let info = NodeAndStyleInfo::new(parent_element, parent_element.style(context));
// 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>.
//
// TODO: Is there a less hacky way to do this?
handler.handle_text(&info, "\u{200B}".into());
handler.handle_text(&info, parent_element.to_threadsafe().node_text_content());
}
traverse_pseudo_element(WhichPseudoElement::After, parent_element, context, handler);
}