mirror of
https://github.com/servo/servo.git
synced 2025-08-12 17:05:33 +01:00
script: Use an implemented pseudo-element to fortype=color
::color-swatch
(#37427)
Implement internal pseudo element, which would be resolved as a "Implemented Pseudo Element" within style computation. This is an concrete element that would has a primary style after the style computation, but could match and style resolved like an pseudo element. Therefore, it would have a different behavior compared to how does `pseudo`s that `ServoLayoutNode` had. Where they would not have a concrete element behind it. Note that, due to the nature of these pseudo elements residing inside a UA widget, these pseudo elements would therefore not be accessible in JavaScript by default. This kind of element is required in order to implement the [form control pseudo element](https://drafts.csswg.org/css-forms-1/#pseudo-elements) like `::placeholder`, `::color-swatch`, `::field-text`, etc. See [this docs](https://hackmd.io/@ChaKweTiau/BJ3zRdLQlg) for more details of the implementation. Then, the implemented pseudo element is utilized to implement style matching for input `type=text`. Servo's side of: https://github.com/servo/stylo/pull/212 Testing: No WPT regression. --------- Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>
This commit is contained in:
parent
d2ccf419c3
commit
378c4648e4
12 changed files with 201 additions and 163 deletions
|
@ -29,10 +29,8 @@ use js::rust::{HandleObject, MutableHandleObject};
|
|||
use net_traits::blob_url_store::get_blob_origin;
|
||||
use net_traits::filemanager_thread::FileManagerThreadMsg;
|
||||
use net_traits::{CoreResourceMsg, IpcSend};
|
||||
use script_bindings::codegen::GenericBindings::ShadowRootBinding::{
|
||||
ShadowRootMode, SlotAssignmentMode,
|
||||
};
|
||||
use style::attr::AttrValue;
|
||||
use style::selector_parser::PseudoElement;
|
||||
use style::str::{split_commas, str_join};
|
||||
use stylo_atoms::Atom;
|
||||
use stylo_dom::ElementState;
|
||||
|
@ -59,7 +57,7 @@ use crate::dom::bindings::str::{DOMString, FromInputValueString, ToInputValueStr
|
|||
use crate::dom::clipboardevent::ClipboardEvent;
|
||||
use crate::dom::compositionevent::CompositionEvent;
|
||||
use crate::dom::document::Document;
|
||||
use crate::dom::element::{AttributeMutation, Element, ElementCreator, LayoutElementHelpers};
|
||||
use crate::dom::element::{AttributeMutation, Element, LayoutElementHelpers};
|
||||
use crate::dom::event::{Event, EventBubbles, EventCancelable};
|
||||
use crate::dom::eventtarget::EventTarget;
|
||||
use crate::dom::file::File;
|
||||
|
@ -73,14 +71,13 @@ use crate::dom::htmlformelement::{
|
|||
FormControl, FormDatum, FormDatumValue, FormSubmitterElement, HTMLFormElement, ResetFrom,
|
||||
SubmittedFrom,
|
||||
};
|
||||
use crate::dom::htmlstyleelement::HTMLStyleElement;
|
||||
use crate::dom::keyboardevent::KeyboardEvent;
|
||||
use crate::dom::mouseevent::MouseEvent;
|
||||
use crate::dom::node::{
|
||||
BindContext, CloneChildrenFlag, Node, NodeDamage, NodeTraits, ShadowIncluding, UnbindContext,
|
||||
};
|
||||
use crate::dom::nodelist::NodeList;
|
||||
use crate::dom::shadowroot::{IsUserAgentWidget, ShadowRoot};
|
||||
use crate::dom::shadowroot::ShadowRoot;
|
||||
use crate::dom::textcontrol::{TextControlElement, TextControlSelection};
|
||||
use crate::dom::validation::{Validatable, is_barred_by_datalist_ancestor};
|
||||
use crate::dom::validitystate::{ValidationFlags, ValidityState};
|
||||
|
@ -119,16 +116,6 @@ enum ShadowTree {
|
|||
// TODO: Add shadow trees for other input types (range etc) here
|
||||
}
|
||||
|
||||
const COLOR_TREE_STYLE: &str = "
|
||||
#color-value {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid gray;
|
||||
border-radius: 2px;
|
||||
}
|
||||
";
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#attr-input-type>
|
||||
#[derive(Clone, Copy, Default, JSTraceable, PartialEq)]
|
||||
#[allow(dead_code)]
|
||||
|
@ -1064,19 +1051,9 @@ impl HTMLInputElement {
|
|||
/// Return a reference to the ShadowRoot that this element is a host of,
|
||||
/// or create one if none exists.
|
||||
fn shadow_root(&self, can_gc: CanGc) -> DomRoot<ShadowRoot> {
|
||||
self.upcast::<Element>().shadow_root().unwrap_or_else(|| {
|
||||
self.upcast::<Element>()
|
||||
.attach_shadow(
|
||||
IsUserAgentWidget::Yes,
|
||||
ShadowRootMode::Closed,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
SlotAssignmentMode::Manual,
|
||||
can_gc,
|
||||
)
|
||||
.expect("Attaching UA shadow root failed")
|
||||
})
|
||||
self.upcast::<Element>()
|
||||
.shadow_root()
|
||||
.unwrap_or_else(|| self.upcast::<Element>().attach_ua_shadow_root(true, can_gc))
|
||||
}
|
||||
|
||||
fn create_color_shadow_tree(&self, can_gc: CanGc) {
|
||||
|
@ -1085,29 +1062,13 @@ impl HTMLInputElement {
|
|||
Node::replace_all(None, shadow_root.upcast::<Node>(), can_gc);
|
||||
|
||||
let color_value = HTMLDivElement::new(local_name!("div"), None, &document, None, can_gc);
|
||||
color_value
|
||||
.upcast::<Element>()
|
||||
.SetId(DOMString::from("color-value"), can_gc);
|
||||
shadow_root
|
||||
.upcast::<Node>()
|
||||
.AppendChild(color_value.upcast::<Node>(), can_gc)
|
||||
.unwrap();
|
||||
|
||||
let style = HTMLStyleElement::new(
|
||||
local_name!("style"),
|
||||
None,
|
||||
&document,
|
||||
None,
|
||||
ElementCreator::ScriptCreated,
|
||||
can_gc,
|
||||
);
|
||||
style
|
||||
color_value
|
||||
.upcast::<Node>()
|
||||
.SetTextContent(Some(DOMString::from(COLOR_TREE_STYLE)), can_gc);
|
||||
shadow_root
|
||||
.upcast::<Node>()
|
||||
.AppendChild(style.upcast::<Node>(), can_gc)
|
||||
.unwrap();
|
||||
.set_implemented_pseudo_element(PseudoElement::ColorSwatch);
|
||||
|
||||
let _ = self
|
||||
.shadow_tree
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue