diff options
author | Simon Wülker <simon.wuelker@arcor.de> | 2025-05-15 19:30:38 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-15 17:30:38 +0000 |
commit | b100a98e1d7f5ccf4af54a819a55f20f83308fef (patch) | |
tree | 02352489726897c790e7d4f5ef91e26408a4ce1f /components/script/dom/node.rs | |
parent | f9382fcaa00206ce1f5f99a9dc417065d980b5ee (diff) | |
download | servo-b100a98e1d7f5ccf4af54a819a55f20f83308fef.tar.gz servo-b100a98e1d7f5ccf4af54a819a55f20f83308fef.zip |
Fully support `<input type=color>` (#36992)
This change adds a shadow-tree widget for `<input type=color>` elements.
It also involves some changes to the way layout interacts with the DOM,
because currently all `input` and `textarea` elements are rendered as
plain text and their descendants are ignored. This obviously doesn't
work for `<input type={color, date, range, etc}>`.

<details><summary>HTML used for the screenshot above</summary>
```html
<input type=color>
```
</details>
Testing: I doubt that this affects WPT tests, because the appearance and
behaviour of the widget is almost entirely unspecified.
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
Diffstat (limited to 'components/script/dom/node.rs')
-rw-r--r-- | components/script/dom/node.rs | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 5f08abce354..17235543906 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -50,7 +50,6 @@ use style::stylesheets::{Stylesheet, UrlExtraData}; use uuid::Uuid; use xml5ever::serialize as xml_serialize; -use super::globalscope::GlobalScope; use crate::conversions::Convert; use crate::document_loader::DocumentLoader; use crate::dom::attr::Attr; @@ -92,13 +91,14 @@ use crate::dom::documenttype::DocumentType; use crate::dom::element::{CustomElementCreationMode, Element, ElementCreator, SelectorWrapper}; use crate::dom::event::{Event, EventBubbles, EventCancelable}; use crate::dom::eventtarget::EventTarget; +use crate::dom::globalscope::GlobalScope; use crate::dom::htmlbodyelement::HTMLBodyElement; use crate::dom::htmlcanvaselement::{HTMLCanvasElement, LayoutHTMLCanvasElementHelpers}; use crate::dom::htmlcollection::HTMLCollection; use crate::dom::htmlelement::HTMLElement; use crate::dom::htmliframeelement::{HTMLIFrameElement, HTMLIFrameElementLayoutMethods}; use crate::dom::htmlimageelement::{HTMLImageElement, LayoutHTMLImageElementHelpers}; -use crate::dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers}; +use crate::dom::htmlinputelement::{HTMLInputElement, InputType, LayoutHTMLInputElementHelpers}; use crate::dom::htmllinkelement::HTMLLinkElement; use crate::dom::htmlslotelement::{HTMLSlotElement, Slottable}; use crate::dom::htmlstyleelement::HTMLStyleElement; @@ -1612,6 +1612,8 @@ pub(crate) trait LayoutNodeHelpers<'dom> { /// attempting to read or modify the opaque layout data of this node. unsafe fn clear_style_and_layout_data(self); + /// Whether this element is a `<input>` rendered as text or a `<textarea>`. + fn is_text_input(&self) -> bool; fn text_content(self) -> Cow<'dom, str>; fn selection(self) -> Option<Range<usize>>; fn image_url(self) -> Option<ServoUrl>; @@ -1776,6 +1778,25 @@ impl<'dom> LayoutNodeHelpers<'dom> for LayoutDom<'dom, Node> { self.unsafe_get().layout_data.borrow_mut_for_layout().take(); } + fn is_text_input(&self) -> bool { + let type_id = self.type_id_for_layout(); + if type_id == + NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLInputElement, + )) + { + let input = self.unsafe_get().downcast::<HTMLInputElement>().unwrap(); + + // FIXME: All the non-color input types currently render as text + input.input_type() != InputType::Color + } else { + type_id == + NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLTextAreaElement, + )) + } + } + fn text_content(self) -> Cow<'dom, str> { if let Some(text) = self.downcast::<Text>() { return text.upcast().data_for_layout().into(); |