aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/node.rs
diff options
context:
space:
mode:
authorSimon Wülker <simon.wuelker@arcor.de>2025-05-15 19:30:38 +0200
committerGitHub <noreply@github.com>2025-05-15 17:30:38 +0000
commitb100a98e1d7f5ccf4af54a819a55f20f83308fef (patch)
tree02352489726897c790e7d4f5ef91e26408a4ce1f /components/script/dom/node.rs
parentf9382fcaa00206ce1f5f99a9dc417065d980b5ee (diff)
downloadservo-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}>`. ![image](https://github.com/user-attachments/assets/4f16c3b0-1f79-4095-b19d-1153f5853dd5) <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.rs25
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();