Auto merge of #13715 - heycam:url-or-none, r=Manishearth

Factor out a UrlOrNone type for -moz-binding and list-style-image to use

<!-- Please describe your changes on the following line: -->

r? @Manishearth

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13715)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-10-15 23:24:40 -05:00 committed by GitHub
commit bd1b50456a
7 changed files with 69 additions and 156 deletions

View file

@ -43,7 +43,7 @@ use std::marker::PhantomData;
use std::mem;
use std::sync::Arc;
use std::sync::atomic::Ordering;
use style::computed_values::{caption_side, display, empty_cells, float, list_style_position};
use style::computed_values::{caption_side, display, empty_cells, float, list_style_image, list_style_position};
use style::computed_values::content::ContentItem;
use style::computed_values::position;
use style::context::SharedStyleContext;
@ -1264,14 +1264,14 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
fn build_flow_for_list_item(&mut self, node: &ConcreteThreadSafeLayoutNode, flotation: float::T)
-> ConstructionResult {
let flotation = FloatKind::from_property(flotation);
let marker_fragments = match node.style(self.style_context()).get_list().list_style_image.0 {
Some(ref url) => {
let marker_fragments = match node.style(self.style_context()).get_list().list_style_image {
list_style_image::T::Url(ref url, ref _extra_data) => {
let image_info = box ImageFragmentInfo::new(node,
Some((*url).clone()),
&self.layout_context.shared);
vec![Fragment::new(node, SpecificFragmentInfo::Image(image_info), self.layout_context)]
}
None => {
list_style_image::T::None => {
match ListStyleTypeContent::from_list_style_type(node.style(self.style_context())
.get_list()
.list_style_type) {

View file

@ -893,7 +893,7 @@ fn static_assert() {
#[allow(non_snake_case)]
pub fn set__moz_binding(&mut self, v: longhands::_moz_binding::computed_value::T) {
use properties::longhands::_moz_binding::SpecifiedValue as BindingValue;
use properties::longhands::_moz_binding::computed_value::T as BindingValue;
match v {
BindingValue::None => debug_assert!(self.gecko.mBinding.mRawPtr.is_null()),
BindingValue::Url(ref url, ref extra_data) => {

View file

@ -16,19 +16,24 @@
</%call>
</%def>
<%def name="predefined_type(name, type, initial_value, parse_method='parse', **kwargs)">
<%def name="predefined_type(name, type, initial_value, parse_method='parse', needs_context=False, **kwargs)">
<%call expr="longhand(name, predefined_type=type, **kwargs)">
#[allow(unused_imports)]
use app_units::Au;
use cssparser::{Color as CSSParserColor, RGBA};
pub type SpecifiedValue = specified::${type};
pub use values::specified::${type} as SpecifiedValue;
pub mod computed_value {
pub use values::computed::${type} as T;
}
#[inline] pub fn get_initial_value() -> computed_value::T { ${initial_value} }
#[inline] pub fn parse(_context: &ParserContext, input: &mut Parser)
#[allow(unused_variables)]
#[inline] pub fn parse(context: &ParserContext, input: &mut Parser)
-> Result<SpecifiedValue, ()> {
% if needs_context:
specified::${type}::${parse_method}(context, input)
% else:
specified::${type}::${parse_method}(input)
% endif
}
</%call>
</%def>

View file

@ -920,73 +920,8 @@ ${helpers.single_keyword("-moz-appearance",
animatable=False)}
// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-binding
<%helpers:longhand name="-moz-binding" products="gecko" animatable="False" disable_when_testing="True">
use cssparser::{CssStringWriter, ToCss};
use gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI};
use std::fmt::{self, Write};
use url::Url;
use values::specified::UrlExtraData;
use values::computed::ComputedValueAsSpecified;
use values::NoViewportPercentage;
#[derive(PartialEq, Clone, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum SpecifiedValue {
Url(Url, UrlExtraData),
None,
}
impl ComputedValueAsSpecified for SpecifiedValue {}
impl NoViewportPercentage for SpecifiedValue {}
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
use values::LocalToCss;
match *self {
SpecifiedValue::Url(ref url, _) => {
url.to_css(dest)
}
SpecifiedValue::None => {
try!(dest.write_str("none"));
Ok(())
}
}
}
}
pub mod computed_value {
pub type T = super::SpecifiedValue;
}
#[inline] pub fn get_initial_value() -> SpecifiedValue {
SpecifiedValue::None
}
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
return Ok(SpecifiedValue::None);
}
let url = context.parse_url(&*try!(input.expect_url()));
match context.extra_data {
ParserContextExtraData {
base: Some(ref base),
referrer: Some(ref referrer),
principal: Some(ref principal),
} => {
let extra_data = UrlExtraData {
base: base.clone(),
referrer: referrer.clone(),
principal: principal.clone(),
};
Ok(SpecifiedValue::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 -moz-binding declaration without ParserContextExtraData");
Err(())
},
}
}
</%helpers:longhand>
${helpers.predefined_type("-moz-binding", "UrlOrNone", "computed_value::T::None",
needs_context=True,
products="gecko",
animatable="False",
disable_when_testing="True")}

View file

@ -26,83 +26,9 @@ ${helpers.single_keyword("list-style-type", """
gecko_constant_prefix="NS_STYLE_LIST_STYLE",
animatable=False)}
<%helpers:longhand name="list-style-image" animatable="False">
use cssparser::{ToCss, Token};
use std::fmt;
use url::Url;
use values::LocalToCss;
use values::NoViewportPercentage;
impl NoViewportPercentage for SpecifiedValue {}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum SpecifiedValue {
None,
Url(Url),
}
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self {
SpecifiedValue::None => dest.write_str("none"),
SpecifiedValue::Url(ref url) => url.to_css(dest),
}
}
}
pub mod computed_value {
use cssparser::{ToCss, Token};
use std::fmt;
use url::Url;
use values::LocalToCss;
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct T(pub Option<Url>);
impl ToCss for T {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match self.0 {
None => dest.write_str("none"),
Some(ref url) => url.to_css(dest),
}
}
}
}
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
#[inline]
fn to_computed_value(&self, _context: &Context) -> computed_value::T {
match *self {
SpecifiedValue::None => computed_value::T(None),
SpecifiedValue::Url(ref url) => computed_value::T(Some(url.clone())),
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
computed_value::T(None) => SpecifiedValue::None,
computed_value::T(Some(ref url)) => SpecifiedValue::Url(url.clone()),
}
}
}
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
Ok(SpecifiedValue::None)
} else {
Ok(SpecifiedValue::Url(context.parse_url(&*try!(input.expect_url()))))
}
}
#[inline]
pub fn get_initial_value() -> computed_value::T {
computed_value::T(None)
}
</%helpers:longhand>
${helpers.predefined_type("list-style-image", "UrlOrNone", "computed_value::T::None",
needs_context=True,
animatable="False")}
<%helpers:longhand name="quotes" animatable="False">
use std::borrow::Cow;

View file

@ -13,7 +13,7 @@ use super::LocalToCss;
pub use cssparser::Color as CSSColor;
pub use self::image::{EndingShape as GradientShape, Gradient, GradientKind, Image};
pub use self::image::{LengthOrKeyword, LengthOrPercentageOrKeyword};
pub use super::specified::{Angle, BorderStyle, Time, UrlExtraData};
pub use super::specified::{Angle, BorderStyle, Time, UrlExtraData, UrlOrNone};
pub mod basic_shape;
pub mod image;

View file

@ -18,6 +18,7 @@ use std::ops::Mul;
use style_traits::values::specified::AllowedNumericType;
use super::{CSSFloat, FONT_MEDIUM_PX, HasViewportPercentage, LocalToCss, NoViewportPercentage};
use super::computed::{self, ComputedValueAsSpecified, Context, ToComputedValue};
use url::Url;
pub use self::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingShape, Gradient};
pub use self::image::{GradientKind, HorizontalDirection, Image, LengthOrKeyword, LengthOrPercentageOrKeyword};
@ -1452,3 +1453,49 @@ impl ToCss for Opacity {
self.0.to_css(dest)
}
}
#[derive(PartialEq, Clone, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum UrlOrNone {
Url(Url, UrlExtraData),
None,
}
impl ComputedValueAsSpecified for UrlOrNone {}
impl NoViewportPercentage for UrlOrNone {}
impl ToCss for UrlOrNone {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
use values::LocalToCss;
match *self {
UrlOrNone::Url(ref url, _) => {
url.to_css(dest)
}
UrlOrNone::None => {
try!(dest.write_str("none"));
Ok(())
}
}
}
}
impl UrlOrNone {
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<UrlOrNone, ()> {
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
return Ok(UrlOrNone::None);
}
let url = context.parse_url(&*try!(input.expect_url()));
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(())
},
}
}
}