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