1use cssparser::{Parser, serialize_identifier};
6use js::context::JSContext;
7use script_bindings::codegen::GenericBindings::CSSBinding::PropertyDefinition;
8use style::stylesheets::supports_rule::{Declaration, parse_condition_or_declaration};
9use style::stylesheets::{CssRuleType, UrlExtraData};
10use style::stylist::RegisterCustomPropertyResult;
11use style_traits::ParsingMode;
12
13use crate::css::css::parser_context_for_anonymous_content;
14use crate::dom::bindings::codegen::Bindings::CSSBinding::CSSMethods;
15use crate::dom::bindings::codegen::Bindings::WindowBinding::Window_Binding::WindowMethods;
16use crate::dom::bindings::error::{Error, Fallible};
17use crate::dom::bindings::root::DomRoot;
18use crate::dom::bindings::str::DOMString;
19use crate::dom::window::Window;
20use crate::dom::worklet::Worklet;
21
22#[expect(clippy::upper_case_acronyms)]
23pub(crate) struct CSS {}
24
25impl CSSMethods<crate::DomTypeHolder> for CSS {
26 fn Escape(_: &Window, ident: DOMString) -> Fallible<DOMString> {
28 let mut escaped = String::new();
29 serialize_identifier(&ident.str(), &mut escaped).unwrap();
30 Ok(DOMString::from(escaped))
31 }
32
33 fn Supports(win: &Window, property: DOMString, value: DOMString) -> bool {
35 let mut decl = String::new();
36 serialize_identifier(&property.str(), &mut decl).unwrap();
37 decl.push_str(": ");
38 decl.push_str(&value.str());
39 let decl = Declaration(decl);
40 let url_data = UrlExtraData(win.Document().url().get_arc());
41 let mut context = parser_context_for_anonymous_content(
42 CssRuleType::Style,
43 ParsingMode::DEFAULT,
44 &url_data,
45 );
46 decl.eval(&mut context)
47 }
48
49 fn Supports_(win: &Window, condition: DOMString) -> bool {
51 let condition = condition.str();
52 let mut input = Parser::new(&condition);
53 let cond = match parse_condition_or_declaration(&mut input) {
54 Ok(c) => c,
55 Err(..) => return false,
56 };
57
58 let url_data = UrlExtraData(win.Document().url().get_arc());
59 let mut context = parser_context_for_anonymous_content(
60 CssRuleType::Style,
61 ParsingMode::DEFAULT,
62 &url_data,
63 );
64 cond.eval(&mut context)
65 }
66
67 fn PaintWorklet(cx: &mut JSContext, win: &Window) -> DomRoot<Worklet> {
69 win.paint_worklet(cx)
70 }
71
72 fn RegisterProperty(window: &Window, property_definition: &PropertyDefinition) -> Fallible<()> {
74 use RegisterCustomPropertyResult::*;
75 let result = window.layout_mut().stylist_mut().register_custom_property(
76 &UrlExtraData(window.get_url().get_arc()),
77 &property_definition.name.str(),
78 &property_definition.syntax.str(),
79 property_definition.inherits,
80 property_definition
81 .initialValue
82 .as_ref()
83 .map(|value| value.str())
84 .as_deref(),
85 );
86 Err(match result {
87 SuccessfullyRegistered => return Ok(()),
88 InvalidName |
89 InvalidSyntax |
90 InvalidInitialValue |
91 NoInitialValue |
92 InitialValueNotComputationallyIndependent => Error::Syntax(Some(
93 "CSS property value is not computationally independent".into(),
94 )),
95 AlreadyRegistered => {
96 Error::InvalidModification(Some("CSS property is already registered".into()))
97 },
98 })
99 }
100}