mirror of
https://github.com/servo/servo.git
synced 2025-08-02 04:00:32 +01:00
style: Centralize specified url value handling, and refcount urls.
This commit is contained in:
parent
89c46369a2
commit
5f2e7af864
22 changed files with 267 additions and 187 deletions
|
@ -1205,9 +1205,9 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
||||||
-> ConstructionResult {
|
-> ConstructionResult {
|
||||||
let flotation = FloatKind::from_property(flotation);
|
let flotation = FloatKind::from_property(flotation);
|
||||||
let marker_fragments = match node.style(self.style_context()).get_list().list_style_image {
|
let marker_fragments = match node.style(self.style_context()).get_list().list_style_image {
|
||||||
list_style_image::T::Url(ref url, ref _extra_data) => {
|
list_style_image::T::Url(ref url_value) => {
|
||||||
let image_info = box ImageFragmentInfo::new(node,
|
let image_info = box ImageFragmentInfo::new(node,
|
||||||
Some((*url).clone()),
|
url_value.url().map(|u| (**u).clone()),
|
||||||
&self.layout_context.shared);
|
&self.layout_context.shared);
|
||||||
vec![Fragment::new(node, SpecificFragmentInfo::Image(image_info), self.layout_context)]
|
vec![Fragment::new(node, SpecificFragmentInfo::Image(image_info), self.layout_context)]
|
||||||
}
|
}
|
||||||
|
|
|
@ -612,18 +612,20 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
style);
|
style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(computed::Image::Url(ref image_url, ref _extra_data)) => {
|
Some(computed::Image::Url(ref image_url)) => {
|
||||||
|
if let Some(url) = image_url.url() {
|
||||||
self.build_display_list_for_background_image(state,
|
self.build_display_list_for_background_image(state,
|
||||||
style,
|
style,
|
||||||
display_list_section,
|
display_list_section,
|
||||||
&bounds,
|
&bounds,
|
||||||
&clip,
|
&clip,
|
||||||
image_url,
|
url,
|
||||||
i);
|
i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn compute_background_image_size(&self,
|
fn compute_background_image_size(&self,
|
||||||
style: &ServoComputedValues,
|
style: &ServoComputedValues,
|
||||||
|
|
|
@ -368,7 +368,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
PropertyDeclaration::BackgroundImage(DeclaredValue::Value(
|
PropertyDeclaration::BackgroundImage(DeclaredValue::Value(
|
||||||
background_image::SpecifiedValue(vec![
|
background_image::SpecifiedValue(vec![
|
||||||
background_image::single_value::SpecifiedValue(Some(
|
background_image::single_value::SpecifiedValue(Some(
|
||||||
specified::Image::Url(url, specified::UrlExtraData { })
|
specified::Image::for_cascade(Some(Arc::new(url)), specified::url::UrlExtraData { })
|
||||||
))
|
))
|
||||||
])))));
|
])))));
|
||||||
}
|
}
|
||||||
|
|
1
components/servo/Cargo.lock
generated
1
components/servo/Cargo.lock
generated
|
@ -2528,7 +2528,6 @@ dependencies = [
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -120,11 +120,13 @@ impl nsStyleImage {
|
||||||
Image::Gradient(gradient) => {
|
Image::Gradient(gradient) => {
|
||||||
self.set_gradient(gradient)
|
self.set_gradient(gradient)
|
||||||
},
|
},
|
||||||
Image::Url(ref url, ref extra_data) if with_url => {
|
Image::Url(ref url) if with_url => {
|
||||||
|
let (ptr, len) = url.as_slice_components();
|
||||||
|
let extra_data = url.extra_data();
|
||||||
unsafe {
|
unsafe {
|
||||||
Gecko_SetUrlImageValue(self,
|
Gecko_SetUrlImageValue(self,
|
||||||
url.as_str().as_ptr(),
|
ptr,
|
||||||
url.as_str().len() as u32,
|
len as u32,
|
||||||
extra_data.base.get(),
|
extra_data.base.get(),
|
||||||
extra_data.referrer.get(),
|
extra_data.referrer.get(),
|
||||||
extra_data.principal.get());
|
extra_data.principal.get());
|
||||||
|
|
|
@ -66,15 +66,6 @@ impl<'a> ParserContext<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'a> ParserContext<'a> {
|
|
||||||
pub fn parse_url(&self, input: &str) -> Url {
|
|
||||||
self.base_url.join(input)
|
|
||||||
.unwrap_or_else(|_| Url::parse("about:invalid").unwrap())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Defaults to a no-op.
|
/// Defaults to a no-op.
|
||||||
/// Set a `RUST_LOG=style::errors` environment variable
|
/// Set a `RUST_LOG=style::errors` environment variable
|
||||||
/// to log CSS parse errors to stderr.
|
/// to log CSS parse errors to stderr.
|
||||||
|
|
|
@ -1036,11 +1036,13 @@ fn static_assert() {
|
||||||
use properties::longhands::_moz_binding::computed_value::T as BindingValue;
|
use properties::longhands::_moz_binding::computed_value::T as BindingValue;
|
||||||
match v {
|
match v {
|
||||||
BindingValue::None => debug_assert!(self.gecko.mBinding.mRawPtr.is_null()),
|
BindingValue::None => debug_assert!(self.gecko.mBinding.mRawPtr.is_null()),
|
||||||
BindingValue::Url(ref url, ref extra_data) => {
|
BindingValue::Url(ref url) => {
|
||||||
|
let extra_data = url.extra_data();
|
||||||
|
let (ptr, len) = url.as_slice_components();
|
||||||
unsafe {
|
unsafe {
|
||||||
Gecko_SetMozBinding(&mut self.gecko,
|
Gecko_SetMozBinding(&mut self.gecko,
|
||||||
url.as_str().as_ptr(),
|
ptr,
|
||||||
url.as_str().len() as u32,
|
len as u32,
|
||||||
extra_data.base.get(),
|
extra_data.base.get(),
|
||||||
extra_data.referrer.get(),
|
extra_data.referrer.get(),
|
||||||
extra_data.principal.get());
|
extra_data.principal.get());
|
||||||
|
@ -1441,11 +1443,13 @@ fn static_assert() {
|
||||||
Gecko_SetListStyleImageNone(&mut self.gecko);
|
Gecko_SetListStyleImageNone(&mut self.gecko);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UrlOrNone::Url(ref url, ref extra_data) => {
|
UrlOrNone::Url(ref url) => {
|
||||||
|
let (ptr, len) = url.as_slice_components();
|
||||||
|
let extra_data = url.extra_data();
|
||||||
unsafe {
|
unsafe {
|
||||||
Gecko_SetListStyleImage(&mut self.gecko,
|
Gecko_SetListStyleImage(&mut self.gecko,
|
||||||
url.as_str().as_ptr(),
|
ptr,
|
||||||
url.as_str().len() as u32,
|
len as u32,
|
||||||
extra_data.base.get(),
|
extra_data.base.get(),
|
||||||
extra_data.referrer.get(),
|
extra_data.referrer.get(),
|
||||||
extra_data.principal.get());
|
extra_data.principal.get());
|
||||||
|
|
|
@ -149,20 +149,21 @@ ${helpers.single_keyword("mask-composite",
|
||||||
has_uncacheable_values="${product == 'gecko'}">
|
has_uncacheable_values="${product == 'gecko'}">
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use url::Url;
|
use std::sync::Arc;
|
||||||
use values::specified::{Image, UrlExtraData};
|
use values::specified::Image;
|
||||||
|
use values::specified::url::SpecifiedUrl;
|
||||||
use values::NoViewportPercentage;
|
use values::NoViewportPercentage;
|
||||||
|
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use url::Url;
|
|
||||||
use values::computed;
|
use values::computed;
|
||||||
|
use values::specified::url::SpecifiedUrl;
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub enum T {
|
pub enum T {
|
||||||
Image(computed::Image),
|
Image(computed::Image),
|
||||||
Url(Url, computed::UrlExtraData),
|
Url(SpecifiedUrl),
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +172,7 @@ ${helpers.single_keyword("mask-composite",
|
||||||
match *self {
|
match *self {
|
||||||
T::None => dest.write_str("none"),
|
T::None => dest.write_str("none"),
|
||||||
T::Image(ref image) => image.to_css(dest),
|
T::Image(ref image) => image.to_css(dest),
|
||||||
T::Url(ref url, _) => url.to_css(dest),
|
T::Url(ref url) => url.to_css(dest),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,7 +184,7 @@ ${helpers.single_keyword("mask-composite",
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub enum SpecifiedValue {
|
pub enum SpecifiedValue {
|
||||||
Image(Image),
|
Image(Image),
|
||||||
Url(Url, UrlExtraData),
|
Url(SpecifiedUrl),
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +192,7 @@ ${helpers.single_keyword("mask-composite",
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
match *self {
|
match *self {
|
||||||
SpecifiedValue::Image(ref image) => image.to_css(dest),
|
SpecifiedValue::Image(ref image) => image.to_css(dest),
|
||||||
SpecifiedValue::Url(ref url, _) => url.to_css(dest),
|
SpecifiedValue::Url(ref url) => url.to_css(dest),
|
||||||
SpecifiedValue::None => dest.write_str("none"),
|
SpecifiedValue::None => dest.write_str("none"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,11 +212,16 @@ ${helpers.single_keyword("mask-composite",
|
||||||
} else {
|
} else {
|
||||||
let image = try!(Image::parse(context, input));
|
let image = try!(Image::parse(context, input));
|
||||||
match image {
|
match image {
|
||||||
Image::Url(url, data) => {
|
Image::Url(url_value) => {
|
||||||
if url.fragment().is_some() {
|
let has_valid_url = match url_value.url() {
|
||||||
Ok(SpecifiedValue::Url(url, data))
|
Some(url) => url.fragment().is_some(),
|
||||||
|
None => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if has_valid_url {
|
||||||
|
Ok(SpecifiedValue::Url(url_value))
|
||||||
} else {
|
} else {
|
||||||
Ok(SpecifiedValue::Image(Image::Url(url, data)))
|
Ok(SpecifiedValue::Image(Image::Url(url_value)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
image => Ok(SpecifiedValue::Image(image))
|
image => Ok(SpecifiedValue::Image(image))
|
||||||
|
@ -231,8 +237,8 @@ ${helpers.single_keyword("mask-composite",
|
||||||
SpecifiedValue::None => computed_value::T::None,
|
SpecifiedValue::None => computed_value::T::None,
|
||||||
SpecifiedValue::Image(ref image) =>
|
SpecifiedValue::Image(ref image) =>
|
||||||
computed_value::T::Image(image.to_computed_value(context)),
|
computed_value::T::Image(image.to_computed_value(context)),
|
||||||
SpecifiedValue::Url(ref url, ref data) =>
|
SpecifiedValue::Url(ref url) =>
|
||||||
computed_value::T::Url(url.clone(), data.clone()),
|
computed_value::T::Url(url.clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,8 +248,8 @@ ${helpers.single_keyword("mask-composite",
|
||||||
computed_value::T::None => SpecifiedValue::None,
|
computed_value::T::None => SpecifiedValue::None,
|
||||||
computed_value::T::Image(ref image) =>
|
computed_value::T::Image(ref image) =>
|
||||||
SpecifiedValue::Image(ToComputedValue::from_computed_value(image)),
|
SpecifiedValue::Image(ToComputedValue::from_computed_value(image)),
|
||||||
computed_value::T::Url(ref url, ref data) =>
|
computed_value::T::Url(ref url) =>
|
||||||
SpecifiedValue::Url(url.clone(), data.clone()),
|
SpecifiedValue::Url(url.clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,17 +10,16 @@
|
||||||
use properties::shorthands::serialize_four_sides;
|
use properties::shorthands::serialize_four_sides;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use url::Url;
|
|
||||||
use values::computed::{BorderRadiusSize, LengthOrPercentage};
|
use values::computed::{BorderRadiusSize, LengthOrPercentage};
|
||||||
use values::computed::UrlExtraData;
|
|
||||||
use values::computed::position::Position;
|
use values::computed::position::Position;
|
||||||
|
use values::specified::url::SpecifiedUrl;
|
||||||
|
|
||||||
pub use values::specified::basic_shape::{FillRule, GeometryBox, ShapeBox};
|
pub use values::specified::basic_shape::{FillRule, GeometryBox, ShapeBox};
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub enum ShapeSource<T> {
|
pub enum ShapeSource<T> {
|
||||||
Url(Url, UrlExtraData),
|
Url(SpecifiedUrl),
|
||||||
Shape(BasicShape, Option<T>),
|
Shape(BasicShape, Option<T>),
|
||||||
Box(T),
|
Box(T),
|
||||||
None,
|
None,
|
||||||
|
@ -35,7 +34,7 @@ impl<T> Default for ShapeSource<T> {
|
||||||
impl<T: ToCss> ToCss for ShapeSource<T> {
|
impl<T: ToCss> ToCss for ShapeSource<T> {
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
match *self {
|
match *self {
|
||||||
ShapeSource::Url(ref url, _) => url.to_css(dest),
|
ShapeSource::Url(ref url) => url.to_css(dest),
|
||||||
ShapeSource::Shape(ref shape, Some(ref reference)) => {
|
ShapeSource::Shape(ref shape, Some(ref reference)) => {
|
||||||
try!(shape.to_css(dest));
|
try!(shape.to_css(dest));
|
||||||
try!(dest.write_str(" "));
|
try!(dest.write_str(" "));
|
||||||
|
|
|
@ -10,10 +10,10 @@
|
||||||
use cssparser::Color as CSSColor;
|
use cssparser::Color as CSSColor;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use url::Url;
|
|
||||||
use values::computed::{Context, Length, LengthOrPercentage, ToComputedValue};
|
use values::computed::{Context, Length, LengthOrPercentage, ToComputedValue};
|
||||||
use values::computed::position::Position;
|
use values::computed::position::Position;
|
||||||
use values::specified::{self, AngleOrCorner, SizeKeyword, UrlExtraData};
|
use values::specified::{self, AngleOrCorner, SizeKeyword};
|
||||||
|
use values::specified::url::SpecifiedUrl;
|
||||||
|
|
||||||
|
|
||||||
impl ToComputedValue for specified::Image {
|
impl ToComputedValue for specified::Image {
|
||||||
|
@ -22,8 +22,8 @@ impl ToComputedValue for specified::Image {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_computed_value(&self, context: &Context) -> Image {
|
fn to_computed_value(&self, context: &Context) -> Image {
|
||||||
match *self {
|
match *self {
|
||||||
specified::Image::Url(ref url, ref extra_data) => {
|
specified::Image::Url(ref url_value) => {
|
||||||
Image::Url(url.clone(), extra_data.clone())
|
Image::Url(url_value.clone())
|
||||||
},
|
},
|
||||||
specified::Image::Gradient(ref gradient) => {
|
specified::Image::Gradient(ref gradient) => {
|
||||||
Image::Gradient(gradient.to_computed_value(context))
|
Image::Gradient(gradient.to_computed_value(context))
|
||||||
|
@ -34,8 +34,8 @@ impl ToComputedValue for specified::Image {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_computed_value(computed: &Image) -> Self {
|
fn from_computed_value(computed: &Image) -> Self {
|
||||||
match *computed {
|
match *computed {
|
||||||
Image::Url(ref url, ref extra_data) => {
|
Image::Url(ref url_value) => {
|
||||||
specified::Image::Url(url.clone(), extra_data.clone())
|
specified::Image::Url(url_value.clone())
|
||||||
},
|
},
|
||||||
Image::Gradient(ref linear_gradient) => {
|
Image::Gradient(ref linear_gradient) => {
|
||||||
specified::Image::Gradient(
|
specified::Image::Gradient(
|
||||||
|
@ -51,14 +51,14 @@ impl ToComputedValue for specified::Image {
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub enum Image {
|
pub enum Image {
|
||||||
Url(Url, UrlExtraData),
|
Url(SpecifiedUrl),
|
||||||
Gradient(Gradient),
|
Gradient(Gradient),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Image {
|
impl fmt::Debug for Image {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
Image::Url(ref url, ref _extra_data) => write!(f, "url(\"{}\")", url),
|
Image::Url(ref url) => url.to_css(f),
|
||||||
Image::Gradient(ref grad) => {
|
Image::Gradient(ref grad) => {
|
||||||
if grad.repeating {
|
if grad.repeating {
|
||||||
let _ = write!(f, "repeating-");
|
let _ = write!(f, "repeating-");
|
||||||
|
@ -75,9 +75,7 @@ impl fmt::Debug for Image {
|
||||||
impl ToCss for Image {
|
impl ToCss for Image {
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
match *self {
|
match *self {
|
||||||
Image::Url(ref url, _) => {
|
Image::Url(ref url) => url.to_css(dest),
|
||||||
url.to_css(dest)
|
|
||||||
}
|
|
||||||
Image::Gradient(ref gradient) => gradient.to_css(dest)
|
Image::Gradient(ref gradient) => gradient.to_css(dest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ use values::{CSSFloat, Either, None_, specified};
|
||||||
pub use cssparser::Color as CSSColor;
|
pub use cssparser::Color as CSSColor;
|
||||||
pub use super::image::{EndingShape as GradientShape, Gradient, GradientKind, Image};
|
pub use super::image::{EndingShape as GradientShape, Gradient, GradientKind, Image};
|
||||||
pub use super::image::{LengthOrKeyword, LengthOrPercentageOrKeyword};
|
pub use super::image::{LengthOrKeyword, LengthOrPercentageOrKeyword};
|
||||||
pub use values::specified::{Angle, BorderStyle, Time, UrlExtraData, UrlOrNone};
|
pub use values::specified::{Angle, BorderStyle, Time, UrlOrNone};
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Copy, Debug)]
|
#[derive(Clone, PartialEq, Copy, Debug)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
|
|
@ -13,7 +13,8 @@ pub use cssparser::Color as CSSColor;
|
||||||
pub use self::image::{EndingShape as GradientShape, Gradient, GradientKind, Image};
|
pub use self::image::{EndingShape as GradientShape, Gradient, GradientKind, Image};
|
||||||
pub use self::image::{LengthOrKeyword, LengthOrPercentageOrKeyword};
|
pub use self::image::{LengthOrKeyword, LengthOrPercentageOrKeyword};
|
||||||
pub use super::{Either, None_};
|
pub use super::{Either, None_};
|
||||||
pub use super::specified::{Angle, BorderStyle, Time, UrlExtraData, UrlOrNone};
|
pub use super::specified::{Angle, BorderStyle, Time, UrlOrNone};
|
||||||
|
pub use super::specified::url::UrlExtraData;
|
||||||
pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto};
|
pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto};
|
||||||
pub use self::length::{LengthOrPercentageOrAutoOrContent, LengthOrPercentageOrNone, LengthOrNone};
|
pub use self::length::{LengthOrPercentageOrAutoOrContent, LengthOrPercentageOrNone, LengthOrNone};
|
||||||
|
|
||||||
|
|
|
@ -12,12 +12,11 @@ use parser::{Parse, ParserContext};
|
||||||
use properties::shorthands::{parse_four_sides, serialize_four_sides};
|
use properties::shorthands::{parse_four_sides, serialize_four_sides};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use url::Url;
|
|
||||||
use values::computed::{ComputedValueAsSpecified, Context, ToComputedValue};
|
use values::computed::{ComputedValueAsSpecified, Context, ToComputedValue};
|
||||||
use values::computed::basic_shape as computed_basic_shape;
|
use values::computed::basic_shape as computed_basic_shape;
|
||||||
use values::specified::{BorderRadiusSize, LengthOrPercentage, Percentage};
|
use values::specified::{BorderRadiusSize, LengthOrPercentage, Percentage};
|
||||||
use values::specified::UrlExtraData;
|
|
||||||
use values::specified::position::{Keyword, Position};
|
use values::specified::position::{Keyword, Position};
|
||||||
|
use values::specified::url::SpecifiedUrl;
|
||||||
|
|
||||||
/// A shape source, for some reference box
|
/// A shape source, for some reference box
|
||||||
///
|
///
|
||||||
|
@ -26,7 +25,7 @@ use values::specified::position::{Keyword, Position};
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub enum ShapeSource<T> {
|
pub enum ShapeSource<T> {
|
||||||
Url(Url, UrlExtraData),
|
Url(SpecifiedUrl),
|
||||||
Shape(BasicShape, Option<T>),
|
Shape(BasicShape, Option<T>),
|
||||||
Box(T),
|
Box(T),
|
||||||
None,
|
None,
|
||||||
|
@ -41,7 +40,7 @@ impl<T> Default for ShapeSource<T> {
|
||||||
impl<T: ToCss> ToCss for ShapeSource<T> {
|
impl<T: ToCss> ToCss for ShapeSource<T> {
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
match *self {
|
match *self {
|
||||||
ShapeSource::Url(ref url, _) => url.to_css(dest),
|
ShapeSource::Url(ref url) => url.to_css(dest),
|
||||||
ShapeSource::Shape(ref shape, Some(ref reference)) => {
|
ShapeSource::Shape(ref shape, Some(ref reference)) => {
|
||||||
try!(shape.to_css(dest));
|
try!(shape.to_css(dest));
|
||||||
try!(dest.write_str(" "));
|
try!(dest.write_str(" "));
|
||||||
|
@ -59,13 +58,8 @@ impl<T: Parse + PartialEq + Copy> ShapeSource<T> {
|
||||||
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||||
if let Ok(_) = input.try(|input| input.expect_ident_matching("none")) {
|
if let Ok(_) = input.try(|input| input.expect_ident_matching("none")) {
|
||||||
Ok(ShapeSource::None)
|
Ok(ShapeSource::None)
|
||||||
} else if let Ok(url) = input.try(|input| input.expect_url()) {
|
} else if let Ok(url) = input.try(|input| SpecifiedUrl::parse(context, input)) {
|
||||||
match UrlExtraData::make_from(context) {
|
Ok(ShapeSource::Url(url))
|
||||||
Some(extra_data) => {
|
|
||||||
Ok(ShapeSource::Url(context.parse_url(&url), extra_data))
|
|
||||||
},
|
|
||||||
None => Err(()),
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
fn parse_component<U: Parse>(input: &mut Parser, component: &mut Option<U>) -> bool {
|
fn parse_component<U: Parse>(input: &mut Parser, component: &mut Option<U>) -> bool {
|
||||||
if component.is_some() {
|
if component.is_some() {
|
||||||
|
@ -98,8 +92,8 @@ impl<T: ToComputedValue> ToComputedValue for ShapeSource<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue {
|
fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue {
|
||||||
match *self {
|
match *self {
|
||||||
ShapeSource::Url(ref url, ref data) => {
|
ShapeSource::Url(ref url) => {
|
||||||
computed_basic_shape::ShapeSource::Url(url.clone(), data.clone())
|
computed_basic_shape::ShapeSource::Url(url.to_computed_value(cx))
|
||||||
}
|
}
|
||||||
ShapeSource::Shape(ref shape, ref reference) => {
|
ShapeSource::Shape(ref shape, ref reference) => {
|
||||||
computed_basic_shape::ShapeSource::Shape(
|
computed_basic_shape::ShapeSource::Shape(
|
||||||
|
@ -116,8 +110,8 @@ impl<T: ToComputedValue> ToComputedValue for ShapeSource<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||||
match *computed {
|
match *computed {
|
||||||
computed_basic_shape::ShapeSource::Url(ref url, ref data) => {
|
computed_basic_shape::ShapeSource::Url(ref url) => {
|
||||||
ShapeSource::Url(url.clone(), data.clone())
|
ShapeSource::Url(SpecifiedUrl::from_computed_value(url))
|
||||||
}
|
}
|
||||||
computed_basic_shape::ShapeSource::Shape(ref shape, ref reference) => {
|
computed_basic_shape::ShapeSource::Shape(ref shape, ref reference) => {
|
||||||
ShapeSource::Shape(
|
ShapeSource::Shape(
|
||||||
|
|
|
@ -11,49 +11,45 @@ use cssparser::Parser;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use std::f32::consts::PI;
|
use std::f32::consts::PI;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::sync::Arc;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use values::computed::ComputedValueAsSpecified;
|
use values::computed::ComputedValueAsSpecified;
|
||||||
use values::specified::{Angle, CSSColor, Length, LengthOrPercentage, UrlExtraData};
|
use values::specified::{Angle, CSSColor, Length, LengthOrPercentage};
|
||||||
use values::specified::position::Position;
|
use values::specified::position::Position;
|
||||||
|
use values::specified::url::{SpecifiedUrl, UrlExtraData};
|
||||||
|
|
||||||
/// Specified values for an image according to CSS-IMAGES.
|
/// Specified values for an image according to CSS-IMAGES.
|
||||||
/// https://drafts.csswg.org/css-images/#image-values
|
/// https://drafts.csswg.org/css-images/#image-values
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub enum Image {
|
pub enum Image {
|
||||||
Url(Url, UrlExtraData),
|
Url(SpecifiedUrl),
|
||||||
Gradient(Gradient),
|
Gradient(Gradient),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToCss for Image {
|
impl ToCss for Image {
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
match *self {
|
match *self {
|
||||||
Image::Url(ref url, ref _extra_data) => {
|
Image::Url(ref url_value) => url_value.to_css(dest),
|
||||||
url.to_css(dest)
|
Image::Gradient(ref gradient) => gradient.to_css(dest),
|
||||||
}
|
|
||||||
Image::Gradient(ref gradient) => gradient.to_css(dest)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Image {
|
impl Image {
|
||||||
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<Image, ()> {
|
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<Image, ()> {
|
||||||
if let Ok(url) = input.try(|input| input.expect_url()) {
|
if let Ok(url) = input.try(|input| SpecifiedUrl::parse(context, input)) {
|
||||||
match UrlExtraData::make_from(context) {
|
return Ok(Image::Url(url));
|
||||||
Some(extra_data) => {
|
|
||||||
Ok(Image::Url(context.parse_url(&url), extra_data))
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
// FIXME(heycam) should ensure we always have a principal, etc., when
|
|
||||||
// parsing style attributes and re-parsing due to CSS Variables.
|
|
||||||
println!("stylo: skipping declaration without ParserContextExtraData");
|
|
||||||
Err(())
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Ok(Image::Gradient(try!(Gradient::parse_function(input))))
|
Ok(Image::Gradient(try!(Gradient::parse_function(input))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates an already specified image value from an already resolved URL
|
||||||
|
/// for insertion in the cascade.
|
||||||
|
pub fn for_cascade(url: Option<Arc<Url>>, extra_data: UrlExtraData) -> Self {
|
||||||
|
Image::Url(SpecifiedUrl::for_cascade(url, extra_data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,8 @@
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use cssparser::{self, Parser, Token};
|
use cssparser::{self, Parser, Token};
|
||||||
use euclid::size::Size2D;
|
use euclid::size::Size2D;
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
use gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI};
|
|
||||||
use parser::ParserContext;
|
use parser::ParserContext;
|
||||||
#[cfg(feature = "gecko")]
|
use self::url::SpecifiedUrl;
|
||||||
use parser::ParserContextExtraData;
|
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::f32::consts::PI;
|
use std::f32::consts::PI;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -17,7 +14,6 @@ use std::ops::Mul;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use super::{CSSFloat, HasViewportPercentage, NoViewportPercentage};
|
use super::{CSSFloat, HasViewportPercentage, NoViewportPercentage};
|
||||||
use super::computed::{ComputedValueAsSpecified, Context, ToComputedValue};
|
use super::computed::{ComputedValueAsSpecified, Context, ToComputedValue};
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
pub use self::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingShape, Gradient};
|
pub use self::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingShape, Gradient};
|
||||||
pub use self::image::{GradientKind, HorizontalDirection, Image, LengthOrKeyword, LengthOrPercentageOrKeyword};
|
pub use self::image::{GradientKind, HorizontalDirection, Image, LengthOrKeyword, LengthOrPercentageOrKeyword};
|
||||||
|
@ -30,6 +26,7 @@ pub mod basic_shape;
|
||||||
pub mod image;
|
pub mod image;
|
||||||
pub mod length;
|
pub mod length;
|
||||||
pub mod position;
|
pub mod position;
|
||||||
|
pub mod url;
|
||||||
|
|
||||||
impl NoViewportPercentage for i32 {} // For PropertyDeclaration::Order
|
impl NoViewportPercentage for i32 {} // For PropertyDeclaration::Order
|
||||||
|
|
||||||
|
@ -263,42 +260,6 @@ impl Angle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Debug)]
|
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
|
||||||
pub struct UrlExtraData {
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
pub base: GeckoArcURI,
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
pub referrer: GeckoArcURI,
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
pub principal: GeckoArcPrincipal,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UrlExtraData {
|
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
pub fn make_from(_: &ParserContext) -> Option<UrlExtraData> {
|
|
||||||
Some(UrlExtraData { })
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
pub fn make_from(context: &ParserContext) -> Option<UrlExtraData> {
|
|
||||||
match context.extra_data {
|
|
||||||
ParserContextExtraData {
|
|
||||||
base: Some(ref base),
|
|
||||||
referrer: Some(ref referrer),
|
|
||||||
principal: Some(ref principal),
|
|
||||||
} => {
|
|
||||||
Some(UrlExtraData {
|
|
||||||
base: base.clone(),
|
|
||||||
referrer: referrer.clone(),
|
|
||||||
principal: principal.clone(),
|
|
||||||
})
|
|
||||||
},
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_border_radius(input: &mut Parser) -> Result<BorderRadiusSize, ()> {
|
pub fn parse_border_radius(input: &mut Parser) -> Result<BorderRadiusSize, ()> {
|
||||||
input.try(BorderRadiusSize::parse).or_else(|()| {
|
input.try(BorderRadiusSize::parse).or_else(|()| {
|
||||||
match_ignore_ascii_case! { try!(input.expect_ident()),
|
match_ignore_ascii_case! { try!(input.expect_ident()),
|
||||||
|
@ -546,7 +507,7 @@ impl ToCss for Opacity {
|
||||||
#[derive(PartialEq, Clone, Debug)]
|
#[derive(PartialEq, Clone, Debug)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub enum UrlOrNone {
|
pub enum UrlOrNone {
|
||||||
Url(Url, UrlExtraData),
|
Url(SpecifiedUrl),
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,13 +517,8 @@ impl NoViewportPercentage for UrlOrNone {}
|
||||||
impl ToCss for UrlOrNone {
|
impl ToCss for UrlOrNone {
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
match *self {
|
match *self {
|
||||||
UrlOrNone::Url(ref url, _) => {
|
UrlOrNone::Url(ref url) => url.to_css(dest),
|
||||||
url.to_css(dest)
|
UrlOrNone::None => dest.write_str("none"),
|
||||||
}
|
|
||||||
UrlOrNone::None => {
|
|
||||||
try!(dest.write_str("none"));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -573,17 +529,6 @@ impl UrlOrNone {
|
||||||
return Ok(UrlOrNone::None);
|
return Ok(UrlOrNone::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = context.parse_url(&*try!(input.expect_url()));
|
Ok(UrlOrNone::Url(try!(SpecifiedUrl::parse(context, input))))
|
||||||
match UrlExtraData::make_from(context) {
|
|
||||||
Some(extra_data) => {
|
|
||||||
Ok(UrlOrNone::Url(url, extra_data))
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
// FIXME(heycam) should ensure we always have a principal, etc., when parsing
|
|
||||||
// style attributes and re-parsing due to CSS Variables.
|
|
||||||
println!("stylo: skipping UrlOrNone declaration without ParserContextExtraData");
|
|
||||||
Err(())
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
165
components/style/values/specified/url.rs
Normal file
165
components/style/values/specified/url.rs
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
/* 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 http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
//! Common handling for the specified value CSS url() values.
|
||||||
|
|
||||||
|
use cssparser::{CssStringWriter, Parser};
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
use gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI};
|
||||||
|
use parser::ParserContext;
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
use parser::ParserContextExtraData;
|
||||||
|
use std::fmt::{self, Write};
|
||||||
|
use std::ptr;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use style_traits::ToCss;
|
||||||
|
use url::Url;
|
||||||
|
use values::computed::ComputedValueAsSpecified;
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Debug)]
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
pub struct UrlExtraData {
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
pub base: GeckoArcURI,
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
pub referrer: GeckoArcURI,
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
pub principal: GeckoArcPrincipal,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UrlExtraData {
|
||||||
|
#[cfg(feature = "servo")]
|
||||||
|
pub fn make_from(_: &ParserContext) -> Option<UrlExtraData> {
|
||||||
|
Some(UrlExtraData { })
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
pub fn make_from(context: &ParserContext) -> Option<UrlExtraData> {
|
||||||
|
match context.extra_data {
|
||||||
|
ParserContextExtraData {
|
||||||
|
base: Some(ref base),
|
||||||
|
referrer: Some(ref referrer),
|
||||||
|
principal: Some(ref principal),
|
||||||
|
} => {
|
||||||
|
Some(UrlExtraData {
|
||||||
|
base: base.clone(),
|
||||||
|
referrer: referrer.clone(),
|
||||||
|
principal: principal.clone(),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A specified url() value.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
pub struct SpecifiedUrl {
|
||||||
|
/// The original URI. This might be optional since we may insert computed
|
||||||
|
/// values of images into the cascade directly, and we don't bother to
|
||||||
|
/// convert their serialization.
|
||||||
|
///
|
||||||
|
/// Refcounted since cloning this should be cheap and data: uris can be
|
||||||
|
/// really large.
|
||||||
|
original: Option<Arc<String>>,
|
||||||
|
|
||||||
|
/// The resolved value for the url, if valid.
|
||||||
|
resolved: Option<Arc<Url>>,
|
||||||
|
|
||||||
|
/// Extra data used for Stylo.
|
||||||
|
extra_data: UrlExtraData,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SpecifiedUrl {
|
||||||
|
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||||
|
let url = try!(input.expect_url());
|
||||||
|
|
||||||
|
let extra_data = match UrlExtraData::make_from(context) {
|
||||||
|
Some(extra_data) => extra_data,
|
||||||
|
None => {
|
||||||
|
// FIXME(heycam) should ensure we always have a principal, etc.,
|
||||||
|
// when parsing style attributes and re-parsing due to CSS
|
||||||
|
// Variables.
|
||||||
|
println!("stylo: skipping declaration without ParserContextExtraData");
|
||||||
|
return Err(())
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let serialization = Arc::new(url.into_owned());
|
||||||
|
let resolved = context.base_url.join(&serialization).ok().map(Arc::new);
|
||||||
|
Ok(SpecifiedUrl {
|
||||||
|
original: Some(serialization),
|
||||||
|
resolved: resolved,
|
||||||
|
extra_data: extra_data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn extra_data(&self) -> &UrlExtraData {
|
||||||
|
&self.extra_data
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn url(&self) -> Option<&Arc<Url>> {
|
||||||
|
self.resolved.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Little helper for Gecko's ffi.
|
||||||
|
pub fn as_slice_components(&self) -> (*const u8, usize) {
|
||||||
|
match self.resolved {
|
||||||
|
Some(ref url) => (url.as_str().as_ptr(), url.as_str().len()),
|
||||||
|
None => (ptr::null(), 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates an already specified url value from an already resolved URL
|
||||||
|
/// for insertion in the cascade.
|
||||||
|
pub fn for_cascade(url: Option<Arc<Url>>, extra_data: UrlExtraData) -> Self {
|
||||||
|
SpecifiedUrl {
|
||||||
|
original: None,
|
||||||
|
resolved: url,
|
||||||
|
extra_data: extra_data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just for unit tests, don't use outside of them!
|
||||||
|
#[cfg(feature = "servo")]
|
||||||
|
pub fn new_for_testing(url: &str) -> Self {
|
||||||
|
SpecifiedUrl {
|
||||||
|
original: Some(Arc::new(url.into())),
|
||||||
|
resolved: Url::parse(url).ok().map(Arc::new),
|
||||||
|
extra_data: UrlExtraData {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for SpecifiedUrl {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
// TODO(emilio): maybe we care about equality of the specified values if
|
||||||
|
// present? Seems not.
|
||||||
|
self.resolved == other.resolved &&
|
||||||
|
self.extra_data == other.extra_data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for SpecifiedUrl {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
|
try!(dest.write_str("url(\""));
|
||||||
|
let string = match self.original {
|
||||||
|
Some(ref original) => &**original,
|
||||||
|
None => match self.resolved {
|
||||||
|
Some(ref url) => url.as_str(),
|
||||||
|
// This can only happen if the url wasn't specified by the
|
||||||
|
// user *and* it's an invalid url that has been transformed
|
||||||
|
// back to specified value via the "uncompute" functionality.
|
||||||
|
None => "about:invalid",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try!(CssStringWriter::new(dest).write_str(string));
|
||||||
|
dest.write_str("\")")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(emilio): Maybe consider ComputedUrl to save a word in style structs?
|
||||||
|
impl ComputedValueAsSpecified for SpecifiedUrl {}
|
|
@ -22,4 +22,3 @@ heapsize_derive = {version = "0.1", optional = true}
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
serde = {version = "0.8", optional = true}
|
serde = {version = "0.8", optional = true}
|
||||||
serde_derive = {version = "0.8", optional = true}
|
serde_derive = {version = "0.8", optional = true}
|
||||||
url = "1.2"
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ extern crate euclid;
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
#[cfg(feature = "servo")] extern crate serde;
|
#[cfg(feature = "servo")] extern crate serde;
|
||||||
#[cfg(feature = "servo")] #[macro_use] extern crate serde_derive;
|
#[cfg(feature = "servo")] #[macro_use] extern crate serde_derive;
|
||||||
extern crate url;
|
|
||||||
|
|
||||||
/// Opaque type stored in type-unsafe work queues for parallel layout.
|
/// Opaque type stored in type-unsafe work queues for parallel layout.
|
||||||
/// Must be transmutable to and from TNode.
|
/// Must be transmutable to and from TNode.
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use cssparser::CssStringWriter;
|
use std::fmt;
|
||||||
use std::fmt::{self, Write};
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
/// The real ToCss trait can't be implemented for types in crates that don't
|
/// The real ToCss trait can't be implemented for types in crates that don't
|
||||||
/// depend on each other.
|
/// depend on each other.
|
||||||
|
@ -30,15 +28,6 @@ impl ToCss for Au {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToCss for Url {
|
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
|
||||||
try!(dest.write_str("url(\""));
|
|
||||||
try!(write!(CssStringWriter::new(dest), "{}", self));
|
|
||||||
try!(dest.write_str("\")"));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! impl_to_css_for_predefined_type {
|
macro_rules! impl_to_css_for_predefined_type {
|
||||||
($name: ty) => {
|
($name: ty) => {
|
||||||
impl<'a> ToCss for $name {
|
impl<'a> ToCss for $name {
|
||||||
|
|
1
ports/cef/Cargo.lock
generated
1
ports/cef/Cargo.lock
generated
|
@ -2357,7 +2357,6 @@ dependencies = [
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
1
ports/geckolib/Cargo.lock
generated
1
ports/geckolib/Cargo.lock
generated
|
@ -373,7 +373,6 @@ dependencies = [
|
||||||
"cssparser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -9,9 +9,8 @@ pub use style::values::specified::{BorderStyle, BorderWidth, CSSColor, Length};
|
||||||
pub use style::values::specified::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrAutoOrContent};
|
pub use style::values::specified::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrAutoOrContent};
|
||||||
pub use style::properties::longhands::outline_color::computed_value::T as ComputedColor;
|
pub use style::properties::longhands::outline_color::computed_value::T as ComputedColor;
|
||||||
pub use style::values::RGBA;
|
pub use style::values::RGBA;
|
||||||
pub use style::values::specified::UrlExtraData;
|
pub use style::values::specified::url::{UrlExtraData, SpecifiedUrl};
|
||||||
pub use style_traits::ToCss;
|
pub use style_traits::ToCss;
|
||||||
pub use url::Url;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn property_declaration_block_should_serialize_correctly() {
|
fn property_declaration_block_should_serialize_correctly() {
|
||||||
|
@ -430,9 +429,7 @@ mod shorthand_serialization {
|
||||||
|
|
||||||
let position = DeclaredValue::Value(ListStylePosition::inside);
|
let position = DeclaredValue::Value(ListStylePosition::inside);
|
||||||
let image = DeclaredValue::Value(ListStyleImage::Url(
|
let image = DeclaredValue::Value(ListStyleImage::Url(
|
||||||
Url::parse("http://servo/test.png").unwrap(),
|
SpecifiedUrl::new_for_testing("http://servo/test.png")));
|
||||||
UrlExtraData {},
|
|
||||||
));
|
|
||||||
let style_type = DeclaredValue::Value(ListStyleType::disc);
|
let style_type = DeclaredValue::Value(ListStyleType::disc);
|
||||||
|
|
||||||
properties.push(PropertyDeclaration::ListStylePosition(position));
|
properties.push(PropertyDeclaration::ListStylePosition(position));
|
||||||
|
@ -747,8 +744,7 @@ mod shorthand_serialization {
|
||||||
let attachment = single_vec_keyword_value!(attachment, scroll);
|
let attachment = single_vec_keyword_value!(attachment, scroll);
|
||||||
|
|
||||||
let image = single_vec_value!(image,
|
let image = single_vec_value!(image,
|
||||||
Some(Image::Url(Url::parse("http://servo/test.png").unwrap(),
|
Some(Image::Url(SpecifiedUrl::new_for_testing("http://servo/test.png"))));
|
||||||
UrlExtraData {})));
|
|
||||||
|
|
||||||
let size = single_vec_variant_value!(size,
|
let size = single_vec_variant_value!(size,
|
||||||
size::single_value::SpecifiedValue::Explicit(
|
size::single_value::SpecifiedValue::Explicit(
|
||||||
|
@ -802,8 +798,7 @@ mod shorthand_serialization {
|
||||||
let attachment = single_vec_keyword_value!(attachment, scroll);
|
let attachment = single_vec_keyword_value!(attachment, scroll);
|
||||||
|
|
||||||
let image = single_vec_value!(image,
|
let image = single_vec_value!(image,
|
||||||
Some(Image::Url(Url::parse("http://servo/test.png").unwrap(),
|
Some(Image::Url(SpecifiedUrl::new_for_testing("http://servo/test.png"))));
|
||||||
UrlExtraData {})));
|
|
||||||
|
|
||||||
let size = single_vec_variant_value!(size,
|
let size = single_vec_variant_value!(size,
|
||||||
size::single_value::SpecifiedValue::Explicit(
|
size::single_value::SpecifiedValue::Explicit(
|
||||||
|
@ -917,8 +912,7 @@ mod shorthand_serialization {
|
||||||
|
|
||||||
let image = single_vec_value_typedef!(image,
|
let image = single_vec_value_typedef!(image,
|
||||||
image::single_value::SpecifiedValue::Image(
|
image::single_value::SpecifiedValue::Image(
|
||||||
Image::Url(Url::parse("http://servo/test.png").unwrap(),
|
Image::Url(SpecifiedUrl::new_for_testing("http://servo/test.png"))));
|
||||||
UrlExtraData {})));
|
|
||||||
|
|
||||||
let mode = single_vec_keyword_value!(mode, luminance);
|
let mode = single_vec_keyword_value!(mode, luminance);
|
||||||
|
|
||||||
|
@ -968,8 +962,7 @@ mod shorthand_serialization {
|
||||||
|
|
||||||
let image = single_vec_value_typedef!(image,
|
let image = single_vec_value_typedef!(image,
|
||||||
image::single_value::SpecifiedValue::Image(
|
image::single_value::SpecifiedValue::Image(
|
||||||
Image::Url(Url::parse("http://servo/test.png").unwrap(),
|
Image::Url(SpecifiedUrl::new_for_testing("http://servo/test.png"))));
|
||||||
UrlExtraData {})));
|
|
||||||
|
|
||||||
let mode = single_vec_keyword_value!(mode, luminance);
|
let mode = single_vec_keyword_value!(mode, luminance);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue