mirror of
https://github.com/servo/servo.git
synced 2025-08-09 15:35:34 +01:00
style: Simplify parsing and storage of SVG paint server fallback. r=boris
Differential Revision: https://phabricator.services.mozilla.com/D36806
This commit is contained in:
parent
f0b5d02901
commit
83da7c1535
5 changed files with 71 additions and 99 deletions
|
@ -5,9 +5,36 @@
|
|||
//! Generic types for CSS values in SVG
|
||||
|
||||
use crate::parser::{Parse, ParserContext};
|
||||
use crate::values::{Either, None_};
|
||||
use cssparser::Parser;
|
||||
use style_traits::{ParseError, StyleParseErrorKind};
|
||||
use style_traits::ParseError;
|
||||
|
||||
/// The fallback of an SVG paint server value.
|
||||
#[derive(
|
||||
Animate,
|
||||
Clone,
|
||||
ComputeSquaredDistance,
|
||||
Debug,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
Parse,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
ToAnimatedZero,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
pub enum SVGPaintFallback<C> {
|
||||
/// The `none` keyword.
|
||||
None,
|
||||
/// A magic value that represents no fallback specified and serializes to
|
||||
/// the empty string.
|
||||
#[css(skip)]
|
||||
Unset,
|
||||
/// A color.
|
||||
Color(C),
|
||||
}
|
||||
|
||||
/// An SVG paint value
|
||||
///
|
||||
|
@ -22,16 +49,26 @@ use style_traits::{ParseError, StyleParseErrorKind};
|
|||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
ToAnimatedZero,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
pub struct SVGPaint<ColorType, UrlPaintServer> {
|
||||
/// The paint source
|
||||
/// The paint source.
|
||||
pub kind: SVGPaintKind<ColorType, UrlPaintServer>,
|
||||
/// The fallback color. It would be empty, the `none` keyword or <color>.
|
||||
pub fallback: Option<Either<ColorType, None_>>,
|
||||
/// The fallback color.
|
||||
pub fallback: SVGPaintFallback<ColorType>,
|
||||
}
|
||||
|
||||
impl<C, U> Default for SVGPaint<C, U> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
kind: SVGPaintKind::None,
|
||||
fallback: SVGPaintFallback::Unset,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An SVG paint value without the fallback
|
||||
|
@ -47,6 +84,7 @@ pub struct SVGPaint<ColorType, UrlPaintServer> {
|
|||
Debug,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
Parse,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
ToAnimatedZero,
|
||||
|
@ -70,65 +108,22 @@ pub enum SVGPaintKind<ColorType, UrlPaintServer> {
|
|||
ContextStroke,
|
||||
}
|
||||
|
||||
impl<ColorType, UrlPaintServer> SVGPaintKind<ColorType, UrlPaintServer> {
|
||||
/// Parse a keyword value only
|
||||
fn parse_ident<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
try_match_ident_ignore_ascii_case! { input,
|
||||
"none" => Ok(SVGPaintKind::None),
|
||||
"context-fill" => Ok(SVGPaintKind::ContextFill),
|
||||
"context-stroke" => Ok(SVGPaintKind::ContextStroke),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse SVGPaint's fallback.
|
||||
/// fallback is keyword(none), Color or empty.
|
||||
/// <https://svgwg.org/svg2-draft/painting.html#SpecifyingPaint>
|
||||
fn parse_fallback<'i, 't, ColorType: Parse>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Option<Either<ColorType, None_>> {
|
||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
||||
Some(Either::Second(None_))
|
||||
} else {
|
||||
if let Ok(color) = input.try(|i| ColorType::parse(context, i)) {
|
||||
Some(Either::First(color))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<ColorType: Parse, UrlPaintServer: Parse> Parse for SVGPaint<ColorType, UrlPaintServer> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(url) = input.try(|i| UrlPaintServer::parse(context, i)) {
|
||||
Ok(SVGPaint {
|
||||
kind: SVGPaintKind::PaintServer(url),
|
||||
fallback: parse_fallback(context, input),
|
||||
})
|
||||
} else if let Ok(kind) = input.try(SVGPaintKind::parse_ident) {
|
||||
if let SVGPaintKind::None = kind {
|
||||
Ok(SVGPaint {
|
||||
kind: kind,
|
||||
fallback: None,
|
||||
})
|
||||
} else {
|
||||
Ok(SVGPaint {
|
||||
kind: kind,
|
||||
fallback: parse_fallback(context, input),
|
||||
})
|
||||
}
|
||||
} else if let Ok(color) = input.try(|i| ColorType::parse(context, i)) {
|
||||
Ok(SVGPaint {
|
||||
kind: SVGPaintKind::Color(color),
|
||||
fallback: None,
|
||||
})
|
||||
} else {
|
||||
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
let kind = SVGPaintKind::parse(context, input)?;
|
||||
if matches!(kind, SVGPaintKind::None | SVGPaintKind::Color(..)) {
|
||||
return Ok(SVGPaint {
|
||||
kind,
|
||||
fallback: SVGPaintFallback::Unset
|
||||
});
|
||||
}
|
||||
let fallback = input
|
||||
.try(|i| SVGPaintFallback::parse(context, i))
|
||||
.unwrap_or(SVGPaintFallback::Unset);
|
||||
Ok(SVGPaint { kind, fallback })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue