Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce ComputedUrl #17812

Merged
merged 1 commit into from Aug 10, 2017
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -44,7 +44,7 @@ use values::animated::effects::FilterList as AnimatedFilterList;
use values::animated::effects::TextShadowList as AnimatedTextShadowList;
use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
use values::computed::{BorderCornerRadius, ClipRect};
use values::computed::{CalcLengthOrPercentage, Color, Context, ComputedValueAsSpecified};
use values::computed::{CalcLengthOrPercentage, Color, Context, ComputedValueAsSpecified, ComputedUrl};
use values::computed::{LengthOrPercentage, MaxLength, MozLength, Percentage, ToComputedValue};
use values::computed::{NonNegativeAu, NonNegativeNumber, PositiveIntegerOrAuto};
use values::computed::length::{NonNegativeLengthOrAuto, NonNegativeLengthOrNormal};
@@ -2974,10 +2974,10 @@ impl ToAnimatedZero for IntermediateColor {
}

/// Animatable SVGPaint
pub type IntermediateSVGPaint = SVGPaint<IntermediateRGBA>;
pub type IntermediateSVGPaint = SVGPaint<IntermediateRGBA, ComputedUrl>;

/// Animatable SVGPaintKind
pub type IntermediateSVGPaintKind = SVGPaintKind<IntermediateRGBA>;
pub type IntermediateSVGPaintKind = SVGPaintKind<IntermediateRGBA, ComputedUrl>;

impl Animatable for IntermediateSVGPaint {
#[inline]
@@ -12,6 +12,7 @@ use std::fmt;
// the threshold.
use std::sync::Arc;
use style_traits::{ToCss, ParseError};
use values::computed::{Context, ToComputedValue, ComputedUrl};

/// A specified url() value for servo.
///
@@ -126,3 +127,35 @@ impl ToCss for SpecifiedUrl {
dest.write_str(")")
}
}

impl ToComputedValue for SpecifiedUrl {
type ComputedValue = ComputedUrl;

// If we can't resolve the URL from the specified one, we fall back to the original
// but still return it as a ComputedUrl::Invalid
fn to_computed_value(&self, _: &Context) -> Self::ComputedValue {
match self.resolved {
Some(ref url) => ComputedUrl::Valid(url.clone()),
None => match self.original {
Some(ref url) => ComputedUrl::Invalid(url.clone()),
None => {
unreachable!("Found specified url with neither resolved or original URI!");
},
}
}
}

fn from_computed_value(computed: &ComputedUrl) -> Self {
match *computed {
ComputedUrl::Valid(ref url) => SpecifiedUrl {
original: None,
resolved: Some(url.clone()),
},
ComputedUrl::Invalid(ref url) => SpecifiedUrl {
original: Some(url.clone()),
resolved: None,
}
}
}
}

@@ -13,6 +13,8 @@ use smallvec::SmallVec;
use std::cmp::max;
use values::computed::Angle as ComputedAngle;
use values::computed::BorderCornerRadius as ComputedBorderCornerRadius;
#[cfg(feature = "servo")]
use values::computed::ComputedUrl;
use values::computed::GreaterThanOrEqualToOneNumber as ComputedGreaterThanOrEqualToOneNumber;
use values::computed::MaxLength as ComputedMaxLength;
use values::computed::MozLength as ComputedMozLength;
@@ -95,6 +97,8 @@ pub trait AnimatedValueAsComputed {}
impl AnimatedValueAsComputed for Au {}
impl AnimatedValueAsComputed for ComputedAngle {}
impl AnimatedValueAsComputed for SpecifiedUrl {}
#[cfg(feature = "servo")]
impl AnimatedValueAsComputed for ComputedUrl {}
impl AnimatedValueAsComputed for bool {}
impl AnimatedValueAsComputed for f32 {}

@@ -9,17 +9,17 @@

use std::fmt;
use style_traits::ToCss;
use values::computed::LengthOrPercentage;
use values::computed::{LengthOrPercentage, ComputedUrl};
use values::generics::basic_shape::{BasicShape as GenericBasicShape};
use values::generics::basic_shape::{Circle as GenericCircle, ClippingShape as GenericClippingShape};
use values::generics::basic_shape::{Ellipse as GenericEllipse, FloatAreaShape as GenericFloatAreaShape};
use values::generics::basic_shape::{InsetRect as GenericInsetRect, ShapeRadius as GenericShapeRadius};

/// A specified clipping shape.
pub type ClippingShape = GenericClippingShape<BasicShape>;
pub type ClippingShape = GenericClippingShape<BasicShape, ComputedUrl>;

/// A specified float area shape.
pub type FloatAreaShape = GenericFloatAreaShape<BasicShape>;
pub type FloatAreaShape = GenericFloatAreaShape<BasicShape, ComputedUrl>;

/// A computed basic shape.
pub type BasicShape = GenericBasicShape<LengthOrPercentage, LengthOrPercentage, LengthOrPercentage>;
@@ -12,7 +12,7 @@ use std::f32::consts::PI;
use std::fmt;
use style_traits::ToCss;
use values::{Either, None_};
use values::computed::{Angle, Context, Length, LengthOrPercentage, NumberOrPercentage, ToComputedValue};
use values::computed::{Angle, ComputedUrl, Context, Length, LengthOrPercentage, NumberOrPercentage, ToComputedValue};
use values::computed::position::Position;
use values::generics::image::{CompatMode, ColorStop as GenericColorStop, EndingShape as GenericEndingShape};
use values::generics::image::{Gradient as GenericGradient, GradientItem as GenericGradientItem};
@@ -27,7 +27,7 @@ pub type ImageLayer = Either<None_, Image>;

/// Computed values for an image according to CSS-IMAGES.
/// https://drafts.csswg.org/css-images/#image-values
pub type Image = GenericImage<Gradient, MozImageRect>;
pub type Image = GenericImage<Gradient, MozImageRect, ComputedUrl>;

/// Computed values for a CSS gradient.
/// https://drafts.csswg.org/css-images/#gradients
@@ -76,7 +76,7 @@ pub type GradientItem = GenericGradientItem<RGBA, LengthOrPercentage>;
pub type ColorStop = GenericColorStop<RGBA, LengthOrPercentage>;

/// Computed values for `-moz-image-rect(...)`.
pub type MozImageRect = GenericMozImageRect<NumberOrPercentage>;
pub type MozImageRect = GenericMozImageRect<NumberOrPercentage, ComputedUrl>;

impl GenericLineDirection for LineDirection {
fn points_downwards(&self) -> bool {
@@ -12,10 +12,14 @@ use media_queries::Device;
#[cfg(feature = "gecko")]
use properties;
use properties::{ComputedValues, StyleBuilder};
#[cfg(feature = "servo")]
use servo_url::ServoUrl;
use std::f32;
use std::f64;
use std::f64::consts::PI;
use std::fmt;
#[cfg(feature = "servo")]
use std::sync::Arc;
use style_traits::ToCss;
use super::{CSSFloat, CSSInteger};
use super::generics::{GreaterThanOrEqualToOne, NonNegative};
@@ -39,9 +43,8 @@ pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection,
pub use self::gecko::ScrollSnapPoint;
pub use self::rect::LengthOrNumberRect;
pub use super::{Auto, Either, None_};
pub use super::specified::{BorderStyle, UrlOrNone};
pub use super::specified::BorderStyle;
pub use super::generics::grid::GridLine;
pub use super::specified::url::SpecifiedUrl;
pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNone, LengthOrNumber, LengthOrPercentage};
pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLength, MozLength};
pub use self::length::NonNegativeLengthOrPercentage;
@@ -684,3 +687,45 @@ impl ToComputedValue for specified::Percentage {
specified::Percentage::new(computed.0)
}
}

/// The computed value of a CSS `url()`, resolved relative to the stylesheet URL.
#[cfg(feature = "servo")]
#[derive(Clone, Debug, HeapSizeOf, Serialize, Deserialize, PartialEq)]
pub enum ComputedUrl {

This comment has been minimized.

@emilio

emilio Jul 26, 2017

Member

We could move this to another module to avoid the cfg's, but that's probably doable as a followup.

This comment has been minimized.

@fnune

fnune Jul 26, 2017

Author Contributor

You mean I should create a new files like this:

computed/ur/servo.rs
computed/url/gecko.rs
computed/url/mod.rs // Export here? Would still need the cfgs am I right?

This comment has been minimized.

@emilio

emilio Jul 29, 2017

Member

Yeah, I meant this, but I wouldn't worry about that for this PR, it's fine to do it in followup work.

/// The `url()` was invalid or it wasn't specified by the user.
Invalid(Arc<String>),
/// The resolved `url()` relative to the stylesheet URL.
Valid(ServoUrl),
}

/// TODO: Properly build ComputedUrl for gecko
#[cfg(feature = "gecko")]
pub type ComputedUrl = specified::url::SpecifiedUrl;

#[cfg(feature = "servo")]
impl ComputedUrl {
/// Returns the resolved url if it was valid.
pub fn url(&self) -> Option<&ServoUrl> {
match *self {
ComputedUrl::Valid(ref url) => Some(url),
_ => None,
}
}
}

#[cfg(feature = "servo")]
impl ToCss for ComputedUrl {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
let string = match *self {
ComputedUrl::Valid(ref url) => url.as_str(),
ComputedUrl::Invalid(ref invalid_string) => invalid_string,

This comment has been minimized.

@fnune

fnune Jul 29, 2017

Author Contributor

With the new changes this invalid_string should either be the original URL if it was specified, or "about:invalid" if not specified.

};

dest.write_str("url(")?;
string.to_css(dest)?;
dest.write_str(")")
}
}

/// <url> | <none>
pub type UrlOrNone = Either<ComputedUrl, None_>;
@@ -8,12 +8,13 @@ use app_units::Au;
use values::{Either, RGBA};
use values::computed::{LengthOrPercentageOrNumber, Opacity};
use values::computed::{NonNegativeAu, NonNegativeLengthOrPercentageOrNumber};
use values::computed::ComputedUrl;
use values::generics::svg as generic;

/// Computed SVG Paint value
pub type SVGPaint = generic::SVGPaint<RGBA>;
pub type SVGPaint = generic::SVGPaint<RGBA, ComputedUrl>;
/// Computed SVG Paint Kind value
pub type SVGPaintKind = generic::SVGPaintKind<RGBA>;
pub type SVGPaintKind = generic::SVGPaintKind<RGBA, ComputedUrl>;

impl Default for SVGPaint {
fn default() -> Self {
@@ -11,10 +11,9 @@ use values::computed::ComputedValueAsSpecified;
use values::generics::border::BorderRadius;
use values::generics::position::Position;
use values::generics::rect::Rect;
use values::specified::url::SpecifiedUrl;

/// A clipping shape, for `clip-path`.
pub type ClippingShape<BasicShape> = ShapeSource<BasicShape, GeometryBox>;
pub type ClippingShape<BasicShape, UrlShapeSource> = ShapeSource<BasicShape, GeometryBox, UrlShapeSource>;

/// https://drafts.fxtf.org/css-masking-1/#typedef-geometry-box
#[allow(missing_docs)]
@@ -29,7 +28,7 @@ pub enum GeometryBox {
impl ComputedValueAsSpecified for GeometryBox {}

/// A float area shape, for `shape-outside`.
pub type FloatAreaShape<BasicShape> = ShapeSource<BasicShape, ShapeBox>;
pub type FloatAreaShape<BasicShape, UrlShapeSource> = ShapeSource<BasicShape, ShapeBox, UrlShapeSource>;

// https://drafts.csswg.org/css-shapes-1/#typedef-shape-box
define_css_keyword_enum!(ShapeBox:
@@ -44,8 +43,8 @@ add_impls_for_keyword_enum!(ShapeBox);
#[allow(missing_docs)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Debug, PartialEq, ToComputedValue, ToCss)]
pub enum ShapeSource<BasicShape, ReferenceBox> {
Url(SpecifiedUrl),
pub enum ShapeSource<BasicShape, ReferenceBox, UrlShapeSource> {
Url(UrlShapeSource),
Shape(BasicShape, Option<ReferenceBox>),
Box(ReferenceBox),
None,
@@ -121,7 +120,7 @@ define_css_keyword_enum!(FillRule:
);
add_impls_for_keyword_enum!(FillRule);

impl<B, T> HasViewportPercentage for ShapeSource<B, T> {
impl<B, T, U> HasViewportPercentage for ShapeSource<B, T, U> {
#[inline]
fn has_viewport_percentage(&self) -> bool { false }
}
@@ -12,16 +12,15 @@ use custom_properties::SpecifiedValue;
use std::fmt;
use style_traits::{HasViewportPercentage, ToCss};
use values::computed::ComputedValueAsSpecified;
use values::specified::url::SpecifiedUrl;

/// An [image].
///
/// [image]: https://drafts.csswg.org/css-images/#image-values
#[derive(Clone, PartialEq, ToComputedValue)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum Image<Gradient, MozImageRect> {
pub enum Image<Gradient, MozImageRect, ImageUrl> {
/// A `<url()>` image.
Url(SpecifiedUrl),
Url(ImageUrl),
/// A `<gradient>` image.
Gradient(Gradient),
/// A `-moz-image-rect` image
@@ -168,16 +167,16 @@ impl ToCss for PaintWorklet {
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[css(comma, function)]
#[derive(Clone, Debug, PartialEq, ToComputedValue, ToCss)]
pub struct MozImageRect<NumberOrPercentage> {
pub url: SpecifiedUrl,
pub struct MozImageRect<NumberOrPercentage, MozImageRectUrl> {
pub url: MozImageRectUrl,
pub top: NumberOrPercentage,
pub right: NumberOrPercentage,
pub bottom: NumberOrPercentage,
pub left: NumberOrPercentage,
}

impl<G, R> fmt::Debug for Image<G, R>
where G: fmt::Debug, R: fmt::Debug,
impl<G, R, U> fmt::Debug for Image<G, R, U>
where G: fmt::Debug, R: fmt::Debug, U: fmt::Debug + ToCss
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
@@ -195,8 +194,8 @@ impl<G, R> fmt::Debug for Image<G, R>
}
}

impl<G, R> ToCss for Image<G, R>
where G: ToCss, R: ToCss,
impl<G, R, U> ToCss for Image<G, R, U>
where G: ToCss, R: ToCss, U: ToCss
{
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self {
@@ -214,7 +213,7 @@ impl<G, R> ToCss for Image<G, R>
}
}

impl<G, R> HasViewportPercentage for Image<G, R>
impl<G, R, U> HasViewportPercentage for Image<G, R, U>
where G: HasViewportPercentage
{
fn has_viewport_percentage(&self) -> bool {
@@ -8,16 +8,15 @@ use cssparser::Parser;
use parser::{Parse, ParserContext};
use std::fmt;
use style_traits::{ParseError, StyleParseError, ToCss};
use values::specified::url::SpecifiedUrl;

/// An SVG paint value
///
/// https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Debug, PartialEq, ToAnimatedValue, ToComputedValue, ToCss)]
pub struct SVGPaint<ColorType> {
pub struct SVGPaint<ColorType, UrlPaintServer> {
/// The paint source
pub kind: SVGPaintKind<ColorType>,
pub kind: SVGPaintKind<ColorType, UrlPaintServer>,
/// The fallback color
pub fallback: Option<ColorType>,
}
@@ -29,20 +28,20 @@ pub struct SVGPaint<ColorType> {
/// properties have a fallback as well.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Debug, PartialEq, ToAnimatedValue, ToComputedValue, ToCss)]
pub enum SVGPaintKind<ColorType> {
pub enum SVGPaintKind<ColorType, UrlPaintServer> {
/// `none`
None,
/// `<color>`
Color(ColorType),
/// `url(...)`
PaintServer(SpecifiedUrl),
PaintServer(UrlPaintServer),
/// `context-fill`
ContextFill,
/// `context-stroke`
ContextStroke,
}

impl<ColorType> SVGPaintKind<ColorType> {
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.expect_ident()?,
@@ -66,9 +65,9 @@ fn parse_fallback<'i, 't, ColorType: Parse>(context: &ParserContext,
}
}

impl<ColorType: Parse> Parse for SVGPaint<ColorType> {
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| SpecifiedUrl::parse(context, i)) {
if let Ok(url) = input.try(|i| UrlPaintServer::parse(context, i)) {
Ok(SVGPaint {
kind: SVGPaintKind::PaintServer(url),
fallback: parse_fallback(context, input),
@@ -26,10 +26,10 @@ use values::specified::position::{HorizontalPosition, Position, PositionComponen
use values::specified::url::SpecifiedUrl;

/// A specified clipping shape.
pub type ClippingShape = GenericClippingShape<BasicShape>;
pub type ClippingShape = GenericClippingShape<BasicShape, SpecifiedUrl>;

/// A specified float area shape.
pub type FloatAreaShape = GenericFloatAreaShape<BasicShape>;
pub type FloatAreaShape = GenericFloatAreaShape<BasicShape, SpecifiedUrl>;

/// A specified basic shape.
pub type BasicShape = GenericBasicShape<HorizontalPosition, VerticalPosition, LengthOrPercentage>;
@@ -49,7 +49,7 @@ pub type ShapeRadius = GenericShapeRadius<LengthOrPercentage>;
/// The specified value of `Polygon`
pub type Polygon = GenericPolygon<LengthOrPercentage>;

impl<ReferenceBox: Parse> Parse for ShapeSource<BasicShape, ReferenceBox> {
impl<ReferenceBox: Parse> Parse for ShapeSource<BasicShape, ReferenceBox, SpecifiedUrl> {
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
return Ok(ShapeSource::None)
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.