///|
pub struct ImageCandidate {
expression : Expression
}
///|
pub fn[I : ImageInput] image_candidate(
value : I,
resolution? : Resolution,
mime? : String,
) -> ImageCandidate {
let expression = value.image_expression()
let values = [expression]
if expression.to_css().contains("image-set(") {
values.push(
invalid_expression(
"STYLE_IMAGE_SET_NESTED", "Image set candidates cannot contain image-set()",
),
)
}
// Image lists and none are not candidates.
if expression.category == "image-list" || expression.to_css() == "none" {
values.push(
invalid_expression(
"STYLE_IMAGE_SET_CANDIDATE", "An image set candidate must be a single image",
),
)
}
if resolution is Some(value) {
let css = value.to_css()
let valid = match numeric_part(css, "resolution") {
Some(number) => number > 0.0
None => false
}
values.push(
if valid {
literal_expression(css, "resolution")
} else {
invalid_expression(
"STYLE_IMAGE_SET_RESOLUTION", "Image resolution must be positive and finite",
)
},
)
}
if mime is Some(value) {
if !value.has_prefix("image/") || value.length() <= 6 || value.contains(" ") {
values.push(
invalid_expression(
"STYLE_IMAGE_SET_MIME", "Image MIME type must start with image/",
),
)
} else {
values.push(
literal_expression(
"type(" + quoted_css_string(value, "image MIME type") + ")",
"mime",
),
)
}
}
{ expression: group_expression("image-candidate", "", values, " ", ""), }
}
///|
pub fn image_set(candidates : Array[ImageCandidate]) -> Image {
let values = candidates.map(value => value.expression)
if values.is_empty() {
values.push(
invalid_expression(
"STYLE_IMAGE_SET_EMPTY", "An image set requires at least one candidate",
),
)
}
{ expression: group_expression("image", "image-set(", values, ", ", ")"), }
}