mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Auto merge of #22930 - emilio:gecko-sync, r=emilio
style: Sync changes from mozilla-central. See individual commits 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/22930) <!-- Reviewable:end -->
This commit is contained in:
commit
427003210b
72 changed files with 846 additions and 1175 deletions
|
@ -2,8 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// FIXME(rust-lang/rust#26264): Remove GenericBackgroundSize.
|
||||
|
||||
use crate::display_list::border;
|
||||
use app_units::Au;
|
||||
use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
|
||||
|
@ -12,7 +10,6 @@ use style::computed_values::background_clip::single_value::T as BackgroundClip;
|
|||
use style::computed_values::background_origin::single_value::T as BackgroundOrigin;
|
||||
use style::properties::style_structs::Background;
|
||||
use style::values::computed::{BackgroundSize, NonNegativeLengthPercentageOrAuto};
|
||||
use style::values::generics::background::BackgroundSize as GenericBackgroundSize;
|
||||
use style::values::specified::background::BackgroundRepeatKeyword;
|
||||
use webrender_api::BorderRadius;
|
||||
|
||||
|
@ -56,8 +53,8 @@ fn compute_background_image_size(
|
|||
) -> Size2D<Au> {
|
||||
match intrinsic_size {
|
||||
None => match bg_size {
|
||||
GenericBackgroundSize::Cover | GenericBackgroundSize::Contain => bounds_size,
|
||||
GenericBackgroundSize::Explicit { width, height } => Size2D::new(
|
||||
BackgroundSize::Cover | BackgroundSize::Contain => bounds_size,
|
||||
BackgroundSize::ExplicitSize { width, height } => Size2D::new(
|
||||
width
|
||||
.to_used_value(bounds_size.width)
|
||||
.unwrap_or(bounds_size.width),
|
||||
|
@ -73,20 +70,16 @@ fn compute_background_image_size(
|
|||
let bounds_aspect_ratio =
|
||||
bounds_size.width.to_f32_px() / bounds_size.height.to_f32_px();
|
||||
match (bg_size, image_aspect_ratio < bounds_aspect_ratio) {
|
||||
(GenericBackgroundSize::Contain, false) | (GenericBackgroundSize::Cover, true) => {
|
||||
Size2D::new(
|
||||
bounds_size.width,
|
||||
bounds_size.width.scale_by(image_aspect_ratio.recip()),
|
||||
)
|
||||
},
|
||||
(GenericBackgroundSize::Contain, true) | (GenericBackgroundSize::Cover, false) => {
|
||||
Size2D::new(
|
||||
bounds_size.height.scale_by(image_aspect_ratio),
|
||||
bounds_size.height,
|
||||
)
|
||||
},
|
||||
(BackgroundSize::Contain, false) | (BackgroundSize::Cover, true) => Size2D::new(
|
||||
bounds_size.width,
|
||||
bounds_size.width.scale_by(image_aspect_ratio.recip()),
|
||||
),
|
||||
(BackgroundSize::Contain, true) | (BackgroundSize::Cover, false) => Size2D::new(
|
||||
bounds_size.height.scale_by(image_aspect_ratio),
|
||||
bounds_size.height,
|
||||
),
|
||||
(
|
||||
GenericBackgroundSize::Explicit {
|
||||
BackgroundSize::ExplicitSize {
|
||||
width,
|
||||
height: NonNegativeLengthPercentageOrAuto::Auto,
|
||||
},
|
||||
|
@ -98,7 +91,7 @@ fn compute_background_image_size(
|
|||
Size2D::new(width, width.scale_by(image_aspect_ratio.recip()))
|
||||
},
|
||||
(
|
||||
GenericBackgroundSize::Explicit {
|
||||
BackgroundSize::ExplicitSize {
|
||||
width: NonNegativeLengthPercentageOrAuto::Auto,
|
||||
height,
|
||||
},
|
||||
|
@ -109,7 +102,7 @@ fn compute_background_image_size(
|
|||
.unwrap_or(own_size.height);
|
||||
Size2D::new(height.scale_by(image_aspect_ratio), height)
|
||||
},
|
||||
(GenericBackgroundSize::Explicit { width, height }, _) => Size2D::new(
|
||||
(BackgroundSize::ExplicitSize { width, height }, _) => Size2D::new(
|
||||
width
|
||||
.to_used_value(bounds_size.width)
|
||||
.unwrap_or(own_size.width),
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// FIXME(rust-lang/rust#26264): Remove GenericBorderImageSideWidth.
|
||||
|
||||
use crate::display_list::ToLayout;
|
||||
use app_units::Au;
|
||||
use euclid::{Rect, SideOffsets2D, Size2D};
|
||||
|
@ -11,11 +9,9 @@ use style::computed_values::border_image_outset::T as BorderImageOutset;
|
|||
use style::properties::style_structs::Border;
|
||||
use style::values::computed::NumberOrPercentage;
|
||||
use style::values::computed::{BorderCornerRadius, BorderImageWidth};
|
||||
use style::values::computed::{BorderImageSideWidth, LengthOrNumber};
|
||||
use style::values::generics::border::BorderImageSideWidth as GenericBorderImageSideWidth;
|
||||
use style::values::computed::{BorderImageSideWidth, NonNegativeLengthOrNumber};
|
||||
use style::values::generics::rect::Rect as StyleRect;
|
||||
use style::values::generics::NonNegative;
|
||||
use style::values::Either;
|
||||
use webrender_api::{BorderRadius, BorderSide, BorderStyle, ColorF};
|
||||
use webrender_api::{LayoutSideOffsets, LayoutSize, NormalBorder};
|
||||
|
||||
|
@ -140,10 +136,10 @@ pub fn simple(color: ColorF, style: BorderStyle) -> NormalBorder {
|
|||
}
|
||||
}
|
||||
|
||||
fn side_image_outset(outset: LengthOrNumber, border_width: Au) -> Au {
|
||||
fn side_image_outset(outset: NonNegativeLengthOrNumber, border_width: Au) -> Au {
|
||||
match outset {
|
||||
Either::First(length) => length.into(),
|
||||
Either::Second(factor) => border_width.scale_by(factor),
|
||||
NonNegativeLengthOrNumber::Length(length) => length.into(),
|
||||
NonNegativeLengthOrNumber::Number(factor) => border_width.scale_by(factor.0),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,9 +159,9 @@ fn side_image_width(
|
|||
total_length: Au,
|
||||
) -> f32 {
|
||||
match border_image_width {
|
||||
GenericBorderImageSideWidth::Length(v) => v.to_used_value(total_length).to_f32_px(),
|
||||
GenericBorderImageSideWidth::Number(x) => border_width * x.0,
|
||||
GenericBorderImageSideWidth::Auto => border_width,
|
||||
BorderImageSideWidth::Length(v) => v.to_used_value(total_length).to_f32_px(),
|
||||
BorderImageSideWidth::Number(x) => border_width * x.0,
|
||||
BorderImageSideWidth::Auto => border_width,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -763,7 +763,7 @@ impl Fragment {
|
|||
let background_size =
|
||||
get_cyclic(&style.get_background().background_size.0, i).clone();
|
||||
let size = match background_size {
|
||||
BackgroundSize::Explicit { width, height } => Size2D::new(
|
||||
BackgroundSize::ExplicitSize { width, height } => Size2D::new(
|
||||
width
|
||||
.to_used_value(bounding_box_size.width)
|
||||
.unwrap_or(bounding_box_size.width),
|
||||
|
|
|
@ -30,7 +30,6 @@ use style::properties::ComputedValues;
|
|||
use style::servo::restyle_damage::ServoRestyleDamage;
|
||||
use style::values::computed::flex::FlexBasis;
|
||||
use style::values::computed::{MaxSize, Size};
|
||||
use style::values::generics::flex::FlexBasis as GenericFlexBasis;
|
||||
|
||||
/// The size of an axis. May be a specified size, a min/max
|
||||
/// constraint, or an unlimited size
|
||||
|
@ -61,8 +60,8 @@ impl AxisSize {
|
|||
/// is definite after flex size resolving.
|
||||
fn from_flex_basis(flex_basis: FlexBasis, main_length: Size, containing_length: Au) -> MaybeAuto {
|
||||
let width = match flex_basis {
|
||||
GenericFlexBasis::Content => return MaybeAuto::Auto,
|
||||
GenericFlexBasis::Width(width) => width,
|
||||
FlexBasis::Content => return MaybeAuto::Auto,
|
||||
FlexBasis::Size(width) => width,
|
||||
};
|
||||
|
||||
let width = match width {
|
||||
|
|
|
@ -57,6 +57,7 @@ include = [
|
|||
"CursorKind",
|
||||
"Display",
|
||||
"DisplayMode",
|
||||
"PrefersColorScheme",
|
||||
"ExtremumLength",
|
||||
"FillRule",
|
||||
"FontDisplay",
|
||||
|
@ -69,6 +70,7 @@ include = [
|
|||
"UserSelect",
|
||||
"Float",
|
||||
"OverscrollBehavior",
|
||||
"ScrollSnapAlign",
|
||||
"ScrollSnapType",
|
||||
"OverflowAnchor",
|
||||
"OverflowClipBox",
|
||||
|
@ -77,32 +79,97 @@ include = [
|
|||
"LengthPercentage",
|
||||
"NonNegativeLengthPercentage",
|
||||
"LengthPercentageOrAuto",
|
||||
"NonNegativeLengthPercentageOrAuto",
|
||||
"Rect",
|
||||
"IntersectionObserverRootMargin",
|
||||
"Size",
|
||||
"MaxSize",
|
||||
"FlexBasis",
|
||||
"Position",
|
||||
"BackgroundSize",
|
||||
"BorderImageSlice",
|
||||
"NonNegativeLengthOrNumberRect",
|
||||
"Perspective",
|
||||
"ZIndex",
|
||||
"TransformOrigin",
|
||||
]
|
||||
item_types = ["enums", "structs", "typedefs"]
|
||||
|
||||
[export.body]
|
||||
"CSSPixelLength" = """
|
||||
inline nscoord ToAppUnits() const;
|
||||
"""
|
||||
|
||||
"LengthPercentage" = """
|
||||
// Defined in nsStyleCoord.h
|
||||
static constexpr inline StyleLengthPercentage Zero();
|
||||
static inline StyleLengthPercentage FromAppUnits(nscoord);
|
||||
static inline StyleLengthPercentage FromPixels(CSSCoord);
|
||||
static inline StyleLengthPercentage FromPercentage(float);
|
||||
inline CSSCoord LengthInCSSPixels() const;
|
||||
inline float Percentage() const;
|
||||
inline bool HasPercent() const;
|
||||
inline bool ConvertsToLength() const;
|
||||
inline nscoord ToLength() const;
|
||||
inline bool ConvertsToPercentage() const;
|
||||
inline bool HasLengthAndPercentage() const;
|
||||
inline float ToPercentage() const;
|
||||
inline CSSCoord LengthInCSSPixels() const;
|
||||
inline float Percentage() const;
|
||||
inline CSSCoord ResolveToCSSPixels(CSSCoord aPercentageBasisInCSSPixels) const;
|
||||
template<typename T> inline CSSCoord ResolveToCSSPixelsWith(T aPercentageGetter) const;
|
||||
template<typename T, typename U>
|
||||
inline nscoord Resolve(T aPercentageGetter, U aPercentRoundingFunction) const;
|
||||
template<typename T>
|
||||
inline nscoord Resolve(nscoord aPercentageBasis, T aPercentRoundingFunction) const;
|
||||
template<typename T> inline nscoord Resolve(T aPercentageGetter) const;
|
||||
inline nscoord Resolve(nscoord aPercentageBasis) const;
|
||||
template<typename T> inline nscoord ResolveWith(T aPercentageGetter) const;
|
||||
"""
|
||||
|
||||
"GenericLengthPercentageOrAuto" = """
|
||||
inline const StyleLengthPercentage& AsLengthPercentage() const;
|
||||
inline bool HasPercent() const;
|
||||
inline bool ConvertsToLength() const;
|
||||
inline nscoord ToLength() const;
|
||||
inline bool ConvertsToPercentage() const;
|
||||
inline float ToPercentage() const;
|
||||
inline bool HasPercent() const;
|
||||
inline bool HasLengthAndPercentage() const;
|
||||
"""
|
||||
|
||||
"GenericSize" = """
|
||||
inline const StyleLengthPercentage& AsLengthPercentage() const;
|
||||
inline StyleExtremumLength AsExtremumLength() const;
|
||||
inline bool ConvertsToLength() const;
|
||||
inline nscoord ToLength() const;
|
||||
inline bool ConvertsToPercentage() const;
|
||||
inline float ToPercentage() const;
|
||||
inline bool HasPercent() const;
|
||||
inline bool HasLengthAndPercentage() const;
|
||||
inline bool BehavesLikeInitialValueOnBlockAxis() const;
|
||||
"""
|
||||
|
||||
"GenericFlexBasis" = """
|
||||
inline bool IsAuto() const;
|
||||
inline const StyleSize& AsSize() const;
|
||||
"""
|
||||
|
||||
"GenericMaxSize" = """
|
||||
inline const StyleLengthPercentage& AsLengthPercentage() const;
|
||||
inline StyleExtremumLength AsExtremumLength() const;
|
||||
inline bool ConvertsToLength() const;
|
||||
inline nscoord ToLength() const;
|
||||
inline bool ConvertsToPercentage() const;
|
||||
inline float ToPercentage() const;
|
||||
inline bool HasPercent() const;
|
||||
inline bool HasLengthAndPercentage() const;
|
||||
inline bool BehavesLikeInitialValueOnBlockAxis() const;
|
||||
"""
|
||||
|
||||
"GenericPosition" = """
|
||||
inline bool DependsOnPositioningAreaSize() const;
|
||||
static inline StyleGenericPosition FromPercentage(float);
|
||||
"""
|
||||
|
||||
"GenericBackgroundSize" = """
|
||||
bool IsInitialValue() const;
|
||||
"""
|
||||
|
||||
"Rect" = """
|
||||
|
|
|
@ -23,13 +23,10 @@ use crate::values::computed::url::ComputedImageUrl;
|
|||
use crate::values::computed::{Angle, Gradient, Image};
|
||||
use crate::values::computed::{Integer, LengthPercentage};
|
||||
use crate::values::computed::{Length, Percentage, TextAlign};
|
||||
use crate::values::computed::{LengthPercentageOrAuto, NonNegativeLengthPercentageOrAuto};
|
||||
use crate::values::generics::box_::VerticalAlign;
|
||||
use crate::values::generics::grid::{TrackListValue, TrackSize};
|
||||
use crate::values::generics::image::{CompatMode, GradientItem, Image as GenericImage};
|
||||
use crate::values::generics::length::LengthPercentageOrAuto as GenericLengthPercentageOrAuto;
|
||||
use crate::values::generics::rect::Rect;
|
||||
use crate::values::generics::NonNegative;
|
||||
use app_units::Au;
|
||||
use std::f32::consts::PI;
|
||||
use style_traits::values::specified::AllowedNumericType;
|
||||
|
@ -62,42 +59,6 @@ impl From<nsStyleCoord_CalcValue> for LengthPercentage {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl NonNegativeLengthPercentageOrAuto {
|
||||
/// Convert this value in an appropriate `nsStyleCoord::CalcValue`.
|
||||
pub fn to_calc_value(&self) -> Option<nsStyleCoord_CalcValue> {
|
||||
match *self {
|
||||
GenericLengthPercentageOrAuto::LengthPercentage(ref len) => Some(From::from(len.0)),
|
||||
GenericLengthPercentageOrAuto::Auto => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<nsStyleCoord_CalcValue> for LengthPercentageOrAuto {
|
||||
fn from(other: nsStyleCoord_CalcValue) -> LengthPercentageOrAuto {
|
||||
GenericLengthPercentageOrAuto::LengthPercentage(LengthPercentage::from(other))
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(emilio): A lot of these impl From should probably become explicit or
|
||||
// disappear as we move more stuff to cbindgen.
|
||||
impl From<nsStyleCoord_CalcValue> for NonNegativeLengthPercentageOrAuto {
|
||||
fn from(other: nsStyleCoord_CalcValue) -> Self {
|
||||
GenericLengthPercentageOrAuto::LengthPercentage(NonNegative(
|
||||
LengthPercentage::with_clamping_mode(
|
||||
Au(other.mLength).into(),
|
||||
if other.mHasPercent {
|
||||
Some(Percentage(other.mPercent))
|
||||
} else {
|
||||
None
|
||||
},
|
||||
AllowedNumericType::NonNegative,
|
||||
/* was_calc = */ true,
|
||||
),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Angle> for CoordDataValue {
|
||||
fn from(reference: Angle) -> Self {
|
||||
CoordDataValue::Degree(reference.degrees())
|
||||
|
@ -614,7 +575,6 @@ pub mod basic_shape {
|
|||
//! Conversions from and to CSS shape representations.
|
||||
|
||||
use crate::gecko::values::GeckoStyleCoordConvertible;
|
||||
use crate::gecko_bindings::structs;
|
||||
use crate::gecko_bindings::structs::{nsStyleCoord, nsStyleCorners};
|
||||
use crate::gecko_bindings::structs::{StyleBasicShape, StyleBasicShapeType};
|
||||
use crate::gecko_bindings::structs::{
|
||||
|
@ -628,7 +588,6 @@ pub mod basic_shape {
|
|||
use crate::values::computed::border::{BorderCornerRadius, BorderRadius};
|
||||
use crate::values::computed::length::LengthPercentage;
|
||||
use crate::values::computed::motion::OffsetPath;
|
||||
use crate::values::computed::position;
|
||||
use crate::values::computed::url::ComputedUrl;
|
||||
use crate::values::generics::basic_shape::{
|
||||
BasicShape as GenericBasicShape, InsetRect, Polygon,
|
||||
|
@ -759,12 +718,12 @@ pub mod basic_shape {
|
|||
},
|
||||
StyleBasicShapeType::Circle => GenericBasicShape::Circle(Circle {
|
||||
radius: (&other.mCoordinates[0]).into(),
|
||||
position: (&other.mPosition).into(),
|
||||
position: other.mPosition,
|
||||
}),
|
||||
StyleBasicShapeType::Ellipse => GenericBasicShape::Ellipse(Ellipse {
|
||||
semiaxis_x: (&other.mCoordinates[0]).into(),
|
||||
semiaxis_y: (&other.mCoordinates[1]).into(),
|
||||
position: (&other.mPosition).into(),
|
||||
position: other.mPosition,
|
||||
}),
|
||||
StyleBasicShapeType::Polygon => {
|
||||
let mut coords = Vec::with_capacity(other.mCoordinates.len() / 2);
|
||||
|
@ -852,17 +811,6 @@ pub mod basic_shape {
|
|||
}
|
||||
}
|
||||
|
||||
// Can't be a From impl since we need to set an existing
|
||||
// Position, not create a new one
|
||||
impl From<position::Position> for structs::Position {
|
||||
fn from(other: position::Position) -> Self {
|
||||
structs::Position {
|
||||
mXPosition: other.horizontal.into(),
|
||||
mYPosition: other.vertical.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a nsStyleCoord> for ShapeRadius {
|
||||
fn from(other: &'a nsStyleCoord) -> Self {
|
||||
let other = other.borrow();
|
||||
|
@ -871,15 +819,6 @@ pub mod basic_shape {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a structs::Position> for position::Position {
|
||||
fn from(other: &'a structs::Position) -> Self {
|
||||
position::Position {
|
||||
horizontal: other.mXPosition.into(),
|
||||
vertical: other.mYPosition.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ShapeBox> for StyleGeometryBox {
|
||||
fn from(reference: ShapeBox) -> Self {
|
||||
use crate::gecko_bindings::structs::StyleGeometryBox::*;
|
||||
|
|
|
@ -280,6 +280,16 @@ enum PrefersReducedMotion {
|
|||
Reduce,
|
||||
}
|
||||
|
||||
/// Values for the prefers-color-scheme media feature.
|
||||
#[derive(Clone, Copy, Debug, FromPrimitive, Parse, PartialEq, ToCss)]
|
||||
#[repr(u8)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum PrefersColorScheme {
|
||||
Light,
|
||||
Dark,
|
||||
NoPreference,
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/mediaqueries-5/#prefers-reduced-motion
|
||||
fn eval_prefers_reduced_motion(device: &Device, query_value: Option<PrefersReducedMotion>) -> bool {
|
||||
let prefers_reduced =
|
||||
|
@ -348,6 +358,16 @@ fn eval_overflow_inline(device: &Device, query_value: Option<OverflowInline>) ->
|
|||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme
|
||||
fn eval_prefers_color_scheme(device: &Device, query_value: Option<PrefersColorScheme>) -> bool {
|
||||
let prefers_color_scheme =
|
||||
unsafe { bindings::Gecko_MediaFeatures_PrefersColorScheme(device.document()) };
|
||||
match query_value {
|
||||
Some(v) => prefers_color_scheme == v,
|
||||
None => prefers_color_scheme != PrefersColorScheme::NoPreference,
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/mediaqueries-4/#mf-interaction
|
||||
bitflags! {
|
||||
struct PointerCapabilities: u8 {
|
||||
|
@ -441,7 +461,7 @@ fn eval_moz_is_glyph(
|
|||
query_value: Option<bool>,
|
||||
_: Option<RangeOrOperator>,
|
||||
) -> bool {
|
||||
let is_glyph = unsafe { (*device.document()).mIsSVGGlyphsDocument() };
|
||||
let is_glyph = device.document().mIsSVGGlyphsDocument();
|
||||
query_value.map_or(is_glyph, |v| v == is_glyph)
|
||||
}
|
||||
|
||||
|
@ -526,7 +546,7 @@ lazy_static! {
|
|||
/// to support new types in these entries and (2) ensuring that either
|
||||
/// nsPresContext::MediaFeatureValuesChanged is called when the value that
|
||||
/// would be returned by the evaluator function could change.
|
||||
pub static ref MEDIA_FEATURES: [MediaFeatureDescription; 52] = [
|
||||
pub static ref MEDIA_FEATURES: [MediaFeatureDescription; 53] = [
|
||||
feature!(
|
||||
atom!("width"),
|
||||
AllowsRanges::Yes,
|
||||
|
@ -657,6 +677,12 @@ lazy_static! {
|
|||
keyword_evaluator!(eval_overflow_inline, OverflowInline),
|
||||
ParsingRequirements::empty(),
|
||||
),
|
||||
feature!(
|
||||
atom!("prefers-color-scheme"),
|
||||
AllowsRanges::No,
|
||||
keyword_evaluator!(eval_prefers_color_scheme, PrefersColorScheme),
|
||||
ParsingRequirements::empty(),
|
||||
),
|
||||
feature!(
|
||||
atom!("pointer"),
|
||||
AllowsRanges::No,
|
||||
|
|
|
@ -85,7 +85,9 @@ impl Device {
|
|||
assert!(!pres_context.is_null());
|
||||
Device {
|
||||
pres_context,
|
||||
default_values: ComputedValues::default_values(unsafe { &*pres_context }),
|
||||
default_values: ComputedValues::default_values(unsafe {
|
||||
&*(*pres_context).mDocument.mRawPtr
|
||||
}),
|
||||
// FIXME(bz): Seems dubious?
|
||||
root_font_size: AtomicIsize::new(FontSize::medium().size().0 as isize),
|
||||
body_text_color: AtomicUsize::new(unsafe { &*pres_context }.mDefaultColor as usize),
|
||||
|
@ -162,13 +164,13 @@ impl Device {
|
|||
|
||||
/// Gets the document pointer.
|
||||
#[inline]
|
||||
pub fn document(&self) -> *mut structs::Document {
|
||||
self.pres_context().mDocument.mRawPtr
|
||||
pub fn document(&self) -> &structs::Document {
|
||||
unsafe { &*self.pres_context().mDocument.mRawPtr }
|
||||
}
|
||||
|
||||
/// Recreates the default computed values.
|
||||
pub fn reset_computed_values(&mut self) {
|
||||
self.default_values = ComputedValues::default_values(self.pres_context());
|
||||
self.default_values = ComputedValues::default_values(self.document());
|
||||
}
|
||||
|
||||
/// Rebuild all the cached data.
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
//! `pseudo_element_definition.mako.rs`. If you touch that file, you probably
|
||||
//! need to update the checked-in files for Servo.
|
||||
|
||||
use crate::gecko_bindings::structs::{self, CSSPseudoElementType};
|
||||
use crate::gecko_bindings::structs::{self, PseudoStyleType};
|
||||
use crate::properties::longhands::display::computed_value::T as Display;
|
||||
use crate::properties::{ComputedValues, PropertyFlags};
|
||||
use crate::selector_parser::{NonTSPseudoClass, PseudoElementCascadeType, SelectorImpl};
|
||||
|
|
|
@ -48,17 +48,6 @@ PseudoElement::${pseudo.capitalized_pseudo()}${"({})".format(tree_arg) if pseudo
|
|||
</%def>
|
||||
|
||||
impl PseudoElement {
|
||||
/// Get the pseudo-element as an atom.
|
||||
#[inline]
|
||||
fn atom(&self) -> Atom {
|
||||
match *self {
|
||||
% for pseudo in PSEUDOS:
|
||||
${pseudo_element_variant(pseudo)} => atom!("${pseudo.value}"),
|
||||
% endfor
|
||||
PseudoElement::UnknownWebkit(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an index of the pseudo-element.
|
||||
#[inline]
|
||||
pub fn index(&self) -> usize {
|
||||
|
@ -138,45 +127,36 @@ impl PseudoElement {
|
|||
}
|
||||
}
|
||||
|
||||
/// Construct a pseudo-element from a `CSSPseudoElementType`.
|
||||
/// Construct a pseudo-element from a `PseudoStyleType`.
|
||||
#[inline]
|
||||
pub fn from_pseudo_type(type_: CSSPseudoElementType) -> Option<Self> {
|
||||
pub fn from_pseudo_type(type_: PseudoStyleType) -> Option<Self> {
|
||||
match type_ {
|
||||
% for pseudo in PSEUDOS:
|
||||
% if not pseudo.is_anon_box():
|
||||
CSSPseudoElementType::${pseudo.pseudo_ident} => {
|
||||
Some(${pseudo_element_variant(pseudo)})
|
||||
},
|
||||
% endif
|
||||
% if not pseudo.is_tree_pseudo_element():
|
||||
PseudoStyleType::${pseudo.pseudo_ident} => {
|
||||
Some(${pseudo_element_variant(pseudo)})
|
||||
},
|
||||
% endif
|
||||
% endfor
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct a `CSSPseudoElementType` from a pseudo-element
|
||||
/// Construct a `PseudoStyleType` from a pseudo-element
|
||||
#[inline]
|
||||
fn pseudo_type(&self) -> CSSPseudoElementType {
|
||||
pub fn pseudo_type(&self) -> PseudoStyleType {
|
||||
match *self {
|
||||
% for pseudo in PSEUDOS:
|
||||
% if not pseudo.is_anon_box():
|
||||
PseudoElement::${pseudo.capitalized_pseudo()} => CSSPseudoElementType::${pseudo.pseudo_ident},
|
||||
% elif pseudo.is_tree_pseudo_element():
|
||||
PseudoElement::${pseudo.capitalized_pseudo()}(..) => CSSPseudoElementType::XULTree,
|
||||
% elif pseudo.is_inheriting_anon_box():
|
||||
PseudoElement::${pseudo.capitalized_pseudo()} => CSSPseudoElementType::InheritingAnonBox,
|
||||
% else:
|
||||
PseudoElement::${pseudo.capitalized_pseudo()} => CSSPseudoElementType::NonInheritingAnonBox,
|
||||
% endif
|
||||
% if pseudo.is_tree_pseudo_element():
|
||||
PseudoElement::${pseudo.capitalized_pseudo()}(..) => PseudoStyleType::XULTree,
|
||||
% else:
|
||||
PseudoElement::${pseudo.capitalized_pseudo()} => PseudoStyleType::${pseudo.pseudo_ident},
|
||||
% endif
|
||||
% endfor
|
||||
PseudoElement::UnknownWebkit(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a PseudoInfo for a pseudo
|
||||
pub fn pseudo_info(&self) -> (*mut structs::nsAtom, CSSPseudoElementType) {
|
||||
(self.atom().as_ptr(), self.pseudo_type())
|
||||
}
|
||||
|
||||
/// Get the argument list of a tree pseudo-element.
|
||||
#[inline]
|
||||
pub fn tree_pseudo_args(&self) -> Option<<&[Atom]> {
|
||||
|
@ -188,45 +168,15 @@ impl PseudoElement {
|
|||
}
|
||||
}
|
||||
|
||||
/// Construct a pseudo-element from an `Atom`.
|
||||
#[inline]
|
||||
pub fn from_atom(atom: &Atom) -> Option<Self> {
|
||||
% for pseudo in PSEUDOS:
|
||||
% if pseudo.is_tree_pseudo_element():
|
||||
// We cannot generate ${pseudo_element_variant(pseudo)} from just an atom.
|
||||
% else:
|
||||
if atom == &atom!("${pseudo.value}") {
|
||||
return Some(${pseudo_element_variant(pseudo)});
|
||||
}
|
||||
% endif
|
||||
% endfor
|
||||
None
|
||||
}
|
||||
|
||||
/// Construct a pseudo-element from an anonymous box `Atom`.
|
||||
#[inline]
|
||||
pub fn from_anon_box_atom(atom: &Atom) -> Option<Self> {
|
||||
% for pseudo in PSEUDOS:
|
||||
% if pseudo.is_tree_pseudo_element():
|
||||
// We cannot generate ${pseudo_element_variant(pseudo)} from just an atom.
|
||||
% elif pseudo.is_anon_box():
|
||||
if atom == &atom!("${pseudo.value}") {
|
||||
return Some(${pseudo_element_variant(pseudo)});
|
||||
}
|
||||
% endif
|
||||
% endfor
|
||||
None
|
||||
}
|
||||
|
||||
/// Construct a tree pseudo-element from atom and args.
|
||||
#[inline]
|
||||
pub fn from_tree_pseudo_atom(atom: &Atom, args: Box<[Atom]>) -> Option<Self> {
|
||||
% for pseudo in PSEUDOS:
|
||||
% if pseudo.is_tree_pseudo_element():
|
||||
if atom == &atom!("${pseudo.value}") {
|
||||
return Some(PseudoElement::${pseudo.capitalized_pseudo()}(args.into()));
|
||||
}
|
||||
% endif
|
||||
% if pseudo.is_tree_pseudo_element():
|
||||
if atom == &atom!("${pseudo.value}") {
|
||||
return Some(PseudoElement::${pseudo.capitalized_pseudo()}(args.into()));
|
||||
}
|
||||
% endif
|
||||
% endfor
|
||||
None
|
||||
}
|
||||
|
|
|
@ -41,8 +41,10 @@ class Atom:
|
|||
# The type of atom: "Atom", "PseudoElement", "NonInheritingAnonBox",
|
||||
# or "InheritingAnonBox".
|
||||
self.atom_type = atom_type
|
||||
if self.is_pseudo() or self.is_anon_box():
|
||||
|
||||
if self.is_pseudo_element() or self.is_anon_box() or self.is_tree_pseudo_element():
|
||||
self.pseudo_ident = (ident.split("_", 1))[1]
|
||||
|
||||
if self.is_anon_box():
|
||||
assert self.is_inheriting_anon_box() or self.is_non_inheriting_anon_box()
|
||||
|
||||
|
@ -52,16 +54,21 @@ class Atom:
|
|||
def capitalized_pseudo(self):
|
||||
return self.pseudo_ident[0].upper() + self.pseudo_ident[1:]
|
||||
|
||||
def is_pseudo(self):
|
||||
def is_pseudo_element(self):
|
||||
return self.atom_type == "PseudoElementAtom"
|
||||
|
||||
def is_anon_box(self):
|
||||
if self.is_tree_pseudo_element():
|
||||
return False
|
||||
return self.is_non_inheriting_anon_box() or self.is_inheriting_anon_box()
|
||||
|
||||
def is_non_inheriting_anon_box(self):
|
||||
assert not self.is_tree_pseudo_element()
|
||||
return self.atom_type == "NonInheritingAnonBoxAtom"
|
||||
|
||||
def is_inheriting_anon_box(self):
|
||||
if self.is_tree_pseudo_element():
|
||||
return False
|
||||
return self.atom_type == "InheritingAnonBoxAtom"
|
||||
|
||||
def is_tree_pseudo_element(self):
|
||||
|
|
|
@ -7,22 +7,16 @@
|
|||
//! Different kind of helpers to interact with Gecko values.
|
||||
|
||||
use crate::counter_style::{Symbol, Symbols};
|
||||
use crate::gecko_bindings::structs::{self, nsStyleCoord, CounterStylePtr};
|
||||
use crate::gecko_bindings::structs::{nsStyleCoord, CounterStylePtr};
|
||||
use crate::gecko_bindings::structs::{StyleGridTrackBreadth, StyleShapeRadius};
|
||||
use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue};
|
||||
use crate::media_queries::Device;
|
||||
use crate::values::computed::basic_shape::ShapeRadius as ComputedShapeRadius;
|
||||
use crate::values::computed::FlexBasis as ComputedFlexBasis;
|
||||
use crate::values::computed::{Angle, ExtremumLength, Length, LengthPercentage};
|
||||
use crate::values::computed::{MaxSize as ComputedMaxSize, Size as ComputedSize};
|
||||
use crate::values::computed::{NonNegativeLengthPercentage, Percentage};
|
||||
use crate::values::computed::{Number, NumberOrPercentage};
|
||||
use crate::values::computed::{Angle, Length, LengthPercentage};
|
||||
use crate::values::computed::{Number, NumberOrPercentage, Percentage};
|
||||
use crate::values::generics::basic_shape::ShapeRadius;
|
||||
use crate::values::generics::box_::Perspective;
|
||||
use crate::values::generics::flex::FlexBasis;
|
||||
use crate::values::generics::gecko::ScrollSnapPoint;
|
||||
use crate::values::generics::grid::{TrackBreadth, TrackKeyword};
|
||||
use crate::values::generics::length::{LengthPercentageOrAuto, MaxSize, Size};
|
||||
use crate::values::generics::length::LengthPercentageOrAuto;
|
||||
use crate::values::generics::{CounterStyleOrNone, NonNegative};
|
||||
use crate::values::{Auto, Either, None_, Normal};
|
||||
use crate::Atom;
|
||||
|
@ -80,29 +74,6 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for ComputedFlexBasis {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
match *self {
|
||||
FlexBasis::Content => coord.set_value(CoordDataValue::Enumerated(
|
||||
structs::NS_STYLE_FLEX_BASIS_CONTENT,
|
||||
)),
|
||||
FlexBasis::Width(ref w) => w.to_gecko_style_coord(coord),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
if let Some(width) = ComputedSize::from_gecko_style_coord(coord) {
|
||||
return Some(FlexBasis::Width(width));
|
||||
}
|
||||
|
||||
if let CoordDataValue::Enumerated(structs::NS_STYLE_FLEX_BASIS_CONTENT) = coord.as_value() {
|
||||
return Some(FlexBasis::Content);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for Number {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
coord.set_value(CoordDataValue::Factor(*self));
|
||||
|
@ -336,60 +307,6 @@ impl GeckoStyleCoordConvertible for Normal {
|
|||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for ExtremumLength {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
coord.set_value(CoordDataValue::Enumerated(*self as u32));
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
use num_traits::FromPrimitive;
|
||||
match coord.as_value() {
|
||||
CoordDataValue::Enumerated(v) => ExtremumLength::from_u32(v),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for ComputedSize {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
match *self {
|
||||
Size::LengthPercentage(ref lpoa) => lpoa.to_gecko_style_coord(coord),
|
||||
Size::Auto => coord.set_value(CoordDataValue::Auto),
|
||||
Size::ExtremumLength(ref e) => e.to_gecko_style_coord(coord),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
if let CoordDataValue::Auto = coord.as_value() {
|
||||
return Some(Size::Auto);
|
||||
}
|
||||
if let Some(lp) = NonNegativeLengthPercentage::from_gecko_style_coord(coord) {
|
||||
return Some(Size::LengthPercentage(lp));
|
||||
}
|
||||
ExtremumLength::from_gecko_style_coord(coord).map(Size::ExtremumLength)
|
||||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for ComputedMaxSize {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
match *self {
|
||||
MaxSize::LengthPercentage(ref lpon) => lpon.to_gecko_style_coord(coord),
|
||||
MaxSize::None => coord.set_value(CoordDataValue::None),
|
||||
MaxSize::ExtremumLength(ref e) => e.to_gecko_style_coord(coord),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
if let CoordDataValue::None = coord.as_value() {
|
||||
return Some(MaxSize::None);
|
||||
}
|
||||
if let Some(lp) = NonNegativeLengthPercentage::from_gecko_style_coord(coord) {
|
||||
return Some(MaxSize::LengthPercentage(lp));
|
||||
}
|
||||
ExtremumLength::from_gecko_style_coord(coord).map(MaxSize::ExtremumLength)
|
||||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for ScrollSnapPoint<LengthPercentage> {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
match self.repeated() {
|
||||
|
@ -412,27 +329,6 @@ impl GeckoStyleCoordConvertible for ScrollSnapPoint<LengthPercentage> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<L> GeckoStyleCoordConvertible for Perspective<L>
|
||||
where
|
||||
L: GeckoStyleCoordConvertible,
|
||||
{
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
match *self {
|
||||
Perspective::None => coord.set_value(CoordDataValue::None),
|
||||
Perspective::Length(ref l) => l.to_gecko_style_coord(coord),
|
||||
};
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
use crate::gecko_bindings::structs::root::nsStyleUnit;
|
||||
|
||||
if coord.unit() == nsStyleUnit::eStyleUnit_None {
|
||||
return Some(Perspective::None);
|
||||
}
|
||||
Some(Perspective::Length(L::from_gecko_style_coord(coord)?))
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a given RGBA value to `nscolor`.
|
||||
pub fn convert_rgba_to_nscolor(rgba: &RGBA) -> u32 {
|
||||
((rgba.alpha as u32) << 24) |
|
||||
|
@ -468,16 +364,15 @@ pub fn round_border_to_device_pixels(width: Au, au_per_device_px: Au) -> Au {
|
|||
|
||||
impl CounterStyleOrNone {
|
||||
/// Convert this counter style to a Gecko CounterStylePtr.
|
||||
pub fn to_gecko_value(self, gecko_value: &mut CounterStylePtr, device: &Device) {
|
||||
pub fn to_gecko_value(self, gecko_value: &mut CounterStylePtr) {
|
||||
use crate::gecko_bindings::bindings::Gecko_SetCounterStyleToName as set_name;
|
||||
use crate::gecko_bindings::bindings::Gecko_SetCounterStyleToSymbols as set_symbols;
|
||||
let pres_context = device.pres_context();
|
||||
match self {
|
||||
CounterStyleOrNone::None => unsafe {
|
||||
set_name(gecko_value, atom!("none").into_addrefed(), pres_context);
|
||||
set_name(gecko_value, atom!("none").into_addrefed());
|
||||
},
|
||||
CounterStyleOrNone::Name(name) => unsafe {
|
||||
set_name(gecko_value, name.0.into_addrefed(), pres_context);
|
||||
set_name(gecko_value, name.0.into_addrefed());
|
||||
},
|
||||
CounterStyleOrNone::Symbols(symbols_type, symbols) => {
|
||||
let symbols: Vec<_> = symbols
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
use crate::gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor};
|
||||
use crate::gecko_bindings::structs::StyleComplexColor;
|
||||
use crate::gecko_bindings::structs::StyleComplexColor_Tag as Tag;
|
||||
use crate::values::computed::ui::ColorOrAuto;
|
||||
use crate::values::computed::{Color as ComputedColor, RGBAColor as ComputedRGBA};
|
||||
use crate::values::generics::color::{Color as GenericColor, ComplexColorRatios};
|
||||
use crate::values::{Auto, Either};
|
||||
use crate::values::computed::{Color as ComputedColor, ColorOrAuto, RGBAColor as ComputedRGBA};
|
||||
use crate::values::generics::color::{
|
||||
Color as GenericColor, ColorOrAuto as GenericColorOrAuto, ComplexColorRatios,
|
||||
};
|
||||
|
||||
impl StyleComplexColor {
|
||||
/// Create a `StyleComplexColor` value that represents `currentColor`.
|
||||
|
@ -94,8 +94,8 @@ impl From<StyleComplexColor> for ComputedColor {
|
|||
impl From<ColorOrAuto> for StyleComplexColor {
|
||||
fn from(other: ColorOrAuto) -> Self {
|
||||
match other {
|
||||
Either::First(color) => color.into(),
|
||||
Either::Second(_) => StyleComplexColor::auto(),
|
||||
GenericColorOrAuto::Color(color) => color.into(),
|
||||
GenericColorOrAuto::Auto => StyleComplexColor::auto(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,9 +103,9 @@ impl From<ColorOrAuto> for StyleComplexColor {
|
|||
impl From<StyleComplexColor> for ColorOrAuto {
|
||||
fn from(other: StyleComplexColor) -> Self {
|
||||
if other.mTag != Tag::eAuto {
|
||||
Either::First(other.into())
|
||||
GenericColorOrAuto::Color(other.into())
|
||||
} else {
|
||||
Either::Second(Auto)
|
||||
GenericColorOrAuto::Auto
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -236,7 +236,7 @@ where
|
|||
parent_style.unwrap(),
|
||||
parent_style_ignoring_first_line.unwrap()
|
||||
) ||
|
||||
parent_style.unwrap().pseudo() == Some(PseudoElement::FirstLine)
|
||||
parent_style.unwrap().is_first_line_style()
|
||||
);
|
||||
|
||||
let inherited_style = parent_style.unwrap_or(device.default_computed_values());
|
||||
|
@ -745,13 +745,13 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
|||
|
||||
// FIXME(emilio): Why both setting the generic and passing it
|
||||
// down?
|
||||
let pres_context = self.context.builder.device.pres_context();
|
||||
let doc = self.context.builder.device.document();
|
||||
let gecko_font = self.context.builder.mutate_font().gecko_mut();
|
||||
gecko_font.mGenericID = generic;
|
||||
unsafe {
|
||||
crate::gecko_bindings::bindings::Gecko_nsStyleFont_PrefillDefaultForGeneric(
|
||||
gecko_font,
|
||||
pres_context,
|
||||
doc,
|
||||
generic,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -339,6 +339,7 @@ class Longhand(object):
|
|||
"Resize",
|
||||
"SVGOpacity",
|
||||
"SVGPaintOrder",
|
||||
"ScrollSnapAlign",
|
||||
"ScrollSnapType",
|
||||
"TextAlign",
|
||||
"TextDecorationLine",
|
||||
|
|
|
@ -35,10 +35,9 @@ use crate::gecko_bindings::bindings::Gecko_SetListStyleImageNone;
|
|||
use crate::gecko_bindings::bindings::Gecko_SetListStyleImageImageValue;
|
||||
use crate::gecko_bindings::bindings::Gecko_SetNullImageValue;
|
||||
use crate::gecko_bindings::bindings::{Gecko_ResetFilters, Gecko_CopyFiltersFrom};
|
||||
use crate::gecko_bindings::bindings::RawGeckoPresContextBorrowed;
|
||||
use crate::gecko_bindings::structs;
|
||||
use crate::gecko_bindings::structs::nsCSSPropertyID;
|
||||
use crate::gecko_bindings::structs::mozilla::CSSPseudoElementType;
|
||||
use crate::gecko_bindings::structs::mozilla::PseudoStyleType;
|
||||
use crate::gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut};
|
||||
use crate::gecko_bindings::sugar::refptr::RefPtr;
|
||||
use crate::gecko::values::convert_nscolor_to_rgba;
|
||||
|
@ -61,8 +60,6 @@ use crate::values::computed::BorderStyle;
|
|||
use crate::values::computed::font::FontSize;
|
||||
use crate::values::computed::effects::{BoxShadow, Filter, SimpleShadow};
|
||||
use crate::values::generics::column::ColumnCount;
|
||||
use crate::values::generics::position::ZIndex;
|
||||
use crate::values::generics::text::MozTabSize;
|
||||
use crate::values::generics::transform::TransformStyle;
|
||||
use crate::values::generics::url::UrlOrNone;
|
||||
|
||||
|
@ -102,7 +99,7 @@ impl ComputedValues {
|
|||
).to_outer(pseudo)
|
||||
}
|
||||
|
||||
pub fn default_values(pres_context: RawGeckoPresContextBorrowed) -> Arc<Self> {
|
||||
pub fn default_values(doc: &structs::Document) -> Arc<Self> {
|
||||
ComputedValuesInner::new(
|
||||
/* custom_properties = */ None,
|
||||
/* writing_mode = */ WritingMode::empty(), // FIXME(bz): This seems dubious
|
||||
|
@ -110,31 +107,22 @@ impl ComputedValues {
|
|||
/* rules = */ None,
|
||||
/* visited_style = */ None,
|
||||
% for style_struct in data.style_structs:
|
||||
style_structs::${style_struct.name}::default(pres_context),
|
||||
style_structs::${style_struct.name}::default(doc),
|
||||
% endfor
|
||||
).to_outer(None)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn pseudo(&self) -> Option<PseudoElement> {
|
||||
let atom = (self.0).mPseudoTag.mRawPtr;
|
||||
if atom.is_null() {
|
||||
if self.0.mPseudoType == PseudoStyleType::NotPseudo {
|
||||
return None;
|
||||
}
|
||||
|
||||
let atom = unsafe { Atom::from_raw(atom) };
|
||||
PseudoElement::from_atom(&atom)
|
||||
PseudoElement::from_pseudo_type(self.0.mPseudoType)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_pseudo_type(&self) -> CSSPseudoElementType {
|
||||
self.0.mPseudoType
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_anon_box(&self) -> bool {
|
||||
let our_type = self.get_pseudo_type();
|
||||
return our_type == CSSPseudoElementType::InheritingAnonBox ||
|
||||
our_type == CSSPseudoElementType::NonInheritingAnonBox;
|
||||
pub fn is_first_line_style(&self) -> bool {
|
||||
self.pseudo() == Some(PseudoElement::FirstLine)
|
||||
}
|
||||
|
||||
/// Returns true if the display property is changed from 'none' to others.
|
||||
|
@ -213,9 +201,9 @@ impl ComputedValuesInner {
|
|||
self,
|
||||
pseudo: Option<<&PseudoElement>,
|
||||
) -> Arc<ComputedValues> {
|
||||
let (pseudo_tag, pseudo_ty) = match pseudo {
|
||||
Some(p) => p.pseudo_info(),
|
||||
None => (ptr::null_mut(), structs::CSSPseudoElementType::NotPseudo),
|
||||
let pseudo_ty = match pseudo {
|
||||
Some(p) => p.pseudo_type(),
|
||||
None => structs::PseudoStyleType::NotPseudo,
|
||||
};
|
||||
let arc = unsafe {
|
||||
let arc: Arc<ComputedValues> = Arc::new(uninitialized());
|
||||
|
@ -223,7 +211,6 @@ impl ComputedValuesInner {
|
|||
&arc.0 as *const _ as *mut _,
|
||||
&self,
|
||||
pseudo_ty,
|
||||
pseudo_tag
|
||||
);
|
||||
// We're simulating a move by having C++ do a memcpy and then forgetting
|
||||
// it on this end.
|
||||
|
@ -453,22 +440,6 @@ def set_gecko_property(ffi_name, expr):
|
|||
}
|
||||
</%def>
|
||||
|
||||
<%def name="impl_position(ident, gecko_ffi_name)">
|
||||
#[allow(non_snake_case)]
|
||||
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
||||
${set_gecko_property("%s.mXPosition" % gecko_ffi_name, "v.horizontal.into()")}
|
||||
${set_gecko_property("%s.mYPosition" % gecko_ffi_name, "v.vertical.into()")}
|
||||
}
|
||||
<%call expr="impl_simple_copy(ident, gecko_ffi_name)"></%call>
|
||||
#[allow(non_snake_case)]
|
||||
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
|
||||
longhands::${ident}::computed_value::T {
|
||||
horizontal: self.gecko.${gecko_ffi_name}.mXPosition.into(),
|
||||
vertical: self.gecko.${gecko_ffi_name}.mYPosition.into(),
|
||||
}
|
||||
}
|
||||
</%def>
|
||||
|
||||
<%def name="impl_color(ident, gecko_ffi_name)">
|
||||
<%call expr="impl_color_setter(ident, gecko_ffi_name)"></%call>
|
||||
<%call expr="impl_color_copy(ident, gecko_ffi_name)"></%call>
|
||||
|
@ -1217,55 +1188,6 @@ pub fn clone_transform_from_list(
|
|||
}
|
||||
</%def>
|
||||
|
||||
<%def name="impl_transform_origin(ident, gecko_ffi_name)">
|
||||
#[allow(non_snake_case)]
|
||||
pub fn set_${ident}(&mut self, v: values::computed::TransformOrigin) {
|
||||
self.gecko.${gecko_ffi_name}[0].set(v.horizontal);
|
||||
self.gecko.${gecko_ffi_name}[1].set(v.vertical);
|
||||
// transform-origin supports the third value for depth, while
|
||||
// -moz-window-transform-origin doesn't. The following code is
|
||||
// for handling this difference. If we can have more knowledge
|
||||
// about the type here, we may want to check that the length is
|
||||
// exactly either 2 or 3 in compile time.
|
||||
if let Some(third) = self.gecko.${gecko_ffi_name}.get_mut(2) {
|
||||
third.set(v.depth);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn copy_${ident}_from(&mut self, other: &Self) {
|
||||
self.gecko.${gecko_ffi_name}[0].copy_from(&other.gecko.${gecko_ffi_name}[0]);
|
||||
self.gecko.${gecko_ffi_name}[1].copy_from(&other.gecko.${gecko_ffi_name}[1]);
|
||||
if let (Some(self_third), Some(other_third)) =
|
||||
(self.gecko.${gecko_ffi_name}.get_mut(2), other.gecko.${gecko_ffi_name}.get(2))
|
||||
{
|
||||
self_third.copy_from(other_third)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn reset_${ident}(&mut self, other: &Self) {
|
||||
self.copy_${ident}_from(other)
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn clone_${ident}(&self) -> values::computed::TransformOrigin {
|
||||
use crate::values::computed::{Length, LengthPercentage, TransformOrigin};
|
||||
TransformOrigin {
|
||||
horizontal: LengthPercentage::from_gecko_style_coord(&self.gecko.${gecko_ffi_name}[0])
|
||||
.expect("clone for LengthPercentage failed"),
|
||||
vertical: LengthPercentage::from_gecko_style_coord(&self.gecko.${gecko_ffi_name}[1])
|
||||
.expect("clone for LengthPercentage failed"),
|
||||
depth: if let Some(third) = self.gecko.${gecko_ffi_name}.get(2) {
|
||||
Length::from_gecko_style_coord(third)
|
||||
.expect("clone for Length failed")
|
||||
} else {
|
||||
Length::new(0.)
|
||||
},
|
||||
}
|
||||
}
|
||||
</%def>
|
||||
|
||||
<%def name="impl_logical(name, **kwargs)">
|
||||
${helpers.logical_setter(name)}
|
||||
</%def>
|
||||
|
@ -1273,11 +1195,13 @@ pub fn clone_transform_from_list(
|
|||
<%def name="impl_style_struct(style_struct)">
|
||||
impl ${style_struct.gecko_struct_name} {
|
||||
#[allow(dead_code, unused_variables)]
|
||||
pub fn default(pres_context: RawGeckoPresContextBorrowed) -> Arc<Self> {
|
||||
pub fn default(document: &structs::Document) -> Arc<Self> {
|
||||
let mut result = Arc::new(${style_struct.gecko_struct_name} { gecko: unsafe { zeroed() } });
|
||||
unsafe {
|
||||
Gecko_Construct_Default_${style_struct.gecko_ffi_name}(&mut Arc::get_mut(&mut result).unwrap().gecko,
|
||||
pres_context);
|
||||
Gecko_Construct_Default_${style_struct.gecko_ffi_name}(
|
||||
&mut Arc::get_mut(&mut result).unwrap().gecko,
|
||||
document,
|
||||
);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
@ -1370,6 +1294,7 @@ impl Clone for ${style_struct.gecko_struct_name} {
|
|||
"Appearance": impl_simple,
|
||||
"OverscrollBehavior": impl_simple,
|
||||
"OverflowClipBox": impl_simple,
|
||||
"ScrollSnapAlign": impl_simple,
|
||||
"ScrollSnapType": impl_simple,
|
||||
"Float": impl_simple,
|
||||
"Overflow": impl_simple,
|
||||
|
@ -1385,32 +1310,36 @@ impl Clone for ${style_struct.gecko_struct_name} {
|
|||
"length::NonNegativeLengthOrAuto": impl_style_coord,
|
||||
"length::NonNegativeLengthPercentageOrNormal": impl_style_coord,
|
||||
"FillRule": impl_simple,
|
||||
"FlexBasis": impl_style_coord,
|
||||
"FlexBasis": impl_simple,
|
||||
"Length": impl_absolute_length,
|
||||
"LengthOrNormal": impl_style_coord,
|
||||
"LengthPercentage": impl_simple,
|
||||
"LengthPercentageOrAuto": impl_style_coord,
|
||||
"MaxSize": impl_style_coord,
|
||||
"Size": impl_style_coord,
|
||||
"MaxSize": impl_simple,
|
||||
"Size": impl_simple,
|
||||
"MozScriptMinSize": impl_absolute_length,
|
||||
"MozScriptSizeMultiplier": impl_simple,
|
||||
"NonNegativeLengthPercentage": impl_simple,
|
||||
"NonNegativeLengthOrNumber": impl_simple,
|
||||
"NonNegativeLengthOrNumberRect": impl_simple,
|
||||
"BorderImageSlice": impl_simple,
|
||||
"NonNegativeNumber": impl_simple,
|
||||
"Number": impl_simple,
|
||||
"Opacity": impl_simple,
|
||||
"OverflowWrap": impl_simple,
|
||||
"OverflowAnchor": impl_simple,
|
||||
"Perspective": impl_style_coord,
|
||||
"Position": impl_position,
|
||||
"Perspective": impl_simple,
|
||||
"Position": impl_simple,
|
||||
"RGBAColor": impl_rgba_color,
|
||||
"SVGLength": impl_svg_length,
|
||||
"SVGOpacity": impl_svg_opacity,
|
||||
"SVGPaint": impl_svg_paint,
|
||||
"SVGWidth": impl_svg_length,
|
||||
"Transform": impl_transform,
|
||||
"TransformOrigin": impl_transform_origin,
|
||||
"TransformOrigin": impl_simple,
|
||||
"UserSelect": impl_simple,
|
||||
"url::UrlOrNone": impl_css_url,
|
||||
"ZIndex": impl_simple,
|
||||
}
|
||||
|
||||
def longhand_method(longhand):
|
||||
|
@ -1500,8 +1429,8 @@ fn static_assert() {
|
|||
for x in CORNERS]) %>
|
||||
|
||||
<%self:impl_trait style_struct_name="Border"
|
||||
skip_longhands="${skip_border_longhands} border-image-source border-image-outset
|
||||
border-image-repeat border-image-width border-image-slice">
|
||||
skip_longhands="${skip_border_longhands} border-image-source
|
||||
border-image-repeat border-image-width">
|
||||
% for side in SIDES:
|
||||
pub fn set_border_${side.ident}_style(&mut self, v: BorderStyle) {
|
||||
self.gecko.mBorderStyle[${side.index}] = v;
|
||||
|
@ -1602,8 +1531,6 @@ fn static_assert() {
|
|||
}
|
||||
}
|
||||
|
||||
<% impl_style_sides("border_image_outset") %>
|
||||
|
||||
<%
|
||||
border_image_repeat_keywords = ["Stretch", "Repeat", "Round", "Space"]
|
||||
%>
|
||||
|
@ -1645,63 +1572,41 @@ fn static_assert() {
|
|||
}
|
||||
|
||||
<% impl_style_sides("border_image_width") %>
|
||||
|
||||
pub fn set_border_image_slice(&mut self, v: longhands::border_image_slice::computed_value::T) {
|
||||
use crate::gecko_bindings::structs::{NS_STYLE_BORDER_IMAGE_SLICE_NOFILL, NS_STYLE_BORDER_IMAGE_SLICE_FILL};
|
||||
|
||||
v.offsets.to_gecko_rect(&mut self.gecko.mBorderImageSlice);
|
||||
|
||||
let fill = if v.fill {
|
||||
NS_STYLE_BORDER_IMAGE_SLICE_FILL
|
||||
} else {
|
||||
NS_STYLE_BORDER_IMAGE_SLICE_NOFILL
|
||||
};
|
||||
self.gecko.mBorderImageFill = fill as u8;
|
||||
}
|
||||
|
||||
<%self:copy_sides_style_coord ident="border_image_slice">
|
||||
self.gecko.mBorderImageFill = other.gecko.mBorderImageFill;
|
||||
</%self:copy_sides_style_coord>
|
||||
|
||||
pub fn clone_border_image_slice(&self) -> longhands::border_image_slice::computed_value::T {
|
||||
use crate::gecko_bindings::structs::NS_STYLE_BORDER_IMAGE_SLICE_FILL;
|
||||
use crate::values::computed::{BorderImageSlice, NonNegativeNumberOrPercentage};
|
||||
type NumberOrPercentageRect = crate::values::generics::rect::Rect<NonNegativeNumberOrPercentage>;
|
||||
|
||||
BorderImageSlice {
|
||||
offsets:
|
||||
NumberOrPercentageRect::from_gecko_rect(&self.gecko.mBorderImageSlice)
|
||||
.expect("mBorderImageSlice[${side}] could not convert to NumberOrPercentageRect"),
|
||||
fill: self.gecko.mBorderImageFill as u32 == NS_STYLE_BORDER_IMAGE_SLICE_FILL
|
||||
}
|
||||
}
|
||||
</%self:impl_trait>
|
||||
|
||||
<% skip_scroll_margin_longhands = " ".join(["scroll-margin-%s" % x.ident for x in SIDES]) %>
|
||||
<% skip_margin_longhands = " ".join(["margin-%s" % x.ident for x in SIDES]) %>
|
||||
<%self:impl_trait style_struct_name="Margin"
|
||||
skip_longhands="${skip_margin_longhands}">
|
||||
skip_longhands="${skip_margin_longhands}
|
||||
${skip_scroll_margin_longhands}">
|
||||
|
||||
% for side in SIDES:
|
||||
<% impl_split_style_coord("margin_%s" % side.ident,
|
||||
"mMargin",
|
||||
side.index) %>
|
||||
<% impl_split_style_coord("scroll_margin_%s" % side.ident,
|
||||
"mScrollMargin",
|
||||
side.index) %>
|
||||
% endfor
|
||||
</%self:impl_trait>
|
||||
|
||||
<% skip_scroll_padding_longhands = " ".join(["scroll-padding-%s" % x.ident for x in SIDES]) %>
|
||||
<% skip_padding_longhands = " ".join(["padding-%s" % x.ident for x in SIDES]) %>
|
||||
<%self:impl_trait style_struct_name="Padding"
|
||||
skip_longhands="${skip_padding_longhands}">
|
||||
skip_longhands="${skip_padding_longhands}
|
||||
${skip_scroll_padding_longhands}">
|
||||
|
||||
% for side in SIDES:
|
||||
<% impl_split_style_coord("padding_%s" % side.ident,
|
||||
"mPadding",
|
||||
side.index) %>
|
||||
<% impl_split_style_coord("scroll_padding_%s" % side.ident, "mScrollPadding", side.index) %>
|
||||
% endfor
|
||||
</%self:impl_trait>
|
||||
|
||||
<% skip_position_longhands = " ".join(x.ident for x in SIDES + GRID_LINES) %>
|
||||
<%self:impl_trait style_struct_name="Position"
|
||||
skip_longhands="${skip_position_longhands} z-index order
|
||||
skip_longhands="${skip_position_longhands} order
|
||||
align-content justify-content align-self
|
||||
justify-self align-items justify-items
|
||||
grid-auto-rows grid-auto-columns
|
||||
|
@ -1711,38 +1616,6 @@ fn static_assert() {
|
|||
<% impl_split_style_coord(side.ident, "mOffset", side.index) %>
|
||||
% endfor
|
||||
|
||||
pub fn set_z_index(&mut self, v: longhands::z_index::computed_value::T) {
|
||||
match v {
|
||||
ZIndex::Integer(n) => self.gecko.mZIndex.set_value(CoordDataValue::Integer(n)),
|
||||
ZIndex::Auto => self.gecko.mZIndex.set_value(CoordDataValue::Auto),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn copy_z_index_from(&mut self, other: &Self) {
|
||||
use crate::gecko_bindings::structs::nsStyleUnit;
|
||||
// z-index is never a calc(). If it were, we'd be leaking here, so
|
||||
// assert that it isn't.
|
||||
debug_assert_ne!(self.gecko.mZIndex.unit(), nsStyleUnit::eStyleUnit_Calc);
|
||||
unsafe {
|
||||
self.gecko.mZIndex.copy_from_unchecked(&other.gecko.mZIndex);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reset_z_index(&mut self, other: &Self) {
|
||||
self.copy_z_index_from(other)
|
||||
}
|
||||
|
||||
pub fn clone_z_index(&self) -> longhands::z_index::computed_value::T {
|
||||
return match self.gecko.mZIndex.as_value() {
|
||||
CoordDataValue::Integer(n) => ZIndex::Integer(n),
|
||||
CoordDataValue::Auto => ZIndex::Auto,
|
||||
_ => {
|
||||
debug_assert!(false);
|
||||
ZIndex::Integer(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
% for kind in ["align", "justify"]:
|
||||
${impl_simple_type_with_conversion(kind + "_content")}
|
||||
${impl_simple_type_with_conversion(kind + "_self")}
|
||||
|
@ -2216,7 +2089,7 @@ fn static_assert() {
|
|||
pub fn fixup_none_generic(&mut self, device: &Device) {
|
||||
self.gecko.mFont.systemFont = false;
|
||||
unsafe {
|
||||
bindings::Gecko_nsStyleFont_FixupNoneGeneric(&mut self.gecko, device.pres_context())
|
||||
bindings::Gecko_nsStyleFont_FixupNoneGeneric(&mut self.gecko, device.document())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2332,7 +2205,7 @@ fn static_assert() {
|
|||
}
|
||||
|
||||
pub fn fixup_font_min_size(&mut self, device: &Device) {
|
||||
unsafe { bindings::Gecko_nsStyleFont_FixupMinFontSize(&mut self.gecko, device.pres_context()) }
|
||||
unsafe { bindings::Gecko_nsStyleFont_FixupMinFontSize(&mut self.gecko, device.document()) }
|
||||
}
|
||||
|
||||
pub fn apply_unconstrained_font_size(&mut self, v: NonNegativeLength) {
|
||||
|
@ -2654,12 +2527,11 @@ fn static_assert() {
|
|||
${impl_simple("_moz_script_level", "mScriptLevel")}
|
||||
<% impl_simple_type_with_conversion("font_language_override", "mFont.languageOverride") %>
|
||||
|
||||
pub fn set_font_variant_alternates(&mut self,
|
||||
v: values::computed::font::FontVariantAlternates,
|
||||
device: &Device) {
|
||||
pub fn set_font_variant_alternates(
|
||||
&mut self,
|
||||
v: values::computed::font::FontVariantAlternates,
|
||||
) {
|
||||
use crate::gecko_bindings::bindings::{Gecko_ClearAlternateValues, Gecko_AppendAlternateValues};
|
||||
use crate::gecko_bindings::bindings::Gecko_nsFont_ResetFontFeatureValuesLookup;
|
||||
use crate::gecko_bindings::bindings::Gecko_nsFont_SetFontFeatureValuesLookup;
|
||||
% for value in "normal swash stylistic ornaments annotation styleset character_variant historical".split():
|
||||
use crate::gecko_bindings::structs::NS_FONT_VARIANT_ALTERNATES_${value.upper()};
|
||||
% endfor
|
||||
|
@ -2671,7 +2543,6 @@ fn static_assert() {
|
|||
|
||||
if v.0.is_empty() {
|
||||
self.gecko.mFont.variantAlternates = NS_FONT_VARIANT_ALTERNATES_NORMAL as u16;
|
||||
unsafe { Gecko_nsFont_ResetFontFeatureValuesLookup(&mut self.gecko.mFont); }
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2704,10 +2575,6 @@ fn static_assert() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
Gecko_nsFont_SetFontFeatureValuesLookup(&mut self.gecko.mFont, device.pres_context());
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
|
@ -2997,10 +2864,8 @@ fn static_assert() {
|
|||
clear transition-duration transition-delay
|
||||
transition-timing-function transition-property
|
||||
rotate scroll-snap-points-x scroll-snap-points-y
|
||||
scroll-snap-coordinate
|
||||
perspective-origin -moz-binding will-change
|
||||
offset-path perspective-origin -moz-binding
|
||||
will-change shape-outside contain touch-action
|
||||
scroll-snap-coordinate -moz-binding will-change
|
||||
offset-path shape-outside contain touch-action
|
||||
translate scale""" %>
|
||||
<%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}">
|
||||
#[inline]
|
||||
|
@ -3095,11 +2960,7 @@ fn static_assert() {
|
|||
where I: IntoIterator<Item = longhands::scroll_snap_coordinate::computed_value::single_value::T>,
|
||||
I::IntoIter: ExactSizeIterator
|
||||
{
|
||||
let iter = v.into_iter().map(|c| structs::mozilla::Position {
|
||||
mXPosition: c.horizontal.into(),
|
||||
mYPosition: c.vertical.into(),
|
||||
});
|
||||
self.gecko.mScrollSnapCoordinate.assign_from_iter_pod(iter);
|
||||
self.gecko.mScrollSnapCoordinate.assign_from_iter_pod(v.into_iter());
|
||||
}
|
||||
|
||||
pub fn copy_scroll_snap_coordinate_from(&mut self, other: &Self) {
|
||||
|
@ -3112,7 +2973,7 @@ fn static_assert() {
|
|||
}
|
||||
|
||||
pub fn clone_scroll_snap_coordinate(&self) -> longhands::scroll_snap_coordinate::computed_value::T {
|
||||
let vec = self.gecko.mScrollSnapCoordinate.iter().map(|f| f.into()).collect();
|
||||
let vec = self.gecko.mScrollSnapCoordinate.iter().cloned().collect();
|
||||
longhands::scroll_snap_coordinate::computed_value::List(vec)
|
||||
}
|
||||
|
||||
|
@ -3356,31 +3217,6 @@ fn static_assert() {
|
|||
|
||||
${impl_animation_timing_function()}
|
||||
|
||||
pub fn set_perspective_origin(&mut self, v: longhands::perspective_origin::computed_value::T) {
|
||||
self.gecko.mPerspectiveOrigin[0].set(v.horizontal);
|
||||
self.gecko.mPerspectiveOrigin[1].set(v.vertical);
|
||||
}
|
||||
|
||||
pub fn copy_perspective_origin_from(&mut self, other: &Self) {
|
||||
self.gecko.mPerspectiveOrigin[0].copy_from(&other.gecko.mPerspectiveOrigin[0]);
|
||||
self.gecko.mPerspectiveOrigin[1].copy_from(&other.gecko.mPerspectiveOrigin[1]);
|
||||
}
|
||||
|
||||
pub fn reset_perspective_origin(&mut self, other: &Self) {
|
||||
self.copy_perspective_origin_from(other)
|
||||
}
|
||||
|
||||
pub fn clone_perspective_origin(&self) -> longhands::perspective_origin::computed_value::T {
|
||||
use crate::properties::longhands::perspective_origin::computed_value::T;
|
||||
use crate::values::computed::LengthPercentage;
|
||||
T {
|
||||
horizontal: LengthPercentage::from_gecko_style_coord(&self.gecko.mPerspectiveOrigin[0])
|
||||
.expect("Expected length or percentage for horizontal value of perspective-origin"),
|
||||
vertical: LengthPercentage::from_gecko_style_coord(&self.gecko.mPerspectiveOrigin[1])
|
||||
.expect("Expected length or percentage for vertical value of perspective-origin"),
|
||||
}
|
||||
}
|
||||
|
||||
${impl_individual_transform('rotate', 'Rotate', 'mSpecifiedRotate')}
|
||||
${impl_individual_transform('translate', 'Translate', 'mSpecifiedTranslate')}
|
||||
${impl_individual_transform('scale', 'Scale', 'mSpecifiedScale')}
|
||||
|
@ -3759,7 +3595,7 @@ fn static_assert() {
|
|||
<% impl_simple_image_array_property("clip", shorthand, image_layers_field, "mClip", struct_name) %>
|
||||
<% impl_simple_image_array_property("origin", shorthand, image_layers_field, "mOrigin", struct_name) %>
|
||||
|
||||
% for orientation in ["x", "y"]:
|
||||
% for (orientation, keyword) in [("x", "horizontal"), ("y", "vertical")]:
|
||||
pub fn copy_${shorthand}_position_${orientation}_from(&mut self, other: &Self) {
|
||||
use crate::gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType;
|
||||
|
||||
|
@ -3774,8 +3610,7 @@ fn static_assert() {
|
|||
for (layer, other) in self.gecko.${image_layers_field}.mLayers.iter_mut()
|
||||
.zip(other.gecko.${image_layers_field}.mLayers.iter())
|
||||
.take(count as usize) {
|
||||
layer.mPosition.m${orientation.upper()}Position
|
||||
= other.mPosition.m${orientation.upper()}Position;
|
||||
layer.mPosition.${keyword} = other.mPosition.${keyword};
|
||||
}
|
||||
self.gecko.${image_layers_field}.mPosition${orientation.upper()}Count = count;
|
||||
}
|
||||
|
@ -3789,7 +3624,7 @@ fn static_assert() {
|
|||
longhands::${shorthand}_position_${orientation}::computed_value::List(
|
||||
self.gecko.${image_layers_field}.mLayers.iter()
|
||||
.take(self.gecko.${image_layers_field}.mPosition${orientation.upper()}Count as usize)
|
||||
.map(|position| position.mPosition.m${orientation.upper()}Position.into())
|
||||
.map(|position| position.mPosition.${keyword})
|
||||
.collect()
|
||||
)
|
||||
}
|
||||
|
@ -3812,86 +3647,18 @@ fn static_assert() {
|
|||
self.gecko.${image_layers_field}.mPosition${orientation[0].upper()}Count = v.len() as u32;
|
||||
for (servo, geckolayer) in v.zip(self.gecko.${image_layers_field}
|
||||
.mLayers.iter_mut()) {
|
||||
geckolayer.mPosition.m${orientation[0].upper()}Position = servo.into();
|
||||
geckolayer.mPosition.${keyword} = servo;
|
||||
}
|
||||
}
|
||||
% endfor
|
||||
|
||||
<%self:simple_image_array_property name="size" shorthand="${shorthand}" field_name="mSize">
|
||||
use crate::gecko_bindings::structs::nsStyleImageLayers_Size_Dimension;
|
||||
use crate::gecko_bindings::structs::nsStyleImageLayers_Size_DimensionType;
|
||||
use crate::gecko_bindings::structs::{nsStyleCoord_CalcValue, nsStyleImageLayers_Size};
|
||||
use crate::values::generics::background::BackgroundSize;
|
||||
|
||||
let mut width = nsStyleCoord_CalcValue::new();
|
||||
let mut height = nsStyleCoord_CalcValue::new();
|
||||
|
||||
let (w_type, h_type) = match servo {
|
||||
BackgroundSize::Explicit { width: explicit_width, height: explicit_height } => {
|
||||
let mut w_type = nsStyleImageLayers_Size_DimensionType::eAuto;
|
||||
let mut h_type = nsStyleImageLayers_Size_DimensionType::eAuto;
|
||||
if let Some(w) = explicit_width.to_calc_value() {
|
||||
width = w;
|
||||
w_type = nsStyleImageLayers_Size_DimensionType::eLengthPercentage;
|
||||
}
|
||||
if let Some(h) = explicit_height.to_calc_value() {
|
||||
height = h;
|
||||
h_type = nsStyleImageLayers_Size_DimensionType::eLengthPercentage;
|
||||
}
|
||||
(w_type, h_type)
|
||||
}
|
||||
BackgroundSize::Cover => {
|
||||
(
|
||||
nsStyleImageLayers_Size_DimensionType::eCover,
|
||||
nsStyleImageLayers_Size_DimensionType::eCover,
|
||||
)
|
||||
},
|
||||
BackgroundSize::Contain => {
|
||||
(
|
||||
nsStyleImageLayers_Size_DimensionType::eContain,
|
||||
nsStyleImageLayers_Size_DimensionType::eContain,
|
||||
)
|
||||
},
|
||||
};
|
||||
|
||||
nsStyleImageLayers_Size {
|
||||
mWidth: nsStyleImageLayers_Size_Dimension { _base: width },
|
||||
mHeight: nsStyleImageLayers_Size_Dimension { _base: height },
|
||||
mWidthType: w_type as u8,
|
||||
mHeightType: h_type as u8,
|
||||
}
|
||||
servo
|
||||
</%self:simple_image_array_property>
|
||||
|
||||
pub fn clone_${shorthand}_size(&self) -> longhands::${shorthand}_size::computed_value::T {
|
||||
use crate::gecko_bindings::structs::nsStyleCoord_CalcValue as CalcValue;
|
||||
use crate::gecko_bindings::structs::nsStyleImageLayers_Size_DimensionType as DimensionType;
|
||||
use crate::values::computed::NonNegativeLengthPercentageOrAuto;
|
||||
use crate::values::generics::background::BackgroundSize;
|
||||
|
||||
fn to_servo(value: CalcValue, ty: u8) -> NonNegativeLengthPercentageOrAuto {
|
||||
if ty == DimensionType::eAuto as u8 {
|
||||
NonNegativeLengthPercentageOrAuto::auto()
|
||||
} else {
|
||||
debug_assert_eq!(ty, DimensionType::eLengthPercentage as u8);
|
||||
value.into()
|
||||
}
|
||||
}
|
||||
|
||||
longhands::${shorthand}_size::computed_value::List(
|
||||
self.gecko.${image_layers_field}.mLayers.iter().map(|ref layer| {
|
||||
if DimensionType::eCover as u8 == layer.mSize.mWidthType {
|
||||
debug_assert_eq!(layer.mSize.mHeightType, DimensionType::eCover as u8);
|
||||
return BackgroundSize::Cover
|
||||
}
|
||||
if DimensionType::eContain as u8 == layer.mSize.mWidthType {
|
||||
debug_assert_eq!(layer.mSize.mHeightType, DimensionType::eContain as u8);
|
||||
return BackgroundSize::Contain
|
||||
}
|
||||
BackgroundSize::Explicit {
|
||||
width: to_servo(layer.mSize.mWidth._base, layer.mSize.mWidthType),
|
||||
height: to_servo(layer.mSize.mHeight._base, layer.mSize.mHeightType),
|
||||
}
|
||||
}).collect()
|
||||
self.gecko.${image_layers_field}.mLayers.iter().map(|layer| layer.mSize).collect()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -4043,12 +3810,12 @@ fn static_assert() {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_list_style_type(&mut self, v: longhands::list_style_type::computed_value::T, device: &Device) {
|
||||
pub fn set_list_style_type(&mut self, v: longhands::list_style_type::computed_value::T) {
|
||||
use crate::gecko_bindings::bindings::Gecko_SetCounterStyleToString;
|
||||
use nsstring::{nsACString, nsCStr};
|
||||
use self::longhands::list_style_type::computed_value::T;
|
||||
match v {
|
||||
T::CounterStyle(s) => s.to_gecko_value(&mut self.gecko.mCounterStyle, device),
|
||||
T::CounterStyle(s) => s.to_gecko_value(&mut self.gecko.mCounterStyle),
|
||||
T::String(s) => unsafe {
|
||||
Gecko_SetCounterStyleToString(&mut self.gecko.mCounterStyle,
|
||||
&nsCStr::from(&s) as &nsACString)
|
||||
|
@ -4472,7 +4239,7 @@ fn static_assert() {
|
|||
|
||||
<%self:impl_trait style_struct_name="InheritedText"
|
||||
skip_longhands="text-align text-emphasis-style text-shadow line-height letter-spacing word-spacing
|
||||
-webkit-text-stroke-width text-emphasis-position -moz-tab-size">
|
||||
-webkit-text-stroke-width text-emphasis-position">
|
||||
|
||||
<% text_align_keyword = Keyword("text-align",
|
||||
"start end left right center justify -moz-center -moz-left -moz-right char",
|
||||
|
@ -4661,28 +4428,6 @@ fn static_assert() {
|
|||
${impl_non_negative_length('_webkit_text_stroke_width',
|
||||
'mWebkitTextStrokeWidth')}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn set__moz_tab_size(&mut self, v: longhands::_moz_tab_size::computed_value::T) {
|
||||
match v {
|
||||
MozTabSize::Number(non_negative_number) => {
|
||||
self.gecko.mTabSize.set_value(CoordDataValue::Factor(non_negative_number.0));
|
||||
}
|
||||
MozTabSize::Length(non_negative_length) => {
|
||||
self.gecko.mTabSize.set(non_negative_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn clone__moz_tab_size(&self) -> longhands::_moz_tab_size::computed_value::T {
|
||||
match self.gecko.mTabSize.as_value() {
|
||||
CoordDataValue::Coord(coord) => MozTabSize::Length(Au(coord).into()),
|
||||
CoordDataValue::Factor(number) => MozTabSize::Number(From::from(number)),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
<%call expr="impl_coord_copy('_moz_tab_size', 'mTabSize')"></%call>
|
||||
</%self:impl_trait>
|
||||
|
||||
<%self:impl_trait style_struct_name="Text"
|
||||
|
@ -5290,7 +5035,7 @@ clip-path
|
|||
self.gecko.mContents.is_empty()
|
||||
}
|
||||
|
||||
pub fn set_content(&mut self, v: longhands::content::computed_value::T, device: &Device) {
|
||||
pub fn set_content(&mut self, v: longhands::content::computed_value::T) {
|
||||
use crate::values::CustomIdent;
|
||||
use crate::values::generics::counters::{Content, ContentItem};
|
||||
use crate::values::generics::CounterStyleOrNone;
|
||||
|
@ -5315,7 +5060,6 @@ clip-path
|
|||
name: &CustomIdent,
|
||||
sep: &str,
|
||||
style: CounterStyleOrNone,
|
||||
device: &Device,
|
||||
) {
|
||||
debug_assert!(content_type == StyleContentType::Counter ||
|
||||
content_type == StyleContentType::Counters);
|
||||
|
@ -5326,7 +5070,7 @@ clip-path
|
|||
if content_type == StyleContentType::Counters {
|
||||
counter_func.mSeparator.assign_str(sep);
|
||||
}
|
||||
style.to_gecko_value(&mut counter_func.mCounterStyle, device);
|
||||
style.to_gecko_value(&mut counter_func.mCounterStyle);
|
||||
}
|
||||
|
||||
match v {
|
||||
|
@ -5401,7 +5145,6 @@ clip-path
|
|||
&name,
|
||||
"",
|
||||
style.clone(),
|
||||
device,
|
||||
);
|
||||
}
|
||||
ContentItem::Counters(ref name, ref sep, ref style) => {
|
||||
|
@ -5411,7 +5154,6 @@ clip-path
|
|||
&name,
|
||||
&sep,
|
||||
style.clone(),
|
||||
device,
|
||||
);
|
||||
}
|
||||
ContentItem::Url(ref url) => {
|
||||
|
|
|
@ -119,10 +119,9 @@ ${helpers.predefined_type(
|
|||
|
||||
${helpers.predefined_type(
|
||||
"border-image-outset",
|
||||
"LengthOrNumberRect",
|
||||
parse_method="parse_non_negative",
|
||||
initial_value="computed::LengthOrNumberRect::all(computed::LengthOrNumber::zero())",
|
||||
initial_specified_value="specified::LengthOrNumberRect::all(specified::LengthOrNumber::zero())",
|
||||
"NonNegativeLengthOrNumberRect",
|
||||
initial_value="generics::rect::Rect::all(computed::NonNegativeLengthOrNumber::zero())",
|
||||
initial_specified_value="generics::rect::Rect::all(specified::NonNegativeLengthOrNumber::zero())",
|
||||
spec="https://drafts.csswg.org/css-backgrounds/#border-image-outset",
|
||||
animation_value_type="discrete",
|
||||
flags="APPLIES_TO_FIRST_LETTER",
|
||||
|
|
|
@ -417,6 +417,16 @@ ${helpers.single_keyword(
|
|||
animation_value_type="discrete",
|
||||
)}
|
||||
|
||||
${helpers.predefined_type(
|
||||
"scroll-snap-align",
|
||||
"ScrollSnapAlign",
|
||||
"computed::ScrollSnapAlign::none()",
|
||||
products="gecko",
|
||||
gecko_pref="layout.css.scroll-snap-v1.enabled",
|
||||
spec="https://drafts.csswg.org/css-scroll-snap-1/#scroll-snap-align",
|
||||
animation_value_type="discrete",
|
||||
)}
|
||||
|
||||
% for axis in ["x", "y"]:
|
||||
${helpers.predefined_type(
|
||||
"scroll-snap-type-" + axis,
|
||||
|
|
|
@ -98,7 +98,7 @@ pub mod system_colors {
|
|||
unsafe {
|
||||
Gecko_GetLookAndFeelSystemColor(
|
||||
*self as i32,
|
||||
cx.device().pres_context(),
|
||||
cx.device().document(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -396,7 +396,7 @@ ${helpers.predefined_type(
|
|||
&mut system,
|
||||
id as i32,
|
||||
cx.style().get_font().gecko(),
|
||||
cx.device().pres_context()
|
||||
cx.device().document()
|
||||
)
|
||||
}
|
||||
let font_weight = longhands::font_weight::computed_value::T::from_gecko_weight(system.weight);
|
||||
|
|
|
@ -257,10 +257,10 @@ ${helpers.predefined_type(
|
|||
|
||||
${helpers.predefined_type(
|
||||
"-moz-tab-size",
|
||||
"MozTabSize",
|
||||
"generics::text::MozTabSize::Number(From::from(8.0))",
|
||||
"NonNegativeLengthOrNumber",
|
||||
"generics::length::LengthOrNumber::Number(From::from(8.0))",
|
||||
products="gecko",
|
||||
animation_value_type="AnimatedMozTabSize",
|
||||
animation_value_type="LengthOrNumber",
|
||||
spec="https://drafts.csswg.org/css-text-3/#tab-size-property",
|
||||
)}
|
||||
|
||||
|
@ -349,8 +349,8 @@ ${helpers.single_keyword(
|
|||
"-moz-control-character-visibility",
|
||||
"hidden visible",
|
||||
gecko_constant_prefix="NS_STYLE_CONTROL_CHARACTER_VISIBILITY",
|
||||
gecko_ffi_name="mControlCharacterVisibility",
|
||||
animation_value_type="none",
|
||||
gecko_ffi_name="mControlCharacterVisibility",
|
||||
products="gecko",
|
||||
spec="Nonstandard",
|
||||
)}
|
||||
|
|
|
@ -60,7 +60,7 @@ ${helpers.single_keyword(
|
|||
${helpers.predefined_type(
|
||||
"caret-color",
|
||||
"ColorOrAuto",
|
||||
"Either::Second(Auto)",
|
||||
"generics::color::ColorOrAuto::Auto",
|
||||
spec="https://drafts.csswg.org/css-ui/#caret-color",
|
||||
animation_value_type="AnimatedCaretColor",
|
||||
ignored_when_colors_disabled=True,
|
||||
|
|
|
@ -27,3 +27,18 @@
|
|||
servo_restyle_damage="reflow"
|
||||
)}
|
||||
% endfor
|
||||
|
||||
% for side in ALL_SIDES:
|
||||
${helpers.predefined_type(
|
||||
"scroll-margin-%s" % side[0],
|
||||
"Length",
|
||||
"computed::Length::zero()",
|
||||
products="gecko",
|
||||
gecko_pref="layout.css.scroll-snap-v1.enabled",
|
||||
logical=side[1],
|
||||
logical_group="scroll-margin",
|
||||
spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-%s" % side[0],
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE",
|
||||
animation_value_type="ComputedValue",
|
||||
)}
|
||||
% endfor
|
||||
|
|
|
@ -28,3 +28,17 @@
|
|||
servo_restyle_damage="reflow rebuild_and_reflow_inline"
|
||||
)}
|
||||
% endfor
|
||||
|
||||
% for side in ALL_SIDES:
|
||||
${helpers.predefined_type(
|
||||
"scroll-padding-%s" % side[0],
|
||||
"NonNegativeLengthPercentageOrAuto",
|
||||
"computed::NonNegativeLengthPercentageOrAuto::auto()",
|
||||
products="gecko",
|
||||
gecko_pref="layout.css.scroll-snap-v1.enabled",
|
||||
logical=side[1],
|
||||
logical_group="scroll-padding",
|
||||
spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-%s" % side[0],
|
||||
animation_value_type="ComputedValue",
|
||||
)}
|
||||
% endfor
|
||||
|
|
|
@ -75,6 +75,7 @@ ${helpers.single_keyword(
|
|||
extra_prefixes="webkit",
|
||||
animation_value_type="discrete",
|
||||
servo_restyle_damage = "reflow",
|
||||
gecko_enum_prefix = "StyleFlexDirection",
|
||||
)}
|
||||
|
||||
${helpers.single_keyword(
|
||||
|
@ -225,7 +226,7 @@ ${helpers.predefined_type(
|
|||
extra_prefixes="webkit",
|
||||
animation_value_type="ComputedValue",
|
||||
spec="https://drafts.csswg.org/css-flexbox/#order-property",
|
||||
servo_restyle_damage = "reflow",
|
||||
servo_restyle_damage="reflow",
|
||||
)}
|
||||
|
||||
${helpers.predefined_type(
|
||||
|
@ -235,7 +236,8 @@ ${helpers.predefined_type(
|
|||
spec="https://drafts.csswg.org/css-flexbox/#flex-basis-property",
|
||||
extra_prefixes="webkit",
|
||||
animation_value_type="FlexBasis",
|
||||
servo_restyle_damage = "reflow",
|
||||
servo_restyle_damage="reflow",
|
||||
boxed=True,
|
||||
)}
|
||||
|
||||
% for (size, logical) in ALL_SIZES:
|
||||
|
|
|
@ -96,6 +96,7 @@ ${helpers.predefined_type(
|
|||
${helpers.single_keyword(
|
||||
"mask-mode",
|
||||
"match-source alpha luminance",
|
||||
gecko_enum_prefix="StyleMaskMode",
|
||||
vector=True,
|
||||
products="gecko",
|
||||
animation_value_type="discrete",
|
||||
|
|
|
@ -3358,7 +3358,7 @@ impl<'a> StyleBuilder<'a> {
|
|||
debug_assert!(parent_style.is_none() ||
|
||||
std::ptr::eq(parent_style.unwrap(),
|
||||
parent_style_ignoring_first_line.unwrap()) ||
|
||||
parent_style.unwrap().pseudo() == Some(PseudoElement::FirstLine));
|
||||
parent_style.unwrap().is_first_line_style());
|
||||
let reset_style = device.default_computed_values();
|
||||
let inherited_style = parent_style.unwrap_or(reset_style);
|
||||
let inherited_style_ignoring_first_line = parent_style_ignoring_first_line.unwrap_or(reset_style);
|
||||
|
@ -3402,7 +3402,7 @@ impl<'a> StyleBuilder<'a> {
|
|||
let inherited_style = parent_style.unwrap_or(reset_style);
|
||||
#[cfg(feature = "gecko")]
|
||||
debug_assert!(parent_style.is_none() ||
|
||||
parent_style.unwrap().pseudo() != Some(PseudoElement::FirstLine));
|
||||
!parent_style.unwrap().is_first_line_style());
|
||||
StyleBuilder {
|
||||
device,
|
||||
inherited_style,
|
||||
|
@ -3507,14 +3507,11 @@ impl<'a> StyleBuilder<'a> {
|
|||
self.modified_reset = true;
|
||||
% endif
|
||||
|
||||
<% props_need_device = ["content", "list_style_type", "font_variant_alternates"] %>
|
||||
self.${property.style_struct.ident}.mutate()
|
||||
.set_${property.ident}(
|
||||
value,
|
||||
% if property.logical:
|
||||
self.writing_mode,
|
||||
% elif product == "gecko" and property.ident in props_need_device:
|
||||
self.device,
|
||||
% endif
|
||||
);
|
||||
}
|
||||
|
|
|
@ -28,3 +28,32 @@ ${helpers.two_properties_shorthand(
|
|||
"specified::LengthPercentageOrAuto::parse",
|
||||
spec="https://drafts.csswg.org/css-logical/#propdef-margin-inline"
|
||||
)}
|
||||
|
||||
${helpers.four_sides_shorthand(
|
||||
"scroll-margin",
|
||||
"scroll-margin-%s",
|
||||
"specified::Length::parse",
|
||||
spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin",
|
||||
products="gecko",
|
||||
gecko_pref="layout.css.scroll-snap-v1.enabled",
|
||||
)}
|
||||
|
||||
${helpers.two_properties_shorthand(
|
||||
"scroll-margin-block",
|
||||
"scroll-margin-block-start",
|
||||
"scroll-margin-block-end",
|
||||
"specified::Length::parse",
|
||||
spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-block",
|
||||
products="gecko",
|
||||
gecko_pref="layout.css.scroll-snap-v1.enabled",
|
||||
)}
|
||||
|
||||
${helpers.two_properties_shorthand(
|
||||
"scroll-margin-inline",
|
||||
"scroll-margin-inline-start",
|
||||
"scroll-margin-inline-end",
|
||||
"specified::Length::parse",
|
||||
spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-inline",
|
||||
products="gecko",
|
||||
gecko_pref="layout.css.scroll-snap-v1.enabled",
|
||||
)}
|
||||
|
|
|
@ -27,3 +27,33 @@ ${helpers.two_properties_shorthand(
|
|||
"specified::NonNegativeLengthPercentage::parse",
|
||||
spec="https://drafts.csswg.org/css-logical/#propdef-padding-inline"
|
||||
)}
|
||||
|
||||
${helpers.four_sides_shorthand(
|
||||
"scroll-padding",
|
||||
"scroll-padding-%s",
|
||||
"specified::NonNegativeLengthPercentageOrAuto::parse",
|
||||
products="gecko",
|
||||
gecko_pref="layout.css.scroll-snap-v1.enabled",
|
||||
spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding"
|
||||
)}
|
||||
|
||||
${helpers.two_properties_shorthand(
|
||||
"scroll-padding-block",
|
||||
"scroll-padding-block-start",
|
||||
"scroll-padding-block-end",
|
||||
"specified::NonNegativeLengthPercentageOrAuto::parse",
|
||||
products="gecko",
|
||||
gecko_pref="layout.css.scroll-snap-v1.enabled",
|
||||
spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-block"
|
||||
)}
|
||||
|
||||
${helpers.two_properties_shorthand(
|
||||
"scroll-padding-inline",
|
||||
"scroll-padding-inline-start",
|
||||
"scroll-padding-inline-end",
|
||||
"specified::NonNegativeLengthPercentageOrAuto::parse",
|
||||
products="gecko",
|
||||
gecko_pref="layout.css.scroll-snap-v1.enabled",
|
||||
spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-inline"
|
||||
)}
|
||||
|
||||
|
|
|
@ -766,6 +766,11 @@ impl<E: TElement> StyleSharingCache<E> {
|
|||
return None;
|
||||
}
|
||||
|
||||
if target.element.has_animations() {
|
||||
trace!("Miss: Has Animations");
|
||||
return None;
|
||||
}
|
||||
|
||||
if target.matches_user_and_author_rules() !=
|
||||
candidate.element.matches_user_and_author_rules()
|
||||
{
|
||||
|
|
|
@ -198,7 +198,7 @@ impl DocumentMatchingFunction {
|
|||
MediaDocumentKind::Video => "video",
|
||||
},
|
||||
});
|
||||
unsafe { Gecko_DocumentRule_UseForPresentation(device.pres_context(), &*pattern, func) }
|
||||
unsafe { Gecko_DocumentRule_UseForPresentation(device.document(), &*pattern, func) }
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
|
|
|
@ -6,19 +6,8 @@
|
|||
|
||||
use crate::values::computed::length::NonNegativeLengthPercentage;
|
||||
use crate::values::generics::background::BackgroundSize as GenericBackgroundSize;
|
||||
use crate::values::generics::length::LengthPercentageOrAuto;
|
||||
|
||||
pub use crate::values::specified::background::BackgroundRepeat;
|
||||
|
||||
/// A computed value for the `background-size` property.
|
||||
pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentage>;
|
||||
|
||||
impl BackgroundSize {
|
||||
/// Returns `auto auto`.
|
||||
pub fn auto() -> Self {
|
||||
GenericBackgroundSize::Explicit {
|
||||
width: LengthPercentageOrAuto::auto(),
|
||||
height: LengthPercentageOrAuto::auto(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ pub use crate::values::specified::box_::{AnimationName, Appearance, BreakBetween
|
|||
pub use crate::values::specified::box_::{Clear as SpecifiedClear, Float as SpecifiedFloat};
|
||||
pub use crate::values::specified::box_::{Contain, Display, Overflow};
|
||||
pub use crate::values::specified::box_::{OverflowAnchor, OverflowClipBox};
|
||||
pub use crate::values::specified::box_::{OverscrollBehavior, ScrollSnapType};
|
||||
pub use crate::values::specified::box_::{OverscrollBehavior, ScrollSnapAlign, ScrollSnapType};
|
||||
pub use crate::values::specified::box_::{TouchAction, TransitionProperty, WillChange};
|
||||
|
||||
/// A computed value for the `vertical-align` property.
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
use crate::values::animated::color::RGBA as AnimatedRGBA;
|
||||
use crate::values::animated::ToAnimatedValue;
|
||||
use crate::values::generics::color::Color as GenericColor;
|
||||
use crate::values::generics::color::{Color as GenericColor, ColorOrAuto as GenericColorOrAuto};
|
||||
use cssparser::{Color as CSSParserColor, RGBA};
|
||||
use std::fmt;
|
||||
use style_traits::{CssWriter, ToCss};
|
||||
|
@ -101,3 +101,6 @@ impl ToAnimatedValue for RGBA {
|
|||
RGBA::from_floats(animated.red, animated.green, animated.blue, animated.alpha)
|
||||
}
|
||||
}
|
||||
|
||||
/// auto | <color>
|
||||
pub type ColorOrAuto = GenericColorOrAuto<Color>;
|
||||
|
|
|
@ -14,6 +14,6 @@ impl FlexBasis {
|
|||
/// `auto`
|
||||
#[inline]
|
||||
pub fn auto() -> Self {
|
||||
GenericFlexBasis::Width(Size::auto())
|
||||
GenericFlexBasis::Size(Size::auto())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,12 @@
|
|||
|
||||
use super::{Context, Number, Percentage, ToComputedValue};
|
||||
use crate::values::animated::ToAnimatedValue;
|
||||
use crate::values::computed::NonNegativeNumber;
|
||||
use crate::values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
use crate::values::generics::length as generics;
|
||||
use crate::values::generics::length::{MaxSize as GenericMaxSize, Size as GenericSize};
|
||||
use crate::values::generics::length::{
|
||||
GenericLengthOrNumber, MaxSize as GenericMaxSize, Size as GenericSize,
|
||||
};
|
||||
use crate::values::generics::transform::IsZeroLength;
|
||||
use crate::values::generics::NonNegative;
|
||||
use crate::values::specified::length::ViewportPercentageLength;
|
||||
|
@ -503,7 +506,7 @@ impl LengthPercentageOrAuto {
|
|||
|
||||
/// A wrapper of LengthPercentageOrAuto, whose value must be >= 0.
|
||||
pub type NonNegativeLengthPercentageOrAuto =
|
||||
generics::LengthPercentageOrAuto<NonNegativeLengthPercentage>;
|
||||
generics::GenericLengthPercentageOrAuto<NonNegativeLengthPercentage>;
|
||||
|
||||
impl NonNegativeLengthPercentageOrAuto {
|
||||
computed_length_percentage_or_auto!(NonNegativeLengthPercentage);
|
||||
|
@ -678,6 +681,15 @@ impl ToCss for CSSPixelLength {
|
|||
}
|
||||
}
|
||||
|
||||
impl Add for CSSPixelLength {
|
||||
type Output = Self;
|
||||
|
||||
#[inline]
|
||||
fn add(self, other: Self) -> Self {
|
||||
Self::new(self.px() + other.px())
|
||||
}
|
||||
}
|
||||
|
||||
impl Neg for CSSPixelLength {
|
||||
type Output = Self;
|
||||
|
||||
|
@ -708,15 +720,7 @@ pub type Length = CSSPixelLength;
|
|||
pub type LengthOrAuto = Either<Length, Auto>;
|
||||
|
||||
/// Either a computed `<length>` or a `<number>` value.
|
||||
pub type LengthOrNumber = Either<Length, Number>;
|
||||
|
||||
impl LengthOrNumber {
|
||||
/// Returns `0`.
|
||||
#[inline]
|
||||
pub fn zero() -> Self {
|
||||
Either::Second(0.)
|
||||
}
|
||||
}
|
||||
pub type LengthOrNumber = GenericLengthOrNumber<Length, Number>;
|
||||
|
||||
/// Either a computed `<length>` or the `normal` keyword.
|
||||
pub type LengthOrNormal = Either<Length, Normal>;
|
||||
|
@ -776,13 +780,6 @@ impl NonNegativeLength {
|
|||
}
|
||||
}
|
||||
|
||||
impl Add<NonNegativeLength> for NonNegativeLength {
|
||||
type Output = Self;
|
||||
fn add(self, other: Self) -> Self {
|
||||
NonNegativeLength::new(self.px() + other.px())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Length> for NonNegativeLength {
|
||||
#[inline]
|
||||
fn from(len: Length) -> Self {
|
||||
|
@ -813,6 +810,9 @@ pub type NonNegativeLengthOrNormal = Either<NonNegativeLength, Normal>;
|
|||
/// Either a computed NonNegativeLengthPercentage or the `normal` keyword.
|
||||
pub type NonNegativeLengthPercentageOrNormal = Either<NonNegativeLengthPercentage, Normal>;
|
||||
|
||||
/// Either a non-negative `<length>` or a `<number>`.
|
||||
pub type NonNegativeLengthOrNumber = GenericLengthOrNumber<NonNegativeLength, NonNegativeNumber>;
|
||||
|
||||
/// A type for possible values for min- and max- flavors of width, height,
|
||||
/// block-size, and inline-size.
|
||||
#[allow(missing_docs)]
|
||||
|
|
|
@ -44,8 +44,8 @@ pub use self::box_::{AnimationIterationCount, AnimationName, Contain};
|
|||
pub use self::box_::{Appearance, BreakBetween, BreakWithin, Clear, Float};
|
||||
pub use self::box_::{Display, Overflow, OverflowAnchor, TransitionProperty};
|
||||
pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize};
|
||||
pub use self::box_::{ScrollSnapType, TouchAction, VerticalAlign, WillChange};
|
||||
pub use self::color::{Color, ColorPropertyValue, RGBAColor};
|
||||
pub use self::box_::{ScrollSnapAlign, ScrollSnapType, TouchAction, VerticalAlign, WillChange};
|
||||
pub use self::color::{Color, ColorOrAuto, ColorPropertyValue, RGBAColor};
|
||||
pub use self::column::ColumnCount;
|
||||
pub use self::counters::{Content, ContentItem, CounterIncrement, CounterReset};
|
||||
pub use self::easing::TimingFunction;
|
||||
|
@ -61,7 +61,7 @@ pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier,
|
|||
pub use self::gecko::ScrollSnapPoint;
|
||||
pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, MozImageRect};
|
||||
pub use self::length::{CSSPixelLength, ExtremumLength, NonNegativeLength};
|
||||
pub use self::length::{Length, LengthOrNumber, LengthPercentage};
|
||||
pub use self::length::{Length, LengthOrNumber, LengthPercentage, NonNegativeLengthOrNumber};
|
||||
pub use self::length::{LengthPercentageOrAuto, MaxSize, Size};
|
||||
pub use self::length::{NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto};
|
||||
#[cfg(feature = "gecko")]
|
||||
|
@ -71,13 +71,13 @@ pub use self::motion::OffsetPath;
|
|||
pub use self::outline::OutlineStyle;
|
||||
pub use self::percentage::{NonNegativePercentage, Percentage};
|
||||
pub use self::position::{GridAutoFlow, GridTemplateAreas, Position, ZIndex};
|
||||
pub use self::rect::LengthOrNumberRect;
|
||||
pub use self::rect::NonNegativeLengthOrNumberRect;
|
||||
pub use self::resolution::Resolution;
|
||||
pub use self::svg::MozContextProperties;
|
||||
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::{InitialLetter, LetterSpacing, LineHeight};
|
||||
pub use self::text::{OverflowWrap, TextOverflow, WordSpacing};
|
||||
pub use self::text::{TextAlign, TextEmphasisPosition, TextEmphasisStyle};
|
||||
pub use self::time::Time;
|
||||
|
@ -85,7 +85,7 @@ pub use self::transform::{Rotate, Scale, Transform, TransformOperation};
|
|||
pub use self::transform::{TransformOrigin, TransformStyle, Translate};
|
||||
#[cfg(feature = "gecko")]
|
||||
pub use self::ui::CursorImage;
|
||||
pub use self::ui::{ColorOrAuto, Cursor, MozForceBrokenImageIcon, UserSelect};
|
||||
pub use self::ui::{Cursor, MozForceBrokenImageIcon, UserSelect};
|
||||
pub use super::specified::{BorderStyle, TextDecorationLine};
|
||||
pub use super::{Auto, Either, None_};
|
||||
pub use app_units::Au;
|
||||
|
@ -536,6 +536,7 @@ impl From<GreaterThanOrEqualToOneNumber> for CSSFloat {
|
|||
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
|
||||
#[repr(C, u8)]
|
||||
pub enum NumberOrPercentage {
|
||||
Percentage(Percentage),
|
||||
Number(Number),
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
//! Computed types for CSS borders.
|
||||
|
||||
use crate::values::computed::length::LengthOrNumber;
|
||||
use crate::values::computed::length::NonNegativeLengthOrNumber;
|
||||
use crate::values::generics::rect::Rect;
|
||||
|
||||
/// A specified rectangle made of four `<length-or-number>` values.
|
||||
pub type LengthOrNumberRect = Rect<LengthOrNumber>;
|
||||
pub type NonNegativeLengthOrNumberRect = Rect<NonNegativeLengthOrNumber>;
|
||||
|
|
|
@ -10,7 +10,6 @@ use crate::values::computed::length::{Length, LengthPercentage};
|
|||
use crate::values::computed::{NonNegativeLength, NonNegativeNumber};
|
||||
use crate::values::generics::text::InitialLetter as GenericInitialLetter;
|
||||
use crate::values::generics::text::LineHeight as GenericLineHeight;
|
||||
use crate::values::generics::text::MozTabSize as GenericMozTabSize;
|
||||
use crate::values::generics::text::Spacing;
|
||||
use crate::values::specified::text::TextOverflowSide;
|
||||
use crate::values::specified::text::{TextEmphasisFillMode, TextEmphasisShapeKeyword};
|
||||
|
@ -124,9 +123,6 @@ impl TextDecorationsInEffect {
|
|||
}
|
||||
}
|
||||
|
||||
/// A specified value for the `-moz-tab-size` property.
|
||||
pub type MozTabSize = GenericMozTabSize<NonNegativeNumber, NonNegativeLength>;
|
||||
|
||||
/// computed value for the text-emphasis-style property
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
|
||||
pub enum TextEmphasisStyle {
|
||||
|
|
|
@ -21,7 +21,8 @@ pub type TransformOperation =
|
|||
pub type Transform = generic::Transform<TransformOperation>;
|
||||
|
||||
/// The computed value of a CSS `<transform-origin>`
|
||||
pub type TransformOrigin = generic::TransformOrigin<LengthPercentage, LengthPercentage, Length>;
|
||||
pub type TransformOrigin =
|
||||
generic::GenericTransformOrigin<LengthPercentage, LengthPercentage, Length>;
|
||||
|
||||
/// A vector to represent the direction vector (rotate axis) for Rotate3D.
|
||||
pub type DirectionVector = Vector3D<CSSFloat>;
|
||||
|
|
|
@ -8,14 +8,10 @@ use crate::values::computed::color::Color;
|
|||
use crate::values::computed::url::ComputedImageUrl;
|
||||
use crate::values::computed::Number;
|
||||
use crate::values::generics::ui as generics;
|
||||
use crate::values::{Auto, Either};
|
||||
|
||||
pub use crate::values::specified::ui::CursorKind;
|
||||
pub use crate::values::specified::ui::{MozForceBrokenImageIcon, UserSelect};
|
||||
|
||||
/// auto | <color>
|
||||
pub type ColorOrAuto = Either<Color, Auto>;
|
||||
|
||||
/// A computed value for the `cursor` property.
|
||||
pub type Cursor = generics::Cursor<CursorImage>;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
//! Generic types for CSS values related to backgrounds.
|
||||
|
||||
use crate::values::generics::length::LengthPercentageOrAuto;
|
||||
use crate::values::generics::length::{GenericLengthPercentageOrAuto, LengthPercentageOrAuto};
|
||||
use std::fmt::{self, Write};
|
||||
use style_traits::{CssWriter, ToCss};
|
||||
|
||||
|
@ -22,13 +22,14 @@ use style_traits::{CssWriter, ToCss};
|
|||
ToAnimatedZero,
|
||||
ToComputedValue,
|
||||
)]
|
||||
pub enum BackgroundSize<LengthPercentage> {
|
||||
#[repr(C, u8)]
|
||||
pub enum GenericBackgroundSize<LengthPercent> {
|
||||
/// `<width> <height>`
|
||||
Explicit {
|
||||
ExplicitSize {
|
||||
/// Explicit width.
|
||||
width: LengthPercentageOrAuto<LengthPercentage>,
|
||||
width: GenericLengthPercentageOrAuto<LengthPercent>,
|
||||
/// Explicit height.
|
||||
height: LengthPercentageOrAuto<LengthPercentage>,
|
||||
height: GenericLengthPercentageOrAuto<LengthPercent>,
|
||||
},
|
||||
/// `cover`
|
||||
#[animation(error)]
|
||||
|
@ -38,6 +39,8 @@ pub enum BackgroundSize<LengthPercentage> {
|
|||
Contain,
|
||||
}
|
||||
|
||||
pub use self::GenericBackgroundSize as BackgroundSize;
|
||||
|
||||
impl<LengthPercentage> ToCss for BackgroundSize<LengthPercentage>
|
||||
where
|
||||
LengthPercentage: ToCss,
|
||||
|
@ -47,7 +50,7 @@ where
|
|||
W: Write,
|
||||
{
|
||||
match self {
|
||||
BackgroundSize::Explicit { width, height } => {
|
||||
BackgroundSize::ExplicitSize { 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
|
||||
|
@ -63,3 +66,13 @@ where
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<LengthPercentage> BackgroundSize<LengthPercentage> {
|
||||
/// Returns `auto auto`.
|
||||
pub fn auto() -> Self {
|
||||
GenericBackgroundSize::ExplicitSize {
|
||||
width: LengthPercentageOrAuto::Auto,
|
||||
height: LengthPercentageOrAuto::Auto,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,8 @@ pub enum BorderImageSideWidth<LengthPercentage, Number> {
|
|||
#[derive(
|
||||
Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss,
|
||||
)]
|
||||
pub struct BorderImageSlice<NumberOrPercentage> {
|
||||
#[repr(C)]
|
||||
pub struct GenericBorderImageSlice<NumberOrPercentage> {
|
||||
/// The offsets.
|
||||
#[css(field_bound)]
|
||||
pub offsets: Rect<NumberOrPercentage>,
|
||||
|
@ -35,6 +36,8 @@ pub struct BorderImageSlice<NumberOrPercentage> {
|
|||
pub fill: bool,
|
||||
}
|
||||
|
||||
pub use self::GenericBorderImageSlice as BorderImageSlice;
|
||||
|
||||
/// A generic value for the `border-*-radius` longhand properties.
|
||||
#[derive(
|
||||
Animate,
|
||||
|
|
|
@ -74,6 +74,7 @@ pub enum AnimationIterationCount<Number> {
|
|||
Copy,
|
||||
Debug,
|
||||
MallocSizeOf,
|
||||
Parse,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
|
@ -81,13 +82,16 @@ pub enum AnimationIterationCount<Number> {
|
|||
ToComputedValue,
|
||||
ToCss,
|
||||
)]
|
||||
pub enum Perspective<NonNegativeLength> {
|
||||
#[repr(C, u8)]
|
||||
pub enum GenericPerspective<NonNegativeLength> {
|
||||
/// A non-negative length.
|
||||
Length(NonNegativeLength),
|
||||
/// The keyword `none`.
|
||||
None,
|
||||
}
|
||||
|
||||
pub use self::GenericPerspective as Perspective;
|
||||
|
||||
impl<L> Perspective<L> {
|
||||
/// Returns `none`.
|
||||
#[inline]
|
||||
|
|
|
@ -74,3 +74,26 @@ impl<RGBA> From<RGBA> for Color<RGBA> {
|
|||
Self::rgba(color)
|
||||
}
|
||||
}
|
||||
|
||||
/// Either `<color>` or `auto`.
|
||||
#[derive(
|
||||
Animate,
|
||||
Clone,
|
||||
ComputeSquaredDistance,
|
||||
Copy,
|
||||
Debug,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
Parse,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
ToAnimatedZero,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
)]
|
||||
pub enum ColorOrAuto<C> {
|
||||
/// A `<color>
|
||||
Color(C),
|
||||
/// `auto`
|
||||
Auto,
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
Copy,
|
||||
Debug,
|
||||
MallocSizeOf,
|
||||
Parse,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
ComputeSquaredDistance,
|
||||
Copy,
|
||||
Debug,
|
||||
Parse,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
|
@ -19,9 +20,12 @@
|
|||
ToComputedValue,
|
||||
ToCss,
|
||||
)]
|
||||
pub enum FlexBasis<Width> {
|
||||
#[repr(C)]
|
||||
pub enum GenericFlexBasis<S> {
|
||||
/// `content`
|
||||
Content,
|
||||
/// `<width>`
|
||||
Width(Width),
|
||||
Size(S),
|
||||
}
|
||||
|
||||
pub use self::GenericFlexBasis as FlexBasis;
|
||||
|
|
|
@ -192,10 +192,7 @@ impl<L> TrackBreadth<L> {
|
|||
/// <https://drafts.csswg.org/css-grid/#typedef-fixed-breadth>
|
||||
#[inline]
|
||||
pub fn is_fixed(&self) -> bool {
|
||||
match *self {
|
||||
TrackBreadth::Breadth(ref _lp) => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(*self, TrackBreadth::Breadth(..))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ use crate::parser::{Parse, ParserContext};
|
|||
#[cfg(feature = "gecko")]
|
||||
use crate::values::computed::ExtremumLength;
|
||||
use cssparser::Parser;
|
||||
use num_traits::Zero;
|
||||
use style_traits::ParseError;
|
||||
|
||||
/// A `<length-percentage> | auto` value.
|
||||
|
@ -96,14 +97,17 @@ impl<LengthPercentage: Parse> Parse for LengthPercentageOrAuto<LengthPercentage>
|
|||
ToComputedValue,
|
||||
ToCss,
|
||||
)]
|
||||
pub enum Size<LengthPercentage> {
|
||||
LengthPercentage(LengthPercentage),
|
||||
#[repr(C, u8)]
|
||||
pub enum GenericSize<LengthPercent> {
|
||||
LengthPercentage(LengthPercent),
|
||||
Auto,
|
||||
#[cfg(feature = "gecko")]
|
||||
#[animation(error)]
|
||||
ExtremumLength(ExtremumLength),
|
||||
}
|
||||
|
||||
pub use self::GenericSize as Size;
|
||||
|
||||
impl<LengthPercentage> Size<LengthPercentage> {
|
||||
/// `auto` value.
|
||||
#[inline]
|
||||
|
@ -134,14 +138,17 @@ impl<LengthPercentage> Size<LengthPercentage> {
|
|||
ToComputedValue,
|
||||
ToCss,
|
||||
)]
|
||||
pub enum MaxSize<LengthPercentage> {
|
||||
LengthPercentage(LengthPercentage),
|
||||
#[repr(C, u8)]
|
||||
pub enum GenericMaxSize<LengthPercent> {
|
||||
LengthPercentage(LengthPercent),
|
||||
None,
|
||||
#[cfg(feature = "gecko")]
|
||||
#[animation(error)]
|
||||
ExtremumLength(ExtremumLength),
|
||||
}
|
||||
|
||||
pub use self::GenericMaxSize as MaxSize;
|
||||
|
||||
impl<LengthPercentage> MaxSize<LengthPercentage> {
|
||||
/// `none` value.
|
||||
#[inline]
|
||||
|
@ -149,3 +156,42 @@ impl<LengthPercentage> MaxSize<LengthPercentage> {
|
|||
MaxSize::None
|
||||
}
|
||||
}
|
||||
|
||||
/// A generic `<length>` | `<number>` value for the `-moz-tab-size` property.
|
||||
#[derive(
|
||||
Animate,
|
||||
Clone,
|
||||
ComputeSquaredDistance,
|
||||
Copy,
|
||||
Debug,
|
||||
MallocSizeOf,
|
||||
Parse,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
ToAnimatedZero,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
)]
|
||||
#[repr(C, u8)]
|
||||
pub enum GenericLengthOrNumber<L, N> {
|
||||
/// A number.
|
||||
///
|
||||
/// NOTE: Numbers need to be before lengths, in order to parse them
|
||||
/// first, since `0` should be a number, not the `0px` length.
|
||||
Number(N),
|
||||
/// A length.
|
||||
Length(L),
|
||||
}
|
||||
|
||||
pub use self::GenericLengthOrNumber as LengthOrNumber;
|
||||
|
||||
impl<L, N> LengthOrNumber<L, N> {
|
||||
/// Returns `0`.
|
||||
pub fn zero() -> Self
|
||||
where
|
||||
N: Zero,
|
||||
{
|
||||
LengthOrNumber::Number(num_traits::Zero::zero())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ use super::CustomIdent;
|
|||
use crate::counter_style::{parse_counter_style_name, Symbols};
|
||||
use crate::parser::{Parse, ParserContext};
|
||||
use cssparser::Parser;
|
||||
use num_traits::Zero;
|
||||
use std::ops::Add;
|
||||
use style_traits::{KeywordsCollectFn, ParseError};
|
||||
use style_traits::{SpecifiedValueInfo, StyleParseErrorKind};
|
||||
|
||||
|
@ -117,27 +119,25 @@ impl Parse for CounterStyleOrNone {
|
|||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
||||
return Ok(CounterStyleOrNone::None);
|
||||
}
|
||||
if input.try(|i| i.expect_function_matching("symbols")).is_ok() {
|
||||
return input.parse_nested_block(|input| {
|
||||
let symbols_type = input
|
||||
.try(|i| SymbolsType::parse(i))
|
||||
.unwrap_or(SymbolsType::Symbolic);
|
||||
let symbols = Symbols::parse(context, input)?;
|
||||
// There must be at least two symbols for alphabetic or
|
||||
// numeric system.
|
||||
if (symbols_type == SymbolsType::Alphabetic ||
|
||||
symbols_type == SymbolsType::Numeric) && symbols.0.len() < 2
|
||||
{
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
// Identifier is not allowed in symbols() function.
|
||||
if symbols.0.iter().any(|sym| !sym.is_allowed_in_symbols()) {
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
Ok(CounterStyleOrNone::Symbols(symbols_type, symbols))
|
||||
});
|
||||
}
|
||||
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
input.expect_function_matching("symbols")?;
|
||||
input.parse_nested_block(|input| {
|
||||
let symbols_type = input
|
||||
.try(SymbolsType::parse)
|
||||
.unwrap_or(SymbolsType::Symbolic);
|
||||
let symbols = Symbols::parse(context, input)?;
|
||||
// There must be at least two symbols for alphabetic or
|
||||
// numeric system.
|
||||
if (symbols_type == SymbolsType::Alphabetic || symbols_type == SymbolsType::Numeric) &&
|
||||
symbols.0.len() < 2
|
||||
{
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
// Identifier is not allowed in symbols() function.
|
||||
if symbols.0.iter().any(|sym| !sym.is_allowed_in_symbols()) {
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
Ok(CounterStyleOrNone::Symbols(symbols_type, symbols))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,6 +177,24 @@ impl SpecifiedValueInfo for CounterStyleOrNone {
|
|||
#[repr(transparent)]
|
||||
pub struct NonNegative<T>(pub T);
|
||||
|
||||
impl<T: Add<Output = T>> Add<NonNegative<T>> for NonNegative<T> {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, other: Self) -> Self {
|
||||
NonNegative(self.0 + other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Zero> Zero for NonNegative<T> {
|
||||
fn is_zero(&self) -> bool {
|
||||
self.0.is_zero()
|
||||
}
|
||||
|
||||
fn zero() -> Self {
|
||||
NonNegative(T::zero())
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper of greater-than-or-equal-to-one values.
|
||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||
#[derive(
|
||||
|
|
|
@ -19,19 +19,22 @@
|
|||
ToAnimatedZero,
|
||||
ToComputedValue,
|
||||
)]
|
||||
pub struct Position<H, V> {
|
||||
#[repr(C)]
|
||||
pub struct GenericPosition<H, V> {
|
||||
/// The horizontal component of position.
|
||||
pub horizontal: H,
|
||||
/// The vertical component of position.
|
||||
pub vertical: V,
|
||||
}
|
||||
|
||||
pub use self::GenericPosition as Position;
|
||||
|
||||
impl<H, V> Position<H, V> {
|
||||
/// Returns a new position.
|
||||
pub fn new(horizontal: H, vertical: V) -> Self {
|
||||
Self {
|
||||
horizontal: horizontal,
|
||||
vertical: vertical,
|
||||
horizontal,
|
||||
vertical,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,18 +48,22 @@ impl<H, V> Position<H, V> {
|
|||
Debug,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
Parse,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedZero,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
)]
|
||||
pub enum ZIndex<Integer> {
|
||||
#[repr(C, u8)]
|
||||
pub enum GenericZIndex<I> {
|
||||
/// An integer value.
|
||||
Integer(Integer),
|
||||
Integer(I),
|
||||
/// The keyword `auto`.
|
||||
Auto,
|
||||
}
|
||||
|
||||
pub use self::GenericZIndex as ZIndex;
|
||||
|
||||
impl<Integer> ZIndex<Integer> {
|
||||
/// Returns `auto`
|
||||
#[inline]
|
||||
|
|
|
@ -136,6 +136,7 @@ impl<ColorType: Parse, UrlPaintServer: Parse> Parse for SVGPaint<ColorType, UrlP
|
|||
Debug,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
Parse,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
ToAnimatedZero,
|
||||
|
@ -143,28 +144,26 @@ impl<ColorType: Parse, UrlPaintServer: Parse> Parse for SVGPaint<ColorType, UrlP
|
|||
ToCss,
|
||||
)]
|
||||
pub enum SvgLengthPercentageOrNumber<LengthPercentage, Number> {
|
||||
/// <number>
|
||||
///
|
||||
/// Note that this needs to be before, so it gets parsed before the length,
|
||||
/// to handle `0` correctly as a number instead of a `<length>`.
|
||||
Number(Number),
|
||||
/// <length> | <percentage>
|
||||
LengthPercentage(LengthPercentage),
|
||||
/// <number>
|
||||
Number(Number),
|
||||
}
|
||||
|
||||
/// Parsing the SvgLengthPercentageOrNumber. At first, we need to parse number
|
||||
/// since prevent converting to the length.
|
||||
impl<LengthPercentageType: Parse, NumberType: Parse> Parse
|
||||
for SvgLengthPercentageOrNumber<LengthPercentageType, NumberType>
|
||||
{
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(num) = input.try(|i| NumberType::parse(context, i)) {
|
||||
return Ok(SvgLengthPercentageOrNumber::Number(num));
|
||||
}
|
||||
/// Whether the `context-value` value is enabled.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn is_context_value_enabled(_: &ParserContext) -> bool {
|
||||
use crate::gecko_bindings::structs::mozilla;
|
||||
unsafe { mozilla::StaticPrefs_sVarCache_gfx_font_rendering_opentype_svg_enabled }
|
||||
}
|
||||
|
||||
let lp = LengthPercentageType::parse(context, input)?;
|
||||
Ok(SvgLengthPercentageOrNumber::LengthPercentage(lp))
|
||||
}
|
||||
/// Whether the `context-value` value is enabled.
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
pub fn is_context_value_enabled(_: &ParserContext) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// An SVG length value supports `context-value` in addition to length.
|
||||
|
@ -175,6 +174,7 @@ impl<LengthPercentageType: Parse, NumberType: Parse> Parse
|
|||
Debug,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
Parse,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
ToAnimatedZero,
|
||||
|
@ -185,6 +185,7 @@ pub enum SVGLength<LengthType> {
|
|||
/// `<length> | <percentage> | <number>`
|
||||
Length(LengthType),
|
||||
/// `context-value`
|
||||
#[parse(condition = "is_context_value_enabled")]
|
||||
ContextValue,
|
||||
}
|
||||
|
||||
|
@ -216,6 +217,7 @@ pub enum SVGStrokeDashArray<LengthType> {
|
|||
Debug,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
Parse,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedZero,
|
||||
ToComputedValue,
|
||||
|
|
|
@ -149,25 +149,3 @@ impl<N, L> LineHeight<N, L> {
|
|||
LineHeight::Normal
|
||||
}
|
||||
}
|
||||
|
||||
/// A generic value for the `-moz-tab-size` property.
|
||||
#[derive(
|
||||
Animate,
|
||||
Clone,
|
||||
ComputeSquaredDistance,
|
||||
Copy,
|
||||
Debug,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
ToAnimatedZero,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
)]
|
||||
pub enum MozTabSize<Number, Length> {
|
||||
/// A number.
|
||||
Number(Number),
|
||||
/// A length.
|
||||
Length(Length),
|
||||
}
|
||||
|
|
|
@ -83,7 +83,8 @@ impl<T: Into<f64>> From<Matrix3D<T>> for Transform3D<f64> {
|
|||
ToComputedValue,
|
||||
ToCss,
|
||||
)]
|
||||
pub struct TransformOrigin<H, V, Depth> {
|
||||
#[repr(C)]
|
||||
pub struct GenericTransformOrigin<H, V, Depth> {
|
||||
/// The horizontal origin.
|
||||
pub horizontal: H,
|
||||
/// The vertical origin.
|
||||
|
@ -92,13 +93,15 @@ pub struct TransformOrigin<H, V, Depth> {
|
|||
pub depth: Depth,
|
||||
}
|
||||
|
||||
pub use self::GenericTransformOrigin as TransformOrigin;
|
||||
|
||||
impl<H, V, D> TransformOrigin<H, V, D> {
|
||||
/// Returns a new transform origin.
|
||||
pub fn new(horizontal: H, vertical: V, depth: D) -> Self {
|
||||
Self {
|
||||
horizontal: horizontal,
|
||||
vertical: vertical,
|
||||
depth: depth,
|
||||
horizontal,
|
||||
vertical,
|
||||
depth,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,6 @@
|
|||
|
||||
//! Generic types for url properties.
|
||||
|
||||
use crate::parser::{Parse, ParserContext};
|
||||
use cssparser::Parser;
|
||||
use style_traits::ParseError;
|
||||
|
||||
/// An image url or none, used for example in list-style-image
|
||||
#[derive(
|
||||
Animate,
|
||||
|
@ -16,6 +12,7 @@ use style_traits::ParseError;
|
|||
Debug,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
Parse,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
ToAnimatedZero,
|
||||
|
@ -35,19 +32,3 @@ impl<Url> UrlOrNone<Url> {
|
|||
UrlOrNone::None
|
||||
}
|
||||
}
|
||||
|
||||
impl<Url> Parse for UrlOrNone<Url>
|
||||
where
|
||||
Url: Parse,
|
||||
{
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<UrlOrNone<Url>, ParseError<'i>> {
|
||||
if let Ok(url) = input.try(|input| Url::parse(context, input)) {
|
||||
return Ok(UrlOrNone::Url(url));
|
||||
}
|
||||
input.expect_ident_matching("none")?;
|
||||
Ok(UrlOrNone::None)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,6 +125,7 @@ impl Parse for Impossible {
|
|||
Copy,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
Parse,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
ToAnimatedZero,
|
||||
|
@ -147,19 +148,6 @@ impl<A: Debug, B: Debug> Debug for Either<A, B> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<A: Parse, B: Parse> Parse for Either<A, B> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Either<A, B>, ParseError<'i>> {
|
||||
if let Ok(v) = input.try(|i| A::parse(context, i)) {
|
||||
Ok(Either::First(v))
|
||||
} else {
|
||||
B::parse(context, input).map(Either::Second)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://drafts.csswg.org/css-values-4/#custom-idents>
|
||||
#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)]
|
||||
pub struct CustomIdent(pub Atom);
|
||||
|
|
|
@ -26,7 +26,7 @@ impl Parse for BackgroundSize {
|
|||
let height = input
|
||||
.try(|i| NonNegativeLengthPercentageOrAuto::parse(context, i))
|
||||
.unwrap_or(NonNegativeLengthPercentageOrAuto::auto());
|
||||
return Ok(GenericBackgroundSize::Explicit { width, height });
|
||||
return Ok(GenericBackgroundSize::ExplicitSize { width, height });
|
||||
}
|
||||
Ok(try_match_ident_ignore_ascii_case! { input,
|
||||
"cover" => GenericBackgroundSize::Cover,
|
||||
|
@ -35,16 +35,6 @@ impl Parse for BackgroundSize {
|
|||
}
|
||||
}
|
||||
|
||||
impl BackgroundSize {
|
||||
/// Returns `auto auto`.
|
||||
pub fn auto() -> Self {
|
||||
GenericBackgroundSize::Explicit {
|
||||
width: NonNegativeLengthPercentageOrAuto::auto(),
|
||||
height: NonNegativeLengthPercentageOrAuto::auto(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// One of the keywords for `background-repeat`.
|
||||
#[derive(
|
||||
Clone,
|
||||
|
|
|
@ -392,6 +392,76 @@ pub enum ScrollSnapType {
|
|||
Proximity,
|
||||
}
|
||||
|
||||
/// Specified value of scroll-snap-align keyword value.
|
||||
#[allow(missing_docs)]
|
||||
#[derive(
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Eq,
|
||||
FromPrimitive,
|
||||
Hash,
|
||||
MallocSizeOf,
|
||||
Parse,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
)]
|
||||
#[repr(u8)]
|
||||
pub enum ScrollSnapAlignKeyword {
|
||||
None,
|
||||
Start,
|
||||
End,
|
||||
Center,
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-scroll-snap-1/#scroll-snap-align
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)]
|
||||
#[repr(C)]
|
||||
pub struct ScrollSnapAlign {
|
||||
block: ScrollSnapAlignKeyword,
|
||||
inline: ScrollSnapAlignKeyword,
|
||||
}
|
||||
|
||||
impl ScrollSnapAlign {
|
||||
/// Returns `none`.
|
||||
#[inline]
|
||||
pub fn none() -> Self {
|
||||
ScrollSnapAlign {
|
||||
block: ScrollSnapAlignKeyword::None,
|
||||
inline: ScrollSnapAlignKeyword::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for ScrollSnapAlign {
|
||||
/// [ none | start | end | center ]{1,2}
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<ScrollSnapAlign, ParseError<'i>> {
|
||||
let block = ScrollSnapAlignKeyword::parse(input)?;
|
||||
let inline = input.try(ScrollSnapAlignKeyword::parse).unwrap_or(block);
|
||||
Ok(ScrollSnapAlign { block, inline })
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for ScrollSnapAlign {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
self.block.to_css(dest)?;
|
||||
if self.block != self.inline {
|
||||
dest.write_str(" ")?;
|
||||
self.inline.to_css(dest)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||
#[derive(
|
||||
|
@ -782,20 +852,6 @@ impl Parse for Contain {
|
|||
/// A specified value for the `perspective` property.
|
||||
pub type Perspective = GenericPerspective<NonNegativeLength>;
|
||||
|
||||
impl Parse for Perspective {
|
||||
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(GenericPerspective::None);
|
||||
}
|
||||
Ok(GenericPerspective::Length(NonNegativeLength::parse(
|
||||
context, input,
|
||||
)?))
|
||||
}
|
||||
}
|
||||
|
||||
/// A given transition property, that is either `All`, a longhand or shorthand
|
||||
/// property, or an unsupported or custom property.
|
||||
#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue)]
|
||||
|
|
|
@ -11,7 +11,7 @@ use crate::parser::{Parse, ParserContext};
|
|||
#[cfg(feature = "gecko")]
|
||||
use crate::properties::longhands::system_colors::SystemColor;
|
||||
use crate::values::computed::{Color as ComputedColor, Context, ToComputedValue};
|
||||
use crate::values::generics::color::Color as GenericColor;
|
||||
use crate::values::generics::color::{Color as GenericColor, ColorOrAuto as GenericColorOrAuto};
|
||||
use crate::values::specified::calc::CalcNode;
|
||||
use cssparser::{AngleOrNumber, Color as CSSParserColor, Parser, Token, RGBA};
|
||||
use cssparser::{BasicParseErrorKind, NumberOrPercentage, ParseErrorKind};
|
||||
|
@ -469,3 +469,6 @@ impl Parse for ColorPropertyValue {
|
|||
Color::parse_quirky(context, input, AllowQuirks::Yes).map(ColorPropertyValue)
|
||||
}
|
||||
}
|
||||
|
||||
/// auto | <color>
|
||||
pub type ColorOrAuto = GenericColorOrAuto<Color>;
|
||||
|
|
|
@ -4,25 +4,8 @@
|
|||
|
||||
//! Specified types for the column properties.
|
||||
|
||||
use crate::parser::{Parse, ParserContext};
|
||||
use crate::values::generics::column::ColumnCount as GenericColumnCount;
|
||||
use crate::values::specified::PositiveInteger;
|
||||
use cssparser::Parser;
|
||||
use style_traits::ParseError;
|
||||
|
||||
/// A specified type for `column-count` values.
|
||||
pub type ColumnCount = GenericColumnCount<PositiveInteger>;
|
||||
|
||||
impl Parse for ColumnCount {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if input.try(|i| i.expect_ident_matching("auto")).is_ok() {
|
||||
return Ok(GenericColumnCount::Auto);
|
||||
}
|
||||
Ok(GenericColumnCount::Integer(PositiveInteger::parse(
|
||||
context, input,
|
||||
)?))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,39 +4,22 @@
|
|||
|
||||
//! Specified types for CSS values related to flexbox.
|
||||
|
||||
use crate::parser::{Parse, ParserContext};
|
||||
use crate::values::generics::flex::FlexBasis as GenericFlexBasis;
|
||||
use crate::values::specified::Size;
|
||||
use cssparser::Parser;
|
||||
use style_traits::ParseError;
|
||||
|
||||
/// A specified value for the `flex-basis` property.
|
||||
pub type FlexBasis = GenericFlexBasis<Size>;
|
||||
|
||||
impl Parse for FlexBasis {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(width) = input.try(|i| Size::parse(context, i)) {
|
||||
return Ok(GenericFlexBasis::Width(width));
|
||||
}
|
||||
try_match_ident_ignore_ascii_case! { input,
|
||||
"content" => Ok(GenericFlexBasis::Content),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FlexBasis {
|
||||
/// `auto`
|
||||
#[inline]
|
||||
pub fn auto() -> Self {
|
||||
GenericFlexBasis::Width(Size::auto())
|
||||
GenericFlexBasis::Size(Size::auto())
|
||||
}
|
||||
|
||||
/// `0%`
|
||||
#[inline]
|
||||
pub fn zero_percent() -> Self {
|
||||
GenericFlexBasis::Width(Size::zero_percent())
|
||||
GenericFlexBasis::Size(Size::zero_percent())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use crate::values::generics::font::{KeywordSize, VariationValue};
|
|||
use crate::values::generics::NonNegative;
|
||||
use crate::values::specified::length::{FontBaseSize, AU_PER_PT, AU_PER_PX};
|
||||
use crate::values::specified::{AllowQuirks, Angle, Integer, LengthPercentage};
|
||||
use crate::values::specified::{NoCalcLength, Number, Percentage};
|
||||
use crate::values::specified::{NoCalcLength, NonNegativeNumber, Number, Percentage};
|
||||
use crate::values::CustomIdent;
|
||||
use crate::Atom;
|
||||
use app_units::Au;
|
||||
|
@ -81,7 +81,7 @@ pub const MAX_FONT_WEIGHT: f32 = 1000.;
|
|||
/// A specified font-weight value.
|
||||
///
|
||||
/// https://drafts.csswg.org/css-fonts-4/#propdef-font-weight
|
||||
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)]
|
||||
#[derive(Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss)]
|
||||
pub enum FontWeight {
|
||||
/// `<font-weight-absolute>`
|
||||
Absolute(AbsoluteFontWeight),
|
||||
|
@ -111,22 +111,6 @@ impl FontWeight {
|
|||
}
|
||||
}
|
||||
|
||||
impl Parse for FontWeight {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<FontWeight, ParseError<'i>> {
|
||||
if let Ok(absolute) = input.try(|input| AbsoluteFontWeight::parse(context, input)) {
|
||||
return Ok(FontWeight::Absolute(absolute));
|
||||
}
|
||||
|
||||
Ok(try_match_ident_ignore_ascii_case! { input,
|
||||
"bolder" => FontWeight::Bolder,
|
||||
"lighter" => FontWeight::Lighter,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ToComputedValue for FontWeight {
|
||||
type ComputedValue = computed::FontWeight;
|
||||
|
||||
|
@ -335,7 +319,7 @@ impl SpecifiedFontStyle {
|
|||
}
|
||||
|
||||
/// The specified value of the `font-style` property.
|
||||
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)]
|
||||
#[derive(Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum FontStyle {
|
||||
Specified(SpecifiedFontStyle),
|
||||
|
@ -368,20 +352,11 @@ impl ToComputedValue for FontStyle {
|
|||
}
|
||||
}
|
||||
|
||||
impl Parse for FontStyle {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Ok(FontStyle::Specified(SpecifiedFontStyle::parse(
|
||||
context, input,
|
||||
)?))
|
||||
}
|
||||
}
|
||||
|
||||
/// A value for the `font-stretch` property.
|
||||
///
|
||||
/// https://drafts.csswg.org/css-fonts-4/#font-stretch-prop
|
||||
///
|
||||
/// TODO(emilio): We could derive Parse if we had NonNegativePercentage.
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)]
|
||||
#[repr(u8)]
|
||||
|
@ -628,13 +603,13 @@ impl Parse for FamilyName {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)]
|
||||
#[derive(Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss)]
|
||||
/// Preserve the readability of text when font fallback occurs
|
||||
pub enum FontSizeAdjust {
|
||||
/// None variant
|
||||
None,
|
||||
/// Number variant
|
||||
Number(Number),
|
||||
Number(NonNegativeNumber),
|
||||
/// system font
|
||||
#[css(skip)]
|
||||
System(SystemFont),
|
||||
|
@ -657,7 +632,9 @@ impl ToComputedValue for FontSizeAdjust {
|
|||
match *self {
|
||||
FontSizeAdjust::None => computed::FontSizeAdjust::None,
|
||||
FontSizeAdjust::Number(ref n) => {
|
||||
computed::FontSizeAdjust::Number(n.to_computed_value(context))
|
||||
// The computed version handles clamping of animated values
|
||||
// itself.
|
||||
computed::FontSizeAdjust::Number(n.to_computed_value(context).0)
|
||||
},
|
||||
FontSizeAdjust::System(_) => self.compute_system(context),
|
||||
}
|
||||
|
@ -666,32 +643,13 @@ impl ToComputedValue for FontSizeAdjust {
|
|||
fn from_computed_value(computed: &computed::FontSizeAdjust) -> Self {
|
||||
match *computed {
|
||||
computed::FontSizeAdjust::None => FontSizeAdjust::None,
|
||||
computed::FontSizeAdjust::Number(ref v) => {
|
||||
FontSizeAdjust::Number(Number::from_computed_value(v))
|
||||
computed::FontSizeAdjust::Number(v) => {
|
||||
FontSizeAdjust::Number(NonNegativeNumber::from_computed_value(&v.into()))
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for FontSizeAdjust {
|
||||
/// none | <number>
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<FontSizeAdjust, ParseError<'i>> {
|
||||
if input
|
||||
.try(|input| input.expect_ident_matching("none"))
|
||||
.is_ok()
|
||||
{
|
||||
return Ok(FontSizeAdjust::None);
|
||||
}
|
||||
|
||||
Ok(FontSizeAdjust::Number(Number::parse_non_negative(
|
||||
context, input,
|
||||
)?))
|
||||
}
|
||||
}
|
||||
|
||||
/// Additional information for specified keyword-derived font sizes.
|
||||
pub type KeywordInfo = generics::KeywordInfo<NonNegativeLength>;
|
||||
|
||||
|
|
|
@ -305,7 +305,7 @@ impl Gradient {
|
|||
) -> Result<Self, ParseError<'i>> {
|
||||
type Point = GenericPosition<Component<X>, Component<Y>>;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Parse)]
|
||||
enum Component<S> {
|
||||
Center,
|
||||
Number(NumberOrPercentage),
|
||||
|
@ -408,22 +408,6 @@ impl Gradient {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Parse> Parse for Component<S> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(side) = input.try(|i| S::parse(context, i)) {
|
||||
return Ok(Component::Side(side));
|
||||
}
|
||||
if let Ok(number) = input.try(|i| NumberOrPercentage::parse(context, i)) {
|
||||
return Ok(Component::Number(number));
|
||||
}
|
||||
input.try(|i| i.expect_ident_matching("center"))?;
|
||||
Ok(Component::Center)
|
||||
}
|
||||
}
|
||||
|
||||
let ident = input.expect_ident_cloned()?;
|
||||
input.expect_comma()?;
|
||||
|
||||
|
|
|
@ -11,10 +11,13 @@ use crate::font_metrics::FontMetricsQueryResult;
|
|||
use crate::parser::{Parse, ParserContext};
|
||||
use crate::values::computed::{self, CSSPixelLength, Context};
|
||||
use crate::values::generics::length as generics;
|
||||
use crate::values::generics::length::{MaxSize as GenericMaxSize, Size as GenericSize};
|
||||
use crate::values::generics::length::{
|
||||
GenericLengthOrNumber, MaxSize as GenericMaxSize, Size as GenericSize,
|
||||
};
|
||||
use crate::values::generics::transform::IsZeroLength;
|
||||
use crate::values::generics::NonNegative;
|
||||
use crate::values::specified::calc::CalcNode;
|
||||
use crate::values::specified::NonNegativeNumber;
|
||||
use crate::values::{Auto, CSSFloat, Either, Normal};
|
||||
use app_units::Au;
|
||||
use cssparser::{Parser, Token};
|
||||
|
@ -1023,30 +1026,7 @@ pub type LengthOrNormal = Either<Length, Normal>;
|
|||
pub type LengthOrAuto = Either<Length, Auto>;
|
||||
|
||||
/// Either a `<length>` or a `<number>`.
|
||||
pub type LengthOrNumber = Either<Length, Number>;
|
||||
|
||||
impl LengthOrNumber {
|
||||
/// Parse a non-negative LengthOrNumber.
|
||||
pub fn parse_non_negative<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
// We try to parse as a Number first because, for cases like
|
||||
// LengthOrNumber, we want "0" to be parsed as a plain Number rather
|
||||
// than a Length (0px); this matches the behaviour of all major browsers
|
||||
if let Ok(v) = input.try(|i| Number::parse_non_negative(context, i)) {
|
||||
return Ok(Either::Second(v));
|
||||
}
|
||||
|
||||
Length::parse_non_negative(context, input).map(Either::First)
|
||||
}
|
||||
|
||||
/// Returns `0`.
|
||||
#[inline]
|
||||
pub fn zero() -> Self {
|
||||
Either::Second(Number::new(0.))
|
||||
}
|
||||
}
|
||||
pub type LengthOrNumber = GenericLengthOrNumber<Length, Number>;
|
||||
|
||||
/// A specified value for `min-width`, `min-height`, `width` or `height` property.
|
||||
pub type Size = GenericSize<NonNegativeLengthPercentage>;
|
||||
|
@ -1123,3 +1103,6 @@ impl MaxSize {
|
|||
Ok(GenericMaxSize::LengthPercentage(length))
|
||||
}
|
||||
}
|
||||
|
||||
/// A specified non-negative `<length>` | `<number>`.
|
||||
pub type NonNegativeLengthOrNumber = GenericLengthOrNumber<NonNegativeLength, NonNegativeNumber>;
|
||||
|
|
|
@ -19,9 +19,10 @@ use crate::values::serialize_atom_identifier;
|
|||
use crate::values::specified::calc::CalcNode;
|
||||
use crate::{Atom, Namespace, Prefix};
|
||||
use cssparser::{Parser, Token};
|
||||
use num_traits::One;
|
||||
use num_traits::{One, Zero};
|
||||
use std::f32;
|
||||
use std::fmt::{self, Write};
|
||||
use std::ops::Add;
|
||||
use style_traits::values::specified::AllowedNumericType;
|
||||
use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, StyleParseErrorKind, ToCss};
|
||||
|
||||
|
@ -39,8 +40,9 @@ pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display};
|
|||
pub use self::box_::{Appearance, BreakBetween, BreakWithin};
|
||||
pub use self::box_::{Clear, Float, Overflow, OverflowAnchor};
|
||||
pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize};
|
||||
pub use self::box_::{ScrollSnapType, TouchAction, TransitionProperty, VerticalAlign, WillChange};
|
||||
pub use self::color::{Color, ColorPropertyValue, RGBAColor};
|
||||
pub use self::box_::{ScrollSnapAlign, ScrollSnapType};
|
||||
pub use self::box_::{TouchAction, TransitionProperty, VerticalAlign, WillChange};
|
||||
pub use self::color::{Color, ColorOrAuto, ColorPropertyValue, RGBAColor};
|
||||
pub use self::column::ColumnCount;
|
||||
pub use self::counters::{Content, ContentItem, CounterIncrement, CounterReset};
|
||||
pub use self::easing::TimingFunction;
|
||||
|
@ -57,7 +59,7 @@ pub use self::gecko::ScrollSnapPoint;
|
|||
pub use self::image::{ColorStop, EndingShape as GradientEndingShape, Gradient};
|
||||
pub use self::image::{GradientItem, GradientKind, Image, ImageLayer, MozImageRect};
|
||||
pub use self::length::{AbsoluteLength, CalcLengthPercentage, CharacterWidth};
|
||||
pub use self::length::{FontRelativeLength, Length, LengthOrNumber};
|
||||
pub use self::length::{FontRelativeLength, Length, LengthOrNumber, NonNegativeLengthOrNumber};
|
||||
pub use self::length::{LengthPercentage, LengthPercentageOrAuto};
|
||||
pub use self::length::{MaxSize, Size};
|
||||
pub use self::length::{NoCalcLength, ViewportPercentageLength};
|
||||
|
@ -70,14 +72,14 @@ pub use self::outline::OutlineStyle;
|
|||
pub use self::percentage::Percentage;
|
||||
pub use self::position::{GridAutoFlow, GridTemplateAreas, Position};
|
||||
pub use self::position::{PositionComponent, ZIndex};
|
||||
pub use self::rect::LengthOrNumberRect;
|
||||
pub use self::rect::NonNegativeLengthOrNumberRect;
|
||||
pub use self::resolution::Resolution;
|
||||
pub use self::svg::MozContextProperties;
|
||||
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind};
|
||||
pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth};
|
||||
pub use self::svg_path::SVGPathData;
|
||||
pub use self::table::XSpan;
|
||||
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, MozTabSize, TextAlign};
|
||||
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, TextAlign};
|
||||
pub use self::text::{OverflowWrap, TextEmphasisPosition, TextEmphasisStyle};
|
||||
pub use self::text::{TextAlignKeyword, TextDecorationLine, TextOverflow, WordSpacing};
|
||||
pub use self::time::Time;
|
||||
|
@ -85,7 +87,7 @@ pub use self::transform::{Rotate, Scale, Transform};
|
|||
pub use self::transform::{TransformOrigin, TransformStyle, Translate};
|
||||
#[cfg(feature = "gecko")]
|
||||
pub use self::ui::CursorImage;
|
||||
pub use self::ui::{ColorOrAuto, Cursor, MozForceBrokenImageIcon, UserSelect};
|
||||
pub use self::ui::{Cursor, MozForceBrokenImageIcon, UserSelect};
|
||||
pub use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent;
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
|
@ -270,6 +272,26 @@ impl IsParallelTo for (Number, Number, Number) {
|
|||
|
||||
impl SpecifiedValueInfo for Number {}
|
||||
|
||||
impl Add for Number {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, other: Self) -> Self {
|
||||
Self::new(self.get() + other.get())
|
||||
}
|
||||
}
|
||||
|
||||
impl Zero for Number {
|
||||
#[inline]
|
||||
fn zero() -> Self {
|
||||
Self::new(0.)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool {
|
||||
self.get() == 0.
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Number> for f32 {
|
||||
#[inline]
|
||||
fn from(n: Number) -> Self {
|
||||
|
@ -563,7 +585,7 @@ impl Parse for PositiveInteger {
|
|||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Integer::parse_positive(context, input).map(GreaterThanOrEqualToOne::<Integer>)
|
||||
Integer::parse_positive(context, input).map(GreaterThanOrEqualToOne)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -731,15 +731,3 @@ impl GridTemplateAreas {
|
|||
|
||||
/// A specified value for the `z-index` property.
|
||||
pub type ZIndex = GenericZIndex<Integer>;
|
||||
|
||||
impl Parse for ZIndex {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if input.try(|i| i.expect_ident_matching("auto")).is_ok() {
|
||||
return Ok(GenericZIndex::Auto);
|
||||
}
|
||||
Ok(GenericZIndex::Integer(Integer::parse(context, input)?))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,22 +4,8 @@
|
|||
|
||||
//! Specified types for CSS borders.
|
||||
|
||||
use crate::parser::ParserContext;
|
||||
use crate::values::generics::rect::Rect;
|
||||
use crate::values::specified::length::LengthOrNumber;
|
||||
use cssparser::Parser;
|
||||
use style_traits::ParseError;
|
||||
use crate::values::specified::length::NonNegativeLengthOrNumber;
|
||||
|
||||
/// A specified rectangle made of four `<length-or-number>` values.
|
||||
pub type LengthOrNumberRect = Rect<LengthOrNumber>;
|
||||
|
||||
impl LengthOrNumberRect {
|
||||
/// Parses a `LengthOrNumberRect`, rejecting negative values.
|
||||
#[inline]
|
||||
pub fn parse_non_negative<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Rect::parse_with(context, input, LengthOrNumber::parse_non_negative)
|
||||
}
|
||||
}
|
||||
pub type NonNegativeLengthOrNumberRect = Rect<NonNegativeLengthOrNumber>;
|
||||
|
|
|
@ -23,31 +23,6 @@ pub type SVGPaint = generic::SVGPaint<Color, SpecifiedUrl>;
|
|||
/// Specified SVG Paint Kind value
|
||||
pub type SVGPaintKind = generic::SVGPaintKind<Color, SpecifiedUrl>;
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
fn is_context_value_enabled() -> bool {
|
||||
// The prefs can only be mutated on the main thread, so it is safe
|
||||
// to read whenever we are on the main thread or the main thread is
|
||||
// blocked.
|
||||
use crate::gecko_bindings::structs::mozilla;
|
||||
unsafe { mozilla::StaticPrefs_sVarCache_gfx_font_rendering_opentype_svg_enabled }
|
||||
}
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
fn is_context_value_enabled() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_context_value<'i, 't, T>(
|
||||
input: &mut Parser<'i, 't>,
|
||||
value: T,
|
||||
) -> Result<T, ParseError<'i>> {
|
||||
if !is_context_value_enabled() {
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
|
||||
input.expect_ident_matching("context-value")?;
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
/// A value of <length> | <percentage> | <number> for stroke-dashoffset.
|
||||
/// <https://www.w3.org/TR/SVG11/painting.html#StrokeProperties>
|
||||
pub type SvgLengthPercentageOrNumber =
|
||||
|
@ -56,18 +31,6 @@ pub type SvgLengthPercentageOrNumber =
|
|||
/// <length> | <percentage> | <number> | context-value
|
||||
pub type SVGLength = generic::SVGLength<SvgLengthPercentageOrNumber>;
|
||||
|
||||
impl Parse for SVGLength {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
input
|
||||
.try(|i| SvgLengthPercentageOrNumber::parse(context, i))
|
||||
.map(Into::into)
|
||||
.or_else(|_| parse_context_value(input, generic::SVGLength::ContextValue))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SvgLengthPercentageOrNumber> for SVGLength {
|
||||
fn from(length: SvgLengthPercentageOrNumber) -> Self {
|
||||
generic::SVGLength::Length(length)
|
||||
|
@ -82,18 +45,6 @@ pub type NonNegativeSvgLengthPercentageOrNumber =
|
|||
/// A non-negative version of SVGLength.
|
||||
pub type SVGWidth = generic::SVGLength<NonNegativeSvgLengthPercentageOrNumber>;
|
||||
|
||||
impl Parse for SVGWidth {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
input
|
||||
.try(|i| NonNegativeSvgLengthPercentageOrNumber::parse(context, i))
|
||||
.map(Into::into)
|
||||
.or_else(|_| parse_context_value(input, generic::SVGLength::ContextValue))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NonNegativeSvgLengthPercentageOrNumber> for SVGWidth {
|
||||
fn from(length: NonNegativeSvgLengthPercentageOrNumber) -> Self {
|
||||
generic::SVGLength::Length(length)
|
||||
|
@ -113,11 +64,14 @@ impl Parse for SVGStrokeDashArray {
|
|||
NonNegativeSvgLengthPercentageOrNumber::parse(context, i)
|
||||
})
|
||||
}) {
|
||||
Ok(generic::SVGStrokeDashArray::Values(values))
|
||||
} else if let Ok(_) = input.try(|i| i.expect_ident_matching("none")) {
|
||||
Ok(generic::SVGStrokeDashArray::Values(vec![]))
|
||||
} else {
|
||||
parse_context_value(input, generic::SVGStrokeDashArray::ContextValue)
|
||||
return Ok(generic::SVGStrokeDashArray::Values(values));
|
||||
}
|
||||
|
||||
try_match_ident_ignore_ascii_case! { input,
|
||||
"context-value" if generic::is_context_value_enabled(context) => {
|
||||
Ok(generic::SVGStrokeDashArray::ContextValue)
|
||||
},
|
||||
"none" => Ok(generic::SVGStrokeDashArray::Values(vec![])),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -125,22 +79,6 @@ impl Parse for SVGStrokeDashArray {
|
|||
/// <opacity-value> | context-fill-opacity | context-stroke-opacity
|
||||
pub type SVGOpacity = generic::SVGOpacity<Opacity>;
|
||||
|
||||
impl Parse for SVGOpacity {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(opacity) = input.try(|i| Opacity::parse(context, i)) {
|
||||
return Ok(generic::SVGOpacity::Opacity(opacity));
|
||||
}
|
||||
|
||||
try_match_ident_ignore_ascii_case! { input,
|
||||
"context-fill-opacity" => Ok(generic::SVGOpacity::ContextFillOpacity),
|
||||
"context-stroke-opacity" => Ok(generic::SVGOpacity::ContextStrokeOpacity),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The specified value for a single CSS paint-order property.
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, ToCss)]
|
||||
|
|
|
@ -13,11 +13,10 @@ use crate::values::computed::text::TextOverflow as ComputedTextOverflow;
|
|||
use crate::values::computed::{Context, ToComputedValue};
|
||||
use crate::values::generics::text::InitialLetter as GenericInitialLetter;
|
||||
use crate::values::generics::text::LineHeight as GenericLineHeight;
|
||||
use crate::values::generics::text::MozTabSize as GenericMozTabSize;
|
||||
use crate::values::generics::text::Spacing;
|
||||
use crate::values::specified::length::NonNegativeLengthPercentage;
|
||||
use crate::values::specified::length::{FontRelativeLength, Length};
|
||||
use crate::values::specified::length::{LengthPercentage, NoCalcLength};
|
||||
use crate::values::specified::length::{NonNegativeLength, NonNegativeLengthPercentage};
|
||||
use crate::values::specified::{AllowQuirks, Integer, NonNegativeNumber, Number};
|
||||
use cssparser::{Parser, Token};
|
||||
use selectors::parser::SelectorParseErrorKind;
|
||||
|
@ -420,7 +419,7 @@ pub enum TextAlignKeyword {
|
|||
|
||||
/// Specified value of text-align property.
|
||||
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, SpecifiedValueInfo, ToCss)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, Parse, PartialEq, SpecifiedValueInfo, ToCss)]
|
||||
pub enum TextAlign {
|
||||
/// Keyword value of text-align property.
|
||||
Keyword(TextAlignKeyword),
|
||||
|
@ -436,27 +435,6 @@ pub enum TextAlign {
|
|||
MozCenterOrInherit,
|
||||
}
|
||||
|
||||
impl Parse for TextAlign {
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
// MozCenterOrInherit cannot be parsed, only set directly on the elements
|
||||
if let Ok(key) = input.try(TextAlignKeyword::parse) {
|
||||
return Ok(TextAlign::Keyword(key));
|
||||
}
|
||||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
input.expect_ident_matching("match-parent")?;
|
||||
return Ok(TextAlign::MatchParent);
|
||||
}
|
||||
#[cfg(feature = "servo")]
|
||||
{
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TextAlign {
|
||||
/// Convert an enumerated value coming from Gecko to a `TextAlign`.
|
||||
#[cfg(feature = "gecko")]
|
||||
|
@ -835,25 +813,6 @@ impl From<TextEmphasisPosition> for u8 {
|
|||
}
|
||||
}
|
||||
|
||||
/// A specified value for the `-moz-tab-size` property.
|
||||
pub type MozTabSize = GenericMozTabSize<NonNegativeNumber, NonNegativeLength>;
|
||||
|
||||
impl Parse for MozTabSize {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(number) = input.try(|i| NonNegativeNumber::parse(context, i)) {
|
||||
// Numbers need to be parsed first because `0` must be recognised
|
||||
// as the number `0` and not the length `0px`.
|
||||
return Ok(GenericMozTabSize::Number(number));
|
||||
}
|
||||
Ok(GenericMozTabSize::Length(NonNegativeLength::parse(
|
||||
context, input,
|
||||
)?))
|
||||
}
|
||||
}
|
||||
|
||||
/// Values for the `overflow-wrap` property.
|
||||
#[repr(u8)]
|
||||
#[derive(
|
||||
|
|
|
@ -231,7 +231,7 @@ impl Parse for Transform {
|
|||
}
|
||||
|
||||
/// The specified value of a component of a CSS `<transform-origin>`.
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)]
|
||||
#[derive(Clone, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss)]
|
||||
pub enum OriginComponent<S> {
|
||||
/// `center`
|
||||
Center,
|
||||
|
@ -295,25 +295,6 @@ impl Parse for TransformOrigin {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S> Parse for OriginComponent<S>
|
||||
where
|
||||
S: Parse,
|
||||
{
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if input.try(|i| i.expect_ident_matching("center")).is_ok() {
|
||||
return Ok(OriginComponent::Center);
|
||||
}
|
||||
if let Ok(lp) = input.try(|i| LengthPercentage::parse(context, i)) {
|
||||
return Ok(OriginComponent::Length(lp));
|
||||
}
|
||||
let keyword = S::parse(context, input)?;
|
||||
Ok(OriginComponent::Side(keyword))
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> ToComputedValue for OriginComponent<S>
|
||||
where
|
||||
S: Side,
|
||||
|
|
|
@ -9,14 +9,10 @@ use crate::values::generics::ui as generics;
|
|||
use crate::values::specified::color::Color;
|
||||
use crate::values::specified::url::SpecifiedImageUrl;
|
||||
use crate::values::specified::Number;
|
||||
use crate::values::{Auto, Either};
|
||||
use cssparser::Parser;
|
||||
use std::fmt::{self, Write};
|
||||
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
||||
|
||||
/// auto | <color>
|
||||
pub type ColorOrAuto = Either<Color, Auto>;
|
||||
|
||||
/// A specified value for the `cursor` property.
|
||||
pub type Cursor = generics::Cursor<CursorImage>;
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
use crate::cg;
|
||||
use crate::to_css::CssVariantAttrs;
|
||||
use proc_macro2::TokenStream;
|
||||
use syn::{DeriveInput, Path};
|
||||
use synstructure;
|
||||
use syn::{self, DeriveInput, Path};
|
||||
use synstructure::{Structure, VariantInfo};
|
||||
|
||||
#[darling(attributes(parse), default)]
|
||||
#[derive(Default, FromVariant)]
|
||||
|
@ -15,22 +15,90 @@ pub struct ParseVariantAttrs {
|
|||
pub condition: Option<Path>,
|
||||
}
|
||||
|
||||
pub fn derive(input: DeriveInput) -> TokenStream {
|
||||
fn parse_non_keyword_variant(
|
||||
name: &syn::Ident,
|
||||
variant: &VariantInfo,
|
||||
variant_attrs: &CssVariantAttrs,
|
||||
parse_attrs: &ParseVariantAttrs,
|
||||
skip_try: bool,
|
||||
) -> TokenStream {
|
||||
let bindings = variant.bindings();
|
||||
assert!(parse_attrs.aliases.is_none());
|
||||
assert!(variant_attrs.function.is_none());
|
||||
assert!(variant_attrs.keyword.is_none());
|
||||
assert_eq!(
|
||||
bindings.len(),
|
||||
1,
|
||||
"We only support deriving parse for simple variants"
|
||||
);
|
||||
let variant_name = &variant.ast().ident;
|
||||
let ty = &bindings[0].ast().ty;
|
||||
let mut parse = if skip_try {
|
||||
quote! {
|
||||
let v = <#ty as crate::parser::Parse>::parse(context, input)?;
|
||||
return Ok(#name::#variant_name(v));
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
if let Ok(v) = input.try(|i| <#ty as crate::parser::Parse>::parse(context, i)) {
|
||||
return Ok(#name::#variant_name(v));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(ref condition) = parse_attrs.condition {
|
||||
parse = quote! {
|
||||
if #condition(context) {
|
||||
#parse
|
||||
}
|
||||
};
|
||||
|
||||
if skip_try {
|
||||
// We're the last variant and we can fail to parse due to the
|
||||
// condition clause. If that happens, we need to return an error.
|
||||
parse = quote! {
|
||||
#parse
|
||||
Err(input.new_custom_error(style_traits::StyleParseErrorKind::UnspecifiedError))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
parse
|
||||
}
|
||||
|
||||
pub fn derive(mut input: DeriveInput) -> TokenStream {
|
||||
{
|
||||
let mut where_clause = input.generics.where_clause.take();
|
||||
for param in input.generics.type_params() {
|
||||
cg::add_predicate(
|
||||
&mut where_clause,
|
||||
parse_quote!(#param: crate::parser::Parse),
|
||||
);
|
||||
}
|
||||
input.generics.where_clause = where_clause;
|
||||
}
|
||||
|
||||
let name = &input.ident;
|
||||
let s = synstructure::Structure::new(&input);
|
||||
let s = Structure::new(&input);
|
||||
|
||||
let mut saw_condition = false;
|
||||
let match_body = s.variants().iter().fold(quote!(), |match_body, variant| {
|
||||
let bindings = variant.bindings();
|
||||
assert!(
|
||||
bindings.is_empty(),
|
||||
"Parse is only supported for single-variant enums for now"
|
||||
);
|
||||
let mut match_keywords = quote! {};
|
||||
let mut non_keywords = vec![];
|
||||
|
||||
let mut effective_variants = 0;
|
||||
for variant in s.variants().iter() {
|
||||
let css_variant_attrs = cg::parse_variant_attrs_from_ast::<CssVariantAttrs>(&variant.ast());
|
||||
let parse_attrs = cg::parse_variant_attrs_from_ast::<ParseVariantAttrs>(&variant.ast());
|
||||
if css_variant_attrs.skip {
|
||||
return match_body;
|
||||
continue;
|
||||
}
|
||||
effective_variants += 1;
|
||||
|
||||
saw_condition |= parse_attrs.condition.is_some();
|
||||
|
||||
if !variant.bindings().is_empty() {
|
||||
non_keywords.push((variant, css_variant_attrs, parse_attrs));
|
||||
continue;
|
||||
}
|
||||
|
||||
let identifier = cg::to_css_identifier(
|
||||
|
@ -40,55 +108,73 @@ pub fn derive(input: DeriveInput) -> TokenStream {
|
|||
);
|
||||
let ident = &variant.ast().ident;
|
||||
|
||||
saw_condition |= parse_attrs.condition.is_some();
|
||||
let condition = match parse_attrs.condition {
|
||||
Some(ref p) => quote! { if #p(context) },
|
||||
None => quote! {},
|
||||
};
|
||||
|
||||
let mut body = quote! {
|
||||
#match_body
|
||||
match_keywords.extend(quote! {
|
||||
#identifier #condition => Ok(#name::#ident),
|
||||
};
|
||||
});
|
||||
|
||||
let aliases = match parse_attrs.aliases {
|
||||
Some(aliases) => aliases,
|
||||
None => return body,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
for alias in aliases.split(',') {
|
||||
body = quote! {
|
||||
#body
|
||||
match_keywords.extend(quote! {
|
||||
#alias #condition => Ok(#name::#ident),
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
body
|
||||
});
|
||||
let needs_context = saw_condition || !non_keywords.is_empty();
|
||||
|
||||
let context_ident = if saw_condition {
|
||||
let context_ident = if needs_context {
|
||||
quote! { context }
|
||||
} else {
|
||||
quote! { _ }
|
||||
};
|
||||
|
||||
let parse_body = if saw_condition {
|
||||
quote! {
|
||||
let location = input.current_source_location();
|
||||
let ident = input.expect_ident()?;
|
||||
match_ignore_ascii_case! { &ident,
|
||||
#match_body
|
||||
_ => Err(location.new_unexpected_token_error(
|
||||
cssparser::Token::Ident(ident.clone())
|
||||
))
|
||||
let has_keywords = non_keywords.len() != effective_variants;
|
||||
|
||||
let mut parse_non_keywords = quote! {};
|
||||
for (i, (variant, css_attrs, parse_attrs)) in non_keywords.iter().enumerate() {
|
||||
let skip_try = !has_keywords && i == non_keywords.len() - 1;
|
||||
let parse_variant =
|
||||
parse_non_keyword_variant(name, variant, css_attrs, parse_attrs, skip_try);
|
||||
parse_non_keywords.extend(parse_variant);
|
||||
}
|
||||
|
||||
let parse_body = if needs_context {
|
||||
let parse_keywords = if has_keywords {
|
||||
quote! {
|
||||
let location = input.current_source_location();
|
||||
let ident = input.expect_ident()?;
|
||||
match_ignore_ascii_case! { &ident,
|
||||
#match_keywords
|
||||
_ => Err(location.new_unexpected_token_error(
|
||||
cssparser::Token::Ident(ident.clone())
|
||||
))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {}
|
||||
};
|
||||
|
||||
quote! {
|
||||
#parse_non_keywords
|
||||
#parse_keywords
|
||||
}
|
||||
} else {
|
||||
quote! { Self::parse(input) }
|
||||
};
|
||||
|
||||
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
|
||||
|
||||
let parse_trait_impl = quote! {
|
||||
impl crate::parser::Parse for #name {
|
||||
impl #impl_generics crate::parser::Parse for #name #ty_generics #where_clause {
|
||||
#[inline]
|
||||
fn parse<'i, 't>(
|
||||
#context_ident: &crate::parser::ParserContext,
|
||||
|
@ -99,10 +185,12 @@ pub fn derive(input: DeriveInput) -> TokenStream {
|
|||
}
|
||||
};
|
||||
|
||||
if saw_condition {
|
||||
if needs_context {
|
||||
return parse_trait_impl;
|
||||
}
|
||||
|
||||
assert!(non_keywords.is_empty());
|
||||
|
||||
// TODO(emilio): It'd be nice to get rid of these, but that makes the
|
||||
// conversion harder...
|
||||
let methods_impl = quote! {
|
||||
|
@ -125,7 +213,7 @@ pub fn derive(input: DeriveInput) -> TokenStream {
|
|||
#[inline]
|
||||
pub fn from_ident(ident: &str) -> Result<Self, ()> {
|
||||
match_ignore_ascii_case! { ident,
|
||||
#match_body
|
||||
#match_keywords
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue