Auto merge of #22143 - emilio:gecko-sync, r=jdm

style: Sync changes from mozilla-central.

See each individual commit for details.

<!-- 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/22143)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2018-11-08 16:17:09 -05:00 committed by GitHub
commit bb2c5e387f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 242 additions and 205 deletions

View file

@ -366,16 +366,15 @@ impl<'a, 'b> ResolveGeneratedContentFragmentMutator<'a, 'b> {
if quotes.0.is_empty() {
return String::new();
}
let &(ref open_quote, ref close_quote) = if self.traversal.quote as usize >= quotes.0.len()
{
let pair = if self.traversal.quote as usize >= quotes.0.len() {
quotes.0.last().unwrap()
} else {
&quotes.0[self.traversal.quote as usize]
};
if close {
close_quote.to_string()
pair.closing.to_string()
} else {
open_quote.to_string()
pair.opening.to_string()
}
}
}

View file

@ -27,6 +27,7 @@ use gecko_bindings::structs::RawServoCssUrlData;
use gecko_bindings::structs::RawServoDeclarationBlock;
use gecko_bindings::structs::RawServoFontFaceRule;
use gecko_bindings::structs::RawServoMediaList;
use gecko_bindings::structs::RawServoQuotes;
use gecko_bindings::structs::RawServoStyleRule;
use gecko_bindings::structs::RawServoStyleSheetContents;
use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI, Strong};
@ -41,6 +42,7 @@ use stylesheets::keyframes_rule::Keyframe;
use stylesheets::{CounterStyleRule, CssRules, FontFaceRule, FontFeatureValuesRule};
use stylesheets::{DocumentRule, ImportRule, KeyframesRule, MediaRule, NamespaceRule, PageRule};
use stylesheets::{StyleRule, StylesheetContents, SupportsRule};
use values::computed::QuotePair;
macro_rules! impl_arc_ffi {
($servo_type:ty => $gecko_type:ty[$addref:ident, $release:ident]) => {
@ -115,6 +117,9 @@ impl_arc_ffi!(Locked<CounterStyleRule> => RawServoCounterStyleRule
impl_arc_ffi!(CssUrlData => RawServoCssUrlData
[Servo_CssUrlData_AddRef, Servo_CssUrlData_Release]);
impl_arc_ffi!(Box<[QuotePair]> => RawServoQuotes
[Servo_Quotes_AddRef, Servo_Quotes_Release]);
// RuleNode is a Arc-like type but it does not use Arc.
impl StrongRuleNode {

View file

@ -8,10 +8,9 @@ use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
use context::QuirksMode;
use dom::TElement;
use gecko_bindings::bindings::{self, RawServoStyleSet};
use gecko_bindings::structs::StyleSheet as DomStyleSheet;
use gecko_bindings::structs::{nsIDocument, StyleSheetInfo};
use gecko_bindings::structs::{
RawGeckoPresContextBorrowed, ServoStyleSetSizes, StyleSheet as DomStyleSheet,
};
use gecko_bindings::structs::{RawGeckoPresContextBorrowed, ServoStyleSetSizes};
use gecko_bindings::sugar::ownership::{HasArcFFI, HasBoxFFI, HasFFI, HasSimpleFFI};
use invalidation::media_queries::{MediaListKey, ToMediaListKey};
use malloc_size_of::MallocSizeOfOps;

View file

@ -3,29 +3,28 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* This file contains a helper macro includes all supported non-tree-structural
* pseudo-classes.
*
* FIXME: Find a way to autogenerate this file.
*
* Expected usage is as follows:
* ```
* macro_rules! pseudo_class_macro{
* ([$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*]) => {
* // do stuff
* }
* }
* apply_non_ts_list!(pseudo_class_macro)
* ```
*
* $gecko_type can be either "_" or an ident in Gecko's CSSPseudoClassType.
* $state can be either "_" or an expression of type ElementState. If present,
* the semantics are that the pseudo-class matches if any of the bits in
* $state are set on the element.
* $flags can be either "_" or an expression of type NonTSPseudoClassFlag,
* see selector_parser.rs for more details.
*/
* This file contains a helper macro includes all supported non-tree-structural
* pseudo-classes.
*
* FIXME: Find a way to autogenerate this file.
*
* Expected usage is as follows:
* ```
* macro_rules! pseudo_class_macro{
* ([$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*]) => {
* // do stuff
* }
* }
* apply_non_ts_list!(pseudo_class_macro)
* ```
*
* $gecko_type can be either "_" or an ident in Gecko's CSSPseudoClassType.
* $state can be either "_" or an expression of type ElementState. If present,
* the semantics are that the pseudo-class matches if any of the bits in
* $state are set on the element.
* $flags can be either "_" or an expression of type NonTSPseudoClassFlag,
* see selector_parser.rs for more details.
*/
macro_rules! apply_non_ts_list {
($apply_macro:ident) => {

View file

@ -17,13 +17,10 @@ use nsstring::{nsACString, nsCStr};
use std::cmp::max;
use values::computed::basic_shape::ShapeRadius as ComputedShapeRadius;
use values::computed::FlexBasis as ComputedFlexBasis;
use values::computed::{
Angle, ExtremumLength, Length, LengthOrPercentage, LengthOrPercentageOrAuto,
};
use values::computed::{Angle, ExtremumLength, Length, LengthOrPercentage};
use values::computed::{LengthOrPercentageOrAuto, Percentage};
use values::computed::{LengthOrPercentageOrNone, Number, NumberOrPercentage};
use values::computed::{
MaxLength as ComputedMaxLength, MozLength as ComputedMozLength, Percentage,
};
use values::computed::{MaxLength as ComputedMaxLength, MozLength as ComputedMozLength};
use values::computed::{NonNegativeLength, NonNegativeLengthOrPercentage, NonNegativeNumber};
use values::generics::basic_shape::ShapeRadius;
use values::generics::box_::Perspective;

View file

@ -44,9 +44,6 @@ use gecko_bindings::bindings::Gecko_MatchLang;
use gecko_bindings::bindings::Gecko_UnsetDirtyStyleAttr;
use gecko_bindings::bindings::Gecko_UpdateAnimations;
use gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentLWTheme};
use gecko_bindings::bindings::{
Gecko_GetLastChild, Gecko_GetNextStyleChild, Gecko_GetPreviousSibling,
};
use gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags};
use gecko_bindings::structs;
use gecko_bindings::structs::nsChangeHint;
@ -384,12 +381,12 @@ impl<'ln> TNode for GeckoNode<'ln> {
#[inline]
fn last_child(&self) -> Option<Self> {
unsafe { Gecko_GetLastChild(self.0).map(GeckoNode) }
unsafe { bindings::Gecko_GetLastChild(self.0).map(GeckoNode) }
}
#[inline]
fn prev_sibling(&self) -> Option<Self> {
unsafe { Gecko_GetPreviousSibling(self.0).map(GeckoNode) }
unsafe { bindings::Gecko_GetPreviousSibling(self.0).map(GeckoNode) }
}
#[inline]
@ -506,7 +503,7 @@ impl<'a> Iterator for GeckoChildrenIterator<'a> {
// however we can't express this easily with bindgen, and it would
// introduce functions with two input lifetimes into bindgen,
// which would be out of scope for elision.
Gecko_GetNextStyleChild(&mut *(it as *mut _)).map(GeckoNode)
bindings::Gecko_GetNextStyleChild(&mut *(it as *mut _)).map(GeckoNode)
},
}
}

View file

@ -211,6 +211,18 @@ impl<T: RefCounted> structs::RefPtr<T> {
}
impl<T> structs::RefPtr<T> {
/// Sets the contents to an `Arc<T>`, releasing the old value in `self` if
/// necessary.
pub fn set_arc<U>(&mut self, other: Arc<U>)
where
U: HasArcFFI<FFIType = T>,
{
unsafe {
U::release_opt(self.mRawPtr.as_ref());
}
self.set_arc_leaky(other);
}
/// Sets the contents to an Arc<T>
/// will leak existing contents
pub fn set_arc_leaky<U>(&mut self, other: Arc<U>)
@ -277,11 +289,6 @@ impl_threadsafe_refcount!(
bindings::Gecko_AddRefURLExtraDataArbitraryThread,
bindings::Gecko_ReleaseURLExtraDataArbitraryThread
);
impl_threadsafe_refcount!(
structs::nsStyleQuoteValues,
bindings::Gecko_AddRefQuoteValuesArbitraryThread,
bindings::Gecko_ReleaseQuoteValuesArbitraryThread
);
impl_threadsafe_refcount!(
structs::nsCSSValueSharedList,
bindings::Gecko_AddRefCSSValueSharedListArbitraryThread,

View file

@ -4180,23 +4180,11 @@ fn static_assert() {
}
pub fn set_quotes(&mut self, other: longhands::quotes::computed_value::T) {
use gecko_bindings::bindings::Gecko_NewStyleQuoteValues;
use gecko_bindings::sugar::refptr::UniqueRefPtr;
let mut refptr = unsafe {
UniqueRefPtr::from_addrefed(Gecko_NewStyleQuoteValues(other.0.len() as u32))
};
for (servo, gecko) in other.0.into_iter().zip(refptr.mQuotePairs.iter_mut()) {
gecko.first.assign_str(&servo.0);
gecko.second.assign_str(&servo.1);
}
self.gecko.mQuotes.set_move(refptr.get())
self.gecko.mQuotes.set_arc(other.0.clone());
}
pub fn copy_quotes_from(&mut self, other: &Self) {
unsafe { self.gecko.mQuotes.set(&other.gecko.mQuotes); }
self.set_quotes(other.clone_quotes());
}
pub fn reset_quotes(&mut self, other: &Self) {
@ -4204,17 +4192,13 @@ fn static_assert() {
}
pub fn clone_quotes(&self) -> longhands::quotes::computed_value::T {
unsafe {
let ref gecko_quote_values = *self.gecko.mQuotes.mRawPtr;
longhands::quotes::computed_value::T(
gecko_quote_values.mQuotePairs.iter().map(|gecko_pair| {
(
gecko_pair.first.to_string().into_boxed_str(),
gecko_pair.second.to_string().into_boxed_str(),
)
}).collect::<Vec<_>>().into_boxed_slice()
)
}
use gecko_bindings::sugar::ownership::HasArcFFI;
use values::computed::QuotePair;
let quote_pairs = unsafe { &*self.gecko.mQuotes.mRawPtr };
longhands::quotes::computed_value::T(
Box::<[QuotePair]>::as_arc(&quote_pairs).clone_arc()
)
}
#[allow(non_snake_case)]

View file

@ -2212,7 +2212,6 @@ impl ComputedScale {
Scale::None => (1.0, 1.0, 1.0),
Scale::Scale3D(sx, sy, sz) => (sx, sy, sz),
Scale::Scale(sx, sy) => (sx, sy, 1.),
Scale::ScaleX(sx) => (sx, 1., 1.),
}
}
}
@ -2224,21 +2223,38 @@ impl Animate for ComputedScale {
other: &Self,
procedure: Procedure,
) -> Result<Self, ()> {
let from = ComputedScale::resolve(self);
let to = ComputedScale::resolve(other);
// FIXME(emilio, bug 1464791): why does this do something different than
// Scale3D / TransformOperation::Scale3D?
if procedure == Procedure::Add {
// scale(x1,y1,z1)*scale(x2,y2,z2) = scale(x1*x2, y1*y2, z1*z2)
return Ok(Scale::Scale3D(from.0 * to.0, from.1 * to.1, from.2 * to.2));
match (self, other) {
(&Scale::None, &Scale::None) => Ok(Scale::None),
(&Scale::Scale3D(_, ..), _) | (_, &Scale::Scale3D(_, ..)) => {
let from = ComputedScale::resolve(self);
let to = ComputedScale::resolve(other);
// FIXME(emilio, bug 1464791): why does this do something different than
// Scale3D / TransformOperation::Scale3D?
if procedure == Procedure::Add {
// scale(x1,y1,z1)*scale(x2,y2,z2) = scale(x1*x2, y1*y2, z1*z2)
return Ok(Scale::Scale3D(from.0 * to.0, from.1 * to.1, from.2 * to.2));
}
Ok(Scale::Scale3D(
animate_multiplicative_factor(from.0, to.0, procedure)?,
animate_multiplicative_factor(from.1, to.1, procedure)?,
animate_multiplicative_factor(from.2, to.2, procedure)?,
))
},
(&Scale::Scale(_, ..), _) | (_, &Scale::Scale(_, ..)) => {
let from = ComputedScale::resolve(self);
let to = ComputedScale::resolve(other);
// FIXME(emilio, bug 1464791): why does this do something different than
// Scale / TransformOperation::Scale?
if procedure == Procedure::Add {
// scale(x1,y1)*scale(x2,y2) = scale(x1*x2, y1*y2)
return Ok(Scale::Scale(from.0 * to.0, from.1 * to.1));
}
Ok(Scale::Scale(
animate_multiplicative_factor(from.0, to.0, procedure)?,
animate_multiplicative_factor(from.1, to.1, procedure)?,
))
},
}
Ok(Scale::Scale3D(
animate_multiplicative_factor(from.0, to.0, procedure)?,
animate_multiplicative_factor(from.1, to.1, procedure)?,
animate_multiplicative_factor(from.2, to.2, procedure)?,
))
}
}

View file

@ -604,7 +604,6 @@ ${helpers.predefined_type(
${helpers.predefined_type(
"shape-image-threshold", "Opacity", "0.0",
products="gecko",
gecko_pref="layout.css.shape-outside.enabled",
animation_value_type="ComputedValue",
flags="APPLIES_TO_FIRST_LETTER",
spec="https://drafts.csswg.org/css-shapes/#shape-image-threshold-property",
@ -615,7 +614,6 @@ ${helpers.predefined_type(
"NonNegativeLengthOrPercentage",
"computed::NonNegativeLengthOrPercentage::zero()",
products="gecko",
gecko_pref="layout.css.shape-outside.enabled",
animation_value_type="NonNegativeLengthOrPercentage",
flags="APPLIES_TO_FIRST_LETTER",
spec="https://drafts.csswg.org/css-shapes/#shape-margin-property",
@ -627,7 +625,6 @@ ${helpers.predefined_type(
"generics::basic_shape::ShapeSource::None",
products="gecko",
boxed=True,
gecko_pref="layout.css.shape-outside.enabled",
animation_value_type="ComputedValue",
flags="APPLIES_TO_FIRST_LETTER",
spec="https://drafts.csswg.org/css-shapes/#shape-outside-property",

View file

@ -5,9 +5,8 @@
//! Animation implementation for various length-related types.
use super::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero};
use values::computed::length::{
CalcLengthOrPercentage, Length, LengthOrPercentageOrAuto, LengthOrPercentageOrNone,
};
use values::computed::length::{CalcLengthOrPercentage, Length};
use values::computed::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
use values::computed::MaxLength as ComputedMaxLength;
use values::computed::MozLength as ComputedMozLength;
use values::computed::Percentage;

View file

@ -17,7 +17,7 @@ use values::generics::length::{MaxLength as GenericMaxLength, MozLength as Gener
use values::generics::NonNegative;
use values::specified::length::ViewportPercentageLength;
use values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength};
use values::{specified, Auto, CSSFloat, Either, Normal};
use values::{specified, Auto, CSSFloat, Either, IsAuto, Normal};
pub use super::image::Image;
pub use values::specified::url::UrlOrNone;
@ -528,6 +528,13 @@ impl LengthOrPercentageOrAuto {
/// A wrapper of LengthOrPercentageOrAuto, whose value must be >= 0.
pub type NonNegativeLengthOrPercentageOrAuto = NonNegative<LengthOrPercentageOrAuto>;
impl IsAuto for NonNegativeLengthOrPercentageOrAuto {
#[inline]
fn is_auto(&self) -> bool {
*self == Self::auto()
}
}
impl NonNegativeLengthOrPercentageOrAuto {
/// `auto`
#[inline]

View file

@ -6,26 +6,30 @@
#[cfg(feature = "gecko")]
pub use values::specified::list::ListStyleType;
pub use values::specified::list::Quotes;
pub use values::specified::list::{QuotePair, Quotes};
use servo_arc::Arc;
lazy_static! {
static ref INITIAL_QUOTES: Arc<Box<[QuotePair]>> = Arc::new(
vec![
QuotePair {
opening: "\u{201c}".to_owned().into_boxed_str(),
closing: "\u{201d}".to_owned().into_boxed_str(),
},
QuotePair {
opening: "\u{2018}".to_owned().into_boxed_str(),
closing: "\u{2019}".to_owned().into_boxed_str(),
},
]
.into_boxed_slice()
);
}
impl Quotes {
/// Initial value for `quotes`.
///
/// FIXME(emilio): This should ideally not allocate.
#[inline]
pub fn get_initial_value() -> Quotes {
Quotes(
vec![
(
"\u{201c}".to_owned().into_boxed_str(),
"\u{201d}".to_owned().into_boxed_str(),
),
(
"\u{2018}".to_owned().into_boxed_str(),
"\u{2019}".to_owned().into_boxed_str(),
),
]
.into_boxed_slice(),
)
Quotes(INITIAL_QUOTES.clone())
}
}

View file

@ -37,13 +37,11 @@ pub use self::angle::Angle;
pub use self::background::{BackgroundRepeat, BackgroundSize};
pub use self::basic_shape::FillRule;
pub use self::border::{BorderCornerRadius, BorderRadius, BorderSpacing};
pub use self::border::{
BorderImageRepeat, BorderImageSideWidth, BorderImageSlice, BorderImageWidth,
};
pub use self::box_::{
AnimationIterationCount, AnimationName, Contain, Display, TransitionProperty,
};
pub use self::border::{BorderImageRepeat, BorderImageSideWidth};
pub use self::border::{BorderImageSlice, BorderImageWidth};
pub use self::box_::{AnimationIterationCount, AnimationName, Contain};
pub use self::box_::{Appearance, Clear, Float};
pub use self::box_::{Display, TransitionProperty};
pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize};
pub use self::box_::{ScrollSnapType, TouchAction, VerticalAlign, WillChange};
pub use self::color::{Color, ColorPropertyValue, RGBAColor};
@ -52,13 +50,11 @@ pub use self::counters::{Content, ContentItem, CounterIncrement, CounterReset};
pub use self::easing::TimingFunction;
pub use self::effects::{BoxShadow, Filter, SimpleShadow};
pub use self::flex::FlexBasis;
pub use self::font::{
FontFamily, FontLanguageOverride, FontStyle, FontVariantEastAsian, FontVariationSettings,
};
pub use self::font::{FontFamily, FontLanguageOverride, FontStyle};
pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumeric};
pub use self::font::{
FontSize, FontSizeAdjust, FontStretch, FontSynthesis, FontVariantAlternates, FontWeight,
};
pub use self::font::{FontSize, FontSizeAdjust, FontStretch, FontSynthesis};
pub use self::font::{FontVariantAlternates, FontWeight};
pub use self::font::{FontVariantEastAsian, FontVariationSettings};
pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom};
#[cfg(feature = "gecko")]
pub use self::gecko::ScrollSnapPoint;
@ -69,7 +65,7 @@ pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLe
pub use self::length::{NonNegativeLengthOrPercentage, NonNegativeLengthOrPercentageOrAuto};
#[cfg(feature = "gecko")]
pub use self::list::ListStyleType;
pub use self::list::Quotes;
pub use self::list::{QuotePair, Quotes};
pub use self::motion::OffsetPath;
pub use self::outline::OutlineStyle;
pub use self::percentage::{NonNegativePercentage, Percentage};
@ -81,9 +77,8 @@ pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind};
pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth};
pub use self::table::XSpan;
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, MozTabSize};
pub use self::text::{
TextAlign, TextEmphasisPosition, TextEmphasisStyle, TextOverflow, WordSpacing,
};
pub use self::text::{TextAlign, TextEmphasisPosition, TextEmphasisStyle};
pub use self::text::{TextOverflow, WordSpacing};
pub use self::time::Time;
pub use self::transform::{Rotate, Scale, Transform, TransformOperation};
pub use self::transform::{TransformOrigin, TransformStyle, Translate};

View file

@ -6,9 +6,8 @@
use values::computed::color::Color;
use values::computed::url::ComputedUrl;
use values::computed::{
LengthOrPercentage, NonNegativeLengthOrPercentage, NonNegativeNumber, Number, Opacity,
};
use values::computed::{LengthOrPercentage, NonNegativeLengthOrPercentage};
use values::computed::{NonNegativeNumber, Number, Opacity};
use values::generics::svg as generic;
use values::RGBA;

View file

@ -367,7 +367,6 @@ impl Scale {
pub fn to_transform_operation(&self) -> Option<TransformOperation> {
match *self {
generic::Scale::None => None,
generic::Scale::ScaleX(sx) => Some(generic::TransformOperation::ScaleX(sx)),
generic::Scale::Scale(sx, sy) => Some(generic::TransformOperation::Scale(sx, Some(sy))),
generic::Scale::Scale3D(sx, sy, sz) => {
Some(generic::TransformOperation::Scale3D(sx, sy, sz))
@ -378,8 +377,8 @@ impl Scale {
/// Convert Scale to TransformOperation.
pub fn from_transform_operation(operation: &TransformOperation) -> Scale {
match *operation {
generic::TransformOperation::ScaleX(sx) => generic::Scale::ScaleX(sx),
generic::TransformOperation::Scale(sx, Some(sy)) => generic::Scale::Scale(sx, sy),
generic::TransformOperation::Scale(sx, None) => generic::Scale::Scale(sx, sx),
generic::TransformOperation::Scale3D(sx, sy, sz) => generic::Scale::Scale3D(sx, sy, sz),
_ => unreachable!("Found unexpected value for scale"),
}

View file

@ -4,6 +4,10 @@
//! Generic types for CSS values related to backgrounds.
use std::fmt::{self, Write};
use style_traits::{CssWriter, ToCss};
use values::IsAuto;
/// A generic value for the `background-size` property.
#[derive(
Animate,
@ -17,7 +21,6 @@
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue,
ToCss,
)]
pub enum BackgroundSize<LengthOrPercentageOrAuto> {
/// `<width> <height>`
@ -34,3 +37,29 @@ pub enum BackgroundSize<LengthOrPercentageOrAuto> {
#[animation(error)]
Contain,
}
impl<LengthOrPercentageOrAuto> ToCss for BackgroundSize<LengthOrPercentageOrAuto>
where
LengthOrPercentageOrAuto: ToCss + IsAuto,
{
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
match self {
BackgroundSize::Explicit { width, height } => {
width.to_css(dest)?;
// NOTE(emilio): We should probably simplify all these in case
// `width == `height`, but all other browsers agree on only
// special-casing `auto`.
if !width.is_auto() || !height.is_auto() {
dest.write_str(" ")?;
height.to_css(dest)?;
}
Ok(())
},
BackgroundSize::Cover => dest.write_str("cover"),
BackgroundSize::Contain => dest.write_str("contain"),
}
}
}

View file

@ -7,6 +7,8 @@
use app_units::Au;
use euclid::{self, Rect, Transform3D};
use num_traits::Zero;
use std::fmt::{self, Write};
use style_traits::{CssWriter, ToCss};
use values::computed::length::Length as ComputedLength;
use values::computed::length::LengthOrPercentage as ComputedLengthOrPercentage;
use values::specified::angle::Angle as SpecifiedAngle;
@ -560,7 +562,6 @@ pub enum Rotate<Number, Angle> {
SpecifiedValueInfo,
ToAnimatedZero,
ToComputedValue,
ToCss,
)]
/// A value of the `Scale` property
///
@ -568,14 +569,38 @@ pub enum Rotate<Number, Angle> {
pub enum Scale<Number> {
/// 'none'
None,
/// '<number>'
ScaleX(Number),
/// '<number>{2}'
/// '<number>{1,2}'
Scale(Number, Number),
/// '<number>{3}'
Scale3D(Number, Number, Number),
}
impl<Number: ToCss + PartialEq> ToCss for Scale<Number> {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: fmt::Write,
{
match *self {
Scale::None => dest.write_str("none"),
Scale::Scale(ref x, ref y) => {
x.to_css(dest)?;
if x != y {
dest.write_char(' ')?;
y.to_css(dest)?;
}
Ok(())
},
Scale::Scale3D(ref x, ref y, ref z) => {
x.to_css(dest)?;
dest.write_char(' ')?;
y.to_css(dest)?;
dest.write_char(' ')?;
z.to_css(dest)
},
}
}
}
#[derive(
Clone,
ComputeSquaredDistance,

View file

@ -8,9 +8,8 @@
#![deny(missing_docs)]
pub use cssparser::{
serialize_identifier, serialize_name, CowRcStr, Parser, SourceLocation, Token, RGBA,
};
pub use cssparser::{serialize_identifier, serialize_name, CowRcStr, Parser};
pub use cssparser::{SourceLocation, Token, RGBA};
use parser::{Parse, ParserContext};
use selectors::parser::SelectorParseErrorKind;
use std::fmt::{self, Debug, Write};
@ -243,6 +242,13 @@ impl KeyframesName {
impl Eq for KeyframesName {}
/// A trait that returns whether a given type is the `auto` value or not. So far
/// only needed for background-size serialization, which special-cases `auto`.
pub trait IsAuto {
/// Returns whether the value is the `auto` value.
fn is_auto(&self) -> bool;
}
impl PartialEq for KeyframesName {
fn eq(&self, other: &Self) -> bool {
self.as_atom() == other.as_atom()

View file

@ -10,9 +10,8 @@ use parser::{Parse, ParserContext};
use properties::{LonghandId, PropertyDeclarationId, PropertyFlags, PropertyId, ShorthandId};
use selectors::parser::SelectorParseErrorKind;
use std::fmt::{self, Write};
use style_traits::{
CssWriter, KeywordsCollectFn, ParseError, SpecifiedValueInfo, StyleParseErrorKind, ToCss,
};
use style_traits::{CssWriter, KeywordsCollectFn, ParseError};
use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss};
use values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount;
use values::generics::box_::Perspective as GenericPerspective;
use values::generics::box_::VerticalAlign as GenericVerticalAlign;

View file

@ -24,9 +24,8 @@ use values::generics::font::{self as generics, FeatureTagValue, FontSettings, Fo
use values::generics::font::{KeywordSize, VariationValue};
use values::generics::NonNegative;
use values::specified::length::{FontBaseSize, AU_PER_PT, AU_PER_PX};
use values::specified::{
AllowQuirks, Angle, Integer, LengthOrPercentage, NoCalcLength, Number, Percentage,
};
use values::specified::{AllowQuirks, Angle, Integer, LengthOrPercentage};
use values::specified::{NoCalcLength, Number, Percentage};
use values::CustomIdent;
use Atom;

View file

@ -20,7 +20,7 @@ use values::computed::{self, CSSPixelLength, Context, ExtremumLength};
use values::generics::length::{MaxLength as GenericMaxLength, MozLength as GenericMozLength};
use values::generics::NonNegative;
use values::specified::calc::CalcNode;
use values::{Auto, CSSFloat, Either, Normal};
use values::{Auto, CSSFloat, Either, IsAuto, Normal};
pub use super::image::{ColorStop, EndingShape as GradientEndingShape, Gradient};
pub use super::image::{GradientKind, Image};
@ -980,6 +980,13 @@ impl Parse for LengthOrPercentageOrAuto {
/// A wrapper of LengthOrPercentageOrAuto, whose value must be >= 0.
pub type NonNegativeLengthOrPercentageOrAuto = NonNegative<LengthOrPercentageOrAuto>;
impl IsAuto for NonNegativeLengthOrPercentageOrAuto {
#[inline]
fn is_auto(&self) -> bool {
*self == Self::auto()
}
}
impl NonNegativeLengthOrPercentageOrAuto {
/// 0
#[inline]

View file

@ -6,8 +6,8 @@
use cssparser::{Parser, Token};
use parser::{Parse, ParserContext};
use std::fmt::{self, Write};
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
use servo_arc::Arc;
use style_traits::{ParseError, StyleParseErrorKind};
#[cfg(feature = "gecko")]
use values::generics::CounterStyleOrNone;
#[cfg(feature = "gecko")]
@ -73,41 +73,24 @@ impl Parse for ListStyleType {
}
}
/// Specified and computed `quote` property.
///
/// FIXME(emilio): It's a shame that this allocates all the time it's computed,
/// probably should just be refcounted.
/// FIXME This can probably derive ToCss.
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)]
pub struct Quotes(#[css(if_empty = "none")] pub Box<[(Box<str>, Box<str>)]>);
/// A quote pair.
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)]
pub struct QuotePair {
/// The opening quote.
pub opening: Box<str>,
impl ToCss for Quotes {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
let mut iter = self.0.iter();
match iter.next() {
Some(&(ref l, ref r)) => {
l.to_css(dest)?;
dest.write_char(' ')?;
r.to_css(dest)?;
},
None => return dest.write_str("none"),
}
for &(ref l, ref r) in iter {
dest.write_char(' ')?;
l.to_css(dest)?;
dest.write_char(' ')?;
r.to_css(dest)?;
}
Ok(())
}
/// The closing quote.
pub closing: Box<str>,
}
/// Specified and computed `quotes` property.
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)]
pub struct Quotes(
#[css(iterable, if_empty = "none")]
#[ignore_malloc_size_of = "Arc"]
pub Arc<Box<[QuotePair]>>,
);
impl Parse for Quotes {
fn parse<'i, 't>(
_: &ParserContext,
@ -117,24 +100,24 @@ impl Parse for Quotes {
.try(|input| input.expect_ident_matching("none"))
.is_ok()
{
return Ok(Quotes(Vec::new().into_boxed_slice()));
return Ok(Quotes(Arc::new(Box::new([]))));
}
let mut quotes = Vec::new();
loop {
let location = input.current_source_location();
let first = match input.next() {
let opening = match input.next() {
Ok(&Token::QuotedString(ref value)) => value.as_ref().to_owned().into_boxed_str(),
Ok(t) => return Err(location.new_unexpected_token_error(t.clone())),
Err(_) => break,
};
let second = input.expect_string()?.as_ref().to_owned().into_boxed_str();
quotes.push((first, second))
let closing = input.expect_string()?.as_ref().to_owned().into_boxed_str();
quotes.push(QuotePair { opening, closing });
}
if !quotes.is_empty() {
Ok(Quotes(quotes.into_boxed_slice()))
Ok(Quotes(Arc::new(quotes.into_boxed_slice())))
} else {
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
}

View file

@ -43,13 +43,11 @@ pub use self::counters::{Content, ContentItem, CounterIncrement, CounterReset};
pub use self::easing::TimingFunction;
pub use self::effects::{BoxShadow, Filter, SimpleShadow};
pub use self::flex::FlexBasis;
pub use self::font::{
FontFamily, FontLanguageOverride, FontStyle, FontVariantEastAsian, FontVariationSettings,
};
pub use self::font::{FontFamily, FontLanguageOverride, FontStyle};
pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumeric};
pub use self::font::{
FontSize, FontSizeAdjust, FontStretch, FontSynthesis, FontVariantAlternates, FontWeight,
};
pub use self::font::{FontSize, FontSizeAdjust, FontStretch, FontSynthesis};
pub use self::font::{FontVariantAlternates, FontWeight};
pub use self::font::{FontVariantEastAsian, FontVariationSettings};
pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom};
#[cfg(feature = "gecko")]
pub use self::gecko::ScrollSnapPoint;
@ -63,7 +61,7 @@ pub use self::length::{NoCalcLength, ViewportPercentageLength};
pub use self::length::{NonNegativeLengthOrPercentage, NonNegativeLengthOrPercentageOrAuto};
#[cfg(feature = "gecko")]
pub use self::list::ListStyleType;
pub use self::list::Quotes;
pub use self::list::{QuotePair, Quotes};
pub use self::motion::OffsetPath;
pub use self::outline::OutlineStyle;
pub use self::percentage::Percentage;

View file

@ -423,6 +423,6 @@ impl Parse for Scale {
}
// 'scale: <number>'
Ok(generic::Scale::ScaleX(sx))
Ok(generic::Scale::Scale(sx, sx))
}
}

View file

@ -1,7 +1,5 @@
[background-331.html]
type: testharness
[background_initial_size]
expected: FAIL
[background_initial_position]
expected: FAIL

View file

@ -1,7 +1,5 @@
[background-333.html]
type: testharness
[background_specified_color_size]
expected: FAIL
[background_specified_color_position]
expected: FAIL

View file

@ -1,10 +1,5 @@
[background-size-001.html]
type: testharness
[background-size_initial]
expected: FAIL
[background-size_auto]
expected: FAIL
[background-size_length_zero]
expected: FAIL
@ -27,6 +22,3 @@
[background-size_percentage_max]
expected: FAIL
[background-size_auto_auto]
expected: FAIL