Skip to main content

style/values/specified/
param.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! Common handling for the specified value CSS param() values.
6
7use crate::custom_properties::VariableValue;
8use crate::parser::{Parse, ParserContext};
9use crate::values::fmt;
10use crate::values::CssWriter;
11use crate::{derives::*, values::DashedIdent};
12use cssparser::Parser;
13use std::fmt::Write;
14use style_traits::arc_slice::ArcSlice;
15use style_traits::owned_str::OwnedStr;
16use style_traits::{ParseError, ToCss};
17
18/// A struct to hold a specific '<declaration-value>'.
19#[derive(
20    Clone,
21    Debug,
22    MallocSizeOf,
23    PartialEq,
24    SpecifiedValueInfo,
25    ToComputedValue,
26    ToResolvedValue,
27    ToShmem,
28)]
29#[repr(transparent)]
30pub struct LinkParamValue(pub OwnedStr);
31
32/// A single param(--ident, value) entry: https://drafts.csswg.org/css-link-params-1/#funcdef-param
33#[derive(
34    Clone,
35    Debug,
36    MallocSizeOf,
37    PartialEq,
38    SpecifiedValueInfo,
39    ToComputedValue,
40    ToResolvedValue,
41    ToShmem,
42)]
43#[repr(C)]
44pub struct LinkParam {
45    /// link-parameters' param name, in the form of an <dashed-ident>: https://drafts.csswg.org/css-values-4/#typedef-dashed-ident
46    pub name: DashedIdent,
47    /// link-parameters' value, in the form of a <declaration-value>: https://drafts.csswg.org/css-syntax-3/#typedef-declaration-value
48    pub value: LinkParamValue,
49}
50
51/// A struct to hold all specified link-parameters: https://drafts.csswg.org/css-link-params-1/
52///
53/// We treat `none` as an empty slice and vis-versa
54#[derive(
55    Clone,
56    Debug,
57    Default,
58    MallocSizeOf,
59    PartialEq,
60    SpecifiedValueInfo,
61    ToComputedValue,
62    ToCss,
63    ToResolvedValue,
64    ToShmem,
65    ToTyped,
66)]
67#[repr(C)]
68#[css(comma)]
69#[typed(skip_derive_fields)]
70pub struct LinkParameters(
71    /// Slice of specified link-parameters properties: https://drafts.csswg.org/css-link-params-1/#link-param-prop
72    #[css(iterable, if_empty = "none")]
73    #[ignore_malloc_size_of = "Arc"]
74    pub ArcSlice<LinkParam>,
75);
76
77impl LinkParameters {
78    /// Returns the `none` value.
79    pub fn none() -> Self {
80        Self(ArcSlice::default())
81    }
82}
83
84impl Parse for LinkParameters {
85    fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ParseError> {
86        if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
87            return Ok(Self::none());
88        }
89
90        let params = input.parse_comma_separated(|input| {
91            input.expect_function_matching("param")?;
92            input.parse_nested_block(|input| {
93                let name = DashedIdent::parse(context, input)?;
94                input.expect_comma()?;
95                // if a comma exists then parse it and set value as specified, even if no value provided
96                // need to handle url references properly https://bugzilla.mozilla.org/show_bug.cgi?id=2028998
97                let parsed = VariableValue::parse(input, None, context.url_data)?;
98                let value = LinkParamValue(OwnedStr::from(parsed.css));
99                Ok(LinkParam { name, value })
100            })
101        })?;
102
103        Ok(Self(crate::ArcSlice::from_iter(params.into_iter())))
104    }
105}
106
107impl ToCss for LinkParam {
108    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
109    where
110        W: Write,
111    {
112        dest.write_str("param(")?;
113        self.name.to_css(dest)?;
114        dest.write_str(", ")?;
115        if !self.value.0.is_empty() {
116            // Don't use to_css, instead write the raw CSS value without extra quoting.
117            dest.write_str(&self.value.0)?;
118        }
119        dest.write_char(')')
120    }
121}