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

style: Sync changes from mozilla-central.

See each individual commit for details.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22861)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2019-02-10 17:00:26 -05:00 committed by GitHub
commit aeeaf9dda1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 665 additions and 795 deletions

View file

@ -67,7 +67,9 @@ use style::context::SharedStyleContext;
use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect, LogicalSize, WritingMode}; use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect, LogicalSize, WritingMode};
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::ServoRestyleDamage;
use style::values::computed::{LengthPercentageOrAuto, LengthPercentageOrNone}; use style::values::computed::{
LengthPercentageOrAuto, MaxLength, NonNegativeLengthPercentageOrAuto,
};
/// Information specific to floated blocks. /// Information specific to floated blocks.
#[derive(Clone, Serialize)] #[derive(Clone, Serialize)]
@ -419,15 +421,15 @@ impl CandidateBSizeIterator {
// `min-height` and `max-height`, percentage values are ignored. // `min-height` and `max-height`, percentage values are ignored.
let block_size = match fragment.style.content_block_size() { let block_size = match fragment.style.content_block_size() {
LengthPercentageOrAuto::Auto => MaybeAuto::Auto, NonNegativeLengthPercentageOrAuto::Auto => MaybeAuto::Auto,
LengthPercentageOrAuto::LengthPercentage(ref lp) => { NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => {
MaybeAuto::from_option(lp.maybe_to_used_value(block_container_block_size)) MaybeAuto::from_option(lp.maybe_to_used_value(block_container_block_size))
}, },
}; };
let max_block_size = match fragment.style.max_block_size() { let max_block_size = match fragment.style.max_block_size() {
LengthPercentageOrNone::None => None, MaxLength::None => None,
LengthPercentageOrNone::LengthPercentage(ref lp) => { MaxLength::LengthPercentage(ref lp) => {
lp.maybe_to_used_value(block_container_block_size) lp.maybe_to_used_value(block_container_block_size)
}, },
}; };
@ -1400,7 +1402,7 @@ impl BlockFlow {
let content_block_size = self.fragment.style().content_block_size(); let content_block_size = self.fragment.style().content_block_size();
match content_block_size { match content_block_size {
LengthPercentageOrAuto::Auto => { NonNegativeLengthPercentageOrAuto::Auto => {
let container_size = containing_block_size?; let container_size = containing_block_size?;
let (block_start, block_end) = { let (block_start, block_end) = {
let position = self.fragment.style().logical_position(); let position = self.fragment.style().logical_position();
@ -1435,7 +1437,7 @@ impl BlockFlow {
(_, _) => None, (_, _) => None,
} }
}, },
LengthPercentageOrAuto::LengthPercentage(ref lp) => { NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => {
lp.maybe_to_used_value(containing_block_size) lp.maybe_to_used_value(containing_block_size)
}, },
} }
@ -1797,15 +1799,12 @@ impl BlockFlow {
.to_used_value(self.base.block_container_inline_size); .to_used_value(self.base.block_container_inline_size);
let specified_inline_size = self.fragment.style().content_inline_size(); let specified_inline_size = self.fragment.style().content_inline_size();
let container_size = self.base.block_container_inline_size; let container_size = self.base.block_container_inline_size;
let inline_size = if let MaybeAuto::Specified(size) = let inline_size = match specified_inline_size.to_used_value(container_size) {
MaybeAuto::from_style(specified_inline_size, container_size) Some(size) => match self.fragment.style().get_position().box_sizing {
{
match self.fragment.style().get_position().box_sizing {
BoxSizing::BorderBox => size, BoxSizing::BorderBox => size,
BoxSizing::ContentBox => size + self.fragment.border_padding.inline_start_end(), BoxSizing::ContentBox => size + self.fragment.border_padding.inline_start_end(),
} },
} else { None => max(min_inline_size, min(available_inline_size, max_inline_size)),
max(min_inline_size, min(available_inline_size, max_inline_size))
}; };
self.base.position.size.inline = inline_size + self.fragment.margin.inline_start_end(); self.base.position.size.inline = inline_size + self.fragment.margin.inline_start_end();
@ -2026,7 +2025,7 @@ impl BlockFlow {
// If `max-width` is set, then don't perform this speculation. We guess that the // If `max-width` is set, then don't perform this speculation. We guess that the
// page set `max-width` in order to avoid hitting floats. The search box on Google // page set `max-width` in order to avoid hitting floats. The search box on Google
// SERPs falls into this category. // SERPs falls into this category.
if self.fragment.style.max_inline_size() != LengthPercentageOrNone::None { if self.fragment.style.max_inline_size() != MaxLength::None {
return; return;
} }
@ -2156,9 +2155,10 @@ impl Flow for BlockFlow {
fn bubble_inline_sizes(&mut self) { fn bubble_inline_sizes(&mut self) {
// If this block has a fixed width, just use that for the minimum and preferred width, // If this block has a fixed width, just use that for the minimum and preferred width,
// rather than bubbling up children inline width. // rather than bubbling up children inline width.
// FIXME(emilio): This should probably be writing-mode-aware.
let consult_children = match self.fragment.style().get_position().width { let consult_children = match self.fragment.style().get_position().width {
LengthPercentageOrAuto::Auto => true, NonNegativeLengthPercentageOrAuto::Auto => true,
LengthPercentageOrAuto::LengthPercentage(ref lp) => { NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => {
lp.maybe_to_used_value(None).is_none() lp.maybe_to_used_value(None).is_none()
}, },
}; };
@ -2846,9 +2846,16 @@ pub trait ISizeAndMarginsComputer {
parent_flow_inline_size: Au, parent_flow_inline_size: Au,
shared_context: &SharedStyleContext, shared_context: &SharedStyleContext,
) -> MaybeAuto { ) -> MaybeAuto {
MaybeAuto::from_style( MaybeAuto::from_option(
block.fragment().style().content_inline_size(), block
self.containing_block_inline_size(block, parent_flow_inline_size, shared_context), .fragment()
.style()
.content_inline_size()
.to_used_value(self.containing_block_inline_size(
block,
parent_flow_inline_size,
shared_context,
)),
) )
} }

View file

@ -5,16 +5,14 @@
// FIXME(rust-lang/rust#26264): Remove GenericBackgroundSize. // FIXME(rust-lang/rust#26264): Remove GenericBackgroundSize.
use crate::display_list::border; use crate::display_list::border;
use crate::model::MaybeAuto;
use app_units::Au; use app_units::Au;
use euclid::{Point2D, Rect, SideOffsets2D, Size2D}; use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
use style::computed_values::background_attachment::single_value::T as BackgroundAttachment; use style::computed_values::background_attachment::single_value::T as BackgroundAttachment;
use style::computed_values::background_clip::single_value::T as BackgroundClip; use style::computed_values::background_clip::single_value::T as BackgroundClip;
use style::computed_values::background_origin::single_value::T as BackgroundOrigin; use style::computed_values::background_origin::single_value::T as BackgroundOrigin;
use style::properties::style_structs::Background; use style::properties::style_structs::Background;
use style::values::computed::{BackgroundSize, LengthPercentageOrAuto}; use style::values::computed::{BackgroundSize, NonNegativeLengthPercentageOrAuto};
use style::values::generics::background::BackgroundSize as GenericBackgroundSize; use style::values::generics::background::BackgroundSize as GenericBackgroundSize;
use style::values::generics::NonNegative;
use style::values::specified::background::BackgroundRepeatKeyword; use style::values::specified::background::BackgroundRepeatKeyword;
use webrender_api::BorderRadius; use webrender_api::BorderRadius;
@ -60,10 +58,12 @@ fn compute_background_image_size(
None => match bg_size { None => match bg_size {
GenericBackgroundSize::Cover | GenericBackgroundSize::Contain => bounds_size, GenericBackgroundSize::Cover | GenericBackgroundSize::Contain => bounds_size,
GenericBackgroundSize::Explicit { width, height } => Size2D::new( GenericBackgroundSize::Explicit { width, height } => Size2D::new(
MaybeAuto::from_style(width.0, bounds_size.width) width
.specified_or_default(bounds_size.width), .to_used_value(bounds_size.width)
MaybeAuto::from_style(height.0, bounds_size.height) .unwrap_or(bounds_size.width),
.specified_or_default(bounds_size.height), height
.to_used_value(bounds_size.height)
.unwrap_or(bounds_size.height),
), ),
}, },
Some(own_size) => { Some(own_size) => {
@ -88,30 +88,34 @@ fn compute_background_image_size(
( (
GenericBackgroundSize::Explicit { GenericBackgroundSize::Explicit {
width, width,
height: NonNegative(LengthPercentageOrAuto::Auto), height: NonNegativeLengthPercentageOrAuto::Auto,
}, },
_, _,
) => { ) => {
let width = MaybeAuto::from_style(width.0, bounds_size.width) let width = width
.specified_or_default(own_size.width); .to_used_value(bounds_size.width)
.unwrap_or(own_size.width);
Size2D::new(width, width.scale_by(image_aspect_ratio.recip())) Size2D::new(width, width.scale_by(image_aspect_ratio.recip()))
}, },
( (
GenericBackgroundSize::Explicit { GenericBackgroundSize::Explicit {
width: NonNegative(LengthPercentageOrAuto::Auto), width: NonNegativeLengthPercentageOrAuto::Auto,
height, height,
}, },
_, _,
) => { ) => {
let height = MaybeAuto::from_style(height.0, bounds_size.height) let height = height
.specified_or_default(own_size.height); .to_used_value(bounds_size.height)
.unwrap_or(own_size.height);
Size2D::new(height.scale_by(image_aspect_ratio), height) Size2D::new(height.scale_by(image_aspect_ratio), height)
}, },
(GenericBackgroundSize::Explicit { width, height }, _) => Size2D::new( (GenericBackgroundSize::Explicit { width, height }, _) => Size2D::new(
MaybeAuto::from_style(width.0, bounds_size.width) width
.specified_or_default(own_size.width), .to_used_value(bounds_size.width)
MaybeAuto::from_style(height.0, bounds_size.height) .unwrap_or(own_size.width),
.specified_or_default(own_size.height), height
.to_used_value(bounds_size.height)
.unwrap_or(own_size.height),
), ),
} }
}, },

View file

@ -764,10 +764,12 @@ impl Fragment {
get_cyclic(&style.get_background().background_size.0, i).clone(); get_cyclic(&style.get_background().background_size.0, i).clone();
let size = match background_size { let size = match background_size {
BackgroundSize::Explicit { width, height } => Size2D::new( BackgroundSize::Explicit { width, height } => Size2D::new(
MaybeAuto::from_style(width.0, bounding_box_size.width) width
.specified_or_default(bounding_box_size.width), .to_used_value(bounding_box_size.width)
MaybeAuto::from_style(height.0, bounding_box_size.height) .unwrap_or(bounding_box_size.width),
.specified_or_default(bounding_box_size.height), height
.to_used_value(bounding_box_size.height)
.unwrap_or(bounding_box_size.height),
), ),
_ => bounding_box_size, _ => bounding_box_size,
}; };

View file

@ -29,7 +29,9 @@ use style::logical_geometry::{Direction, LogicalSize};
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::ServoRestyleDamage;
use style::values::computed::flex::FlexBasis; use style::values::computed::flex::FlexBasis;
use style::values::computed::{LengthPercentage, LengthPercentageOrAuto, LengthPercentageOrNone}; use style::values::computed::{
MaxLength, NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto,
};
use style::values::generics::flex::FlexBasis as GenericFlexBasis; use style::values::generics::flex::FlexBasis as GenericFlexBasis;
/// The size of an axis. May be a specified size, a min/max /// The size of an axis. May be a specified size, a min/max
@ -45,16 +47,16 @@ impl AxisSize {
/// Generate a new available cross or main axis size from the specified size of the container, /// Generate a new available cross or main axis size from the specified size of the container,
/// containing block size, min constraint, and max constraint /// containing block size, min constraint, and max constraint
pub fn new( pub fn new(
size: LengthPercentageOrAuto, size: NonNegativeLengthPercentageOrAuto,
content_size: Option<Au>, content_size: Option<Au>,
min: LengthPercentage, min: NonNegativeLengthPercentage,
max: LengthPercentageOrNone, max: MaxLength,
) -> AxisSize { ) -> AxisSize {
match size { match size {
LengthPercentageOrAuto::Auto => { NonNegativeLengthPercentageOrAuto::Auto => {
AxisSize::MinMax(SizeConstraint::new(content_size, min, max, None)) AxisSize::MinMax(SizeConstraint::new(content_size, min, max, None))
}, },
LengthPercentageOrAuto::LengthPercentage(ref lp) => { NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => {
match lp.maybe_to_used_value(content_size) { match lp.maybe_to_used_value(content_size) {
Some(length) => AxisSize::Definite(length), Some(length) => AxisSize::Definite(length),
None => AxisSize::Infinite, None => AxisSize::Infinite,
@ -70,7 +72,7 @@ impl AxisSize {
/// is definite after flex size resolving. /// is definite after flex size resolving.
fn from_flex_basis( fn from_flex_basis(
flex_basis: FlexBasis, flex_basis: FlexBasis,
main_length: LengthPercentageOrAuto, main_length: NonNegativeLengthPercentageOrAuto,
containing_length: Au, containing_length: Au,
) -> MaybeAuto { ) -> MaybeAuto {
let width = match flex_basis { let width = match flex_basis {
@ -78,9 +80,16 @@ fn from_flex_basis(
GenericFlexBasis::Width(width) => width, GenericFlexBasis::Width(width) => width,
}; };
match width.0 { let width = match width {
LengthPercentageOrAuto::Auto => MaybeAuto::from_style(main_length, containing_length), NonNegativeLengthPercentageOrAuto::Auto => main_length,
other => MaybeAuto::from_style(other, containing_length), _ => width,
};
match width {
NonNegativeLengthPercentageOrAuto::Auto => MaybeAuto::Auto,
NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => {
MaybeAuto::Specified(lp.to_used_value(containing_length))
},
} }
} }
@ -224,18 +233,18 @@ impl FlexItem {
let mut margin_count = 0; let mut margin_count = 0;
match direction { match direction {
Direction::Inline => { Direction::Inline => {
if margin.inline_start == LengthPercentageOrAuto::Auto { if margin.inline_start.is_auto() {
margin_count += 1; margin_count += 1;
} }
if margin.inline_end == LengthPercentageOrAuto::Auto { if margin.inline_end.is_auto() {
margin_count += 1; margin_count += 1;
} }
}, },
Direction::Block => { Direction::Block => {
if margin.block_start == LengthPercentageOrAuto::Auto { if margin.block_start.is_auto() {
margin_count += 1; margin_count += 1;
} }
if margin.block_end == LengthPercentageOrAuto::Auto { if margin.block_end.is_auto() {
margin_count += 1; margin_count += 1;
} }
}, },
@ -816,7 +825,7 @@ impl FlexFlow {
// cross size of item should equal to the line size if any auto margin exists. // cross size of item should equal to the line size if any auto margin exists.
// https://drafts.csswg.org/css-flexbox/#algo-cross-margins // https://drafts.csswg.org/css-flexbox/#algo-cross-margins
if auto_margin_count > 0 { if auto_margin_count > 0 {
if margin.block_start == LengthPercentageOrAuto::Auto { if margin.block_start.is_auto() {
margin_block_start = if free_space < Au(0) { margin_block_start = if free_space < Au(0) {
Au(0) Au(0)
} else { } else {
@ -830,7 +839,7 @@ impl FlexFlow {
let self_align = block.fragment.style().get_position().align_self; let self_align = block.fragment.style().get_position().align_self;
if self_align == AlignSelf::Stretch && if self_align == AlignSelf::Stretch &&
block.fragment.style().content_block_size() == LengthPercentageOrAuto::Auto block.fragment.style().content_block_size().is_auto()
{ {
free_space = Au(0); free_space = Au(0);
block.base.block_container_explicit_block_size = Some(line.cross_size); block.base.block_container_explicit_block_size = Some(line.cross_size);

View file

@ -10,7 +10,7 @@ use std::cmp::{max, min};
use std::fmt; use std::fmt;
use style::computed_values::float::T as StyleFloat; use style::computed_values::float::T as StyleFloat;
use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode}; use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
use style::values::computed::LengthPercentageOrAuto; use style::values::computed::NonNegativeLengthPercentageOrAuto;
/// The kind of float: left or right. /// The kind of float: left or right.
#[derive(Clone, Copy, Debug, Serialize)] #[derive(Clone, Copy, Debug, Serialize)]
@ -549,9 +549,9 @@ impl SpeculatedFloatPlacement {
// might flow around this float. // might flow around this float.
let inline_size = flow.as_block().fragment.style.content_inline_size(); let inline_size = flow.as_block().fragment.style.content_inline_size();
let fixed = match inline_size { let fixed = match inline_size {
LengthPercentageOrAuto::Auto => false, NonNegativeLengthPercentageOrAuto::Auto => false,
LengthPercentageOrAuto::LengthPercentage(ref lp) => { NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => {
lp.is_definitely_zero() || lp.maybe_to_used_value(None).is_some() lp.0.is_definitely_zero() || lp.0.maybe_to_used_value(None).is_some()
}, },
}; };
if !fixed { if !fixed {

View file

@ -61,7 +61,9 @@ use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::ServoRestyleDamage;
use style::str::char_is_whitespace; use style::str::char_is_whitespace;
use style::values::computed::counters::ContentItem; use style::values::computed::counters::ContentItem;
use style::values::computed::{LengthPercentage, LengthPercentageOrAuto}; use style::values::computed::{
LengthPercentage, LengthPercentageOrAuto, NonNegativeLengthPercentageOrAuto,
};
use style::values::generics::box_::{Perspective, VerticalAlign}; use style::values::generics::box_::{Perspective, VerticalAlign};
use style::values::generics::transform; use style::values::generics::transform;
use webrender_api::{self, LayoutTransform}; use webrender_api::{self, LayoutTransform};
@ -985,8 +987,10 @@ impl Fragment {
if flags.contains( if flags.contains(
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED, QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED,
) { ) {
specified = specified = style
MaybeAuto::from_style(style.content_inline_size(), Au(0)).specified_or_zero(); .content_inline_size()
.to_used_value(Au(0))
.unwrap_or(Au(0));
specified = max(style.min_inline_size().to_used_value(Au(0)), specified); specified = max(style.min_inline_size().to_used_value(Au(0)), specified);
if let Some(max) = style.max_inline_size().to_used_value(Au(0)) { if let Some(max) = style.max_inline_size().to_used_value(Au(0)) {
specified = min(specified, max) specified = min(specified, max)
@ -1611,8 +1615,8 @@ impl Fragment {
SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Iframe(_) |
SpecificFragmentInfo::Svg(_) => { SpecificFragmentInfo::Svg(_) => {
let inline_size = match self.style.content_inline_size() { let inline_size = match self.style.content_inline_size() {
LengthPercentageOrAuto::Auto => None, NonNegativeLengthPercentageOrAuto::Auto => None,
LengthPercentageOrAuto::LengthPercentage(ref lp) => { NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => {
lp.maybe_to_used_value(None) lp.maybe_to_used_value(None)
}, },
}; };

View file

@ -3,6 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
#![deny(unsafe_code)] #![deny(unsafe_code)]
#![feature(type_alias_enum_variants)]
#[macro_use] #[macro_use]
extern crate bitflags; extern crate bitflags;

View file

@ -11,8 +11,10 @@ use std::cmp::{max, min};
use std::fmt; use std::fmt;
use style::logical_geometry::{LogicalMargin, WritingMode}; use style::logical_geometry::{LogicalMargin, WritingMode};
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::values::computed::LengthPercentageOrNone; use style::values::computed::MaxLength;
use style::values::computed::{LengthPercentage, LengthPercentageOrAuto}; use style::values::computed::{
LengthPercentageOrAuto, NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto,
};
/// A collapsible margin. See CSS 2.1 § 8.3.1. /// A collapsible margin. See CSS 2.1 § 8.3.1.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
@ -135,8 +137,8 @@ impl MarginCollapseInfo {
MarginCollapseState::AccumulatingCollapsibleTopMargin => { MarginCollapseState::AccumulatingCollapsibleTopMargin => {
may_collapse_through = may_collapse_through && may_collapse_through = may_collapse_through &&
match fragment.style().content_block_size() { match fragment.style().content_block_size() {
LengthPercentageOrAuto::Auto => true, NonNegativeLengthPercentageOrAuto::Auto => true,
LengthPercentageOrAuto::LengthPercentage(ref lp) => { NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => {
lp.is_definitely_zero() || lp.is_definitely_zero() ||
lp.maybe_to_used_value(containing_block_size).is_none() lp.maybe_to_used_value(containing_block_size).is_none()
}, },
@ -496,11 +498,14 @@ impl MaybeAuto {
/// Receive an optional container size and return used value for width or height. /// Receive an optional container size and return used value for width or height.
/// ///
/// `style_length`: content size as given in the CSS. /// `style_length`: content size as given in the CSS.
pub fn style_length(style_length: LengthPercentageOrAuto, container_size: Option<Au>) -> MaybeAuto { pub fn style_length(
style_length: NonNegativeLengthPercentageOrAuto,
container_size: Option<Au>,
) -> MaybeAuto {
match style_length { match style_length {
LengthPercentageOrAuto::Auto => MaybeAuto::Auto, NonNegativeLengthPercentageOrAuto::Auto => MaybeAuto::Auto,
LengthPercentageOrAuto::LengthPercentage(ref lp) => { NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => {
MaybeAuto::from_option(lp.maybe_to_used_value(container_size)) MaybeAuto::from_option(lp.0.maybe_to_used_value(container_size))
}, },
} }
} }
@ -566,8 +571,8 @@ impl SizeConstraint {
/// Create a `SizeConstraint` for an axis. /// Create a `SizeConstraint` for an axis.
pub fn new( pub fn new(
container_size: Option<Au>, container_size: Option<Au>,
min_size: LengthPercentage, min_size: NonNegativeLengthPercentage,
max_size: LengthPercentageOrNone, max_size: MaxLength,
border: Option<Au>, border: Option<Au>,
) -> SizeConstraint { ) -> SizeConstraint {
let mut min_size = min_size let mut min_size = min_size
@ -575,10 +580,8 @@ impl SizeConstraint {
.unwrap_or(Au(0)); .unwrap_or(Au(0));
let mut max_size = match max_size { let mut max_size = match max_size {
LengthPercentageOrNone::None => None, MaxLength::None => None,
LengthPercentageOrNone::LengthPercentage(ref lp) => { MaxLength::LengthPercentage(ref lp) => lp.maybe_to_used_value(container_size),
lp.maybe_to_used_value(container_size)
},
}; };
// Make sure max size is not smaller than min size. // Make sure max size is not smaller than min size.

View file

@ -19,7 +19,7 @@ use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::values::computed::{LengthPercentageOrAuto, LengthPercentageOrNone}; use style::values::computed::{MaxLength, NonNegativeLengthPercentageOrAuto};
use style::values::generics::column::ColumnCount; use style::values::generics::column::ColumnCount;
use style::values::Either; use style::values::Either;
@ -155,16 +155,14 @@ impl Flow for MulticolFlow {
available_block_size: { available_block_size: {
let style = &self.block_flow.fragment.style; let style = &self.block_flow.fragment.style;
let size = match style.content_block_size() { let size = match style.content_block_size() {
LengthPercentageOrAuto::Auto => None, NonNegativeLengthPercentageOrAuto::Auto => None,
LengthPercentageOrAuto::LengthPercentage(ref lp) => { NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => {
lp.maybe_to_used_value(None) lp.maybe_to_used_value(None)
}, },
}; };
let size = size.or_else(|| match style.max_block_size() { let size = size.or_else(|| match style.max_block_size() {
LengthPercentageOrNone::None => None, MaxLength::None => None,
LengthPercentageOrNone::LengthPercentage(ref lp) => { MaxLength::LengthPercentage(ref lp) => lp.maybe_to_used_value(None),
lp.maybe_to_used_value(None)
},
}); });
size.unwrap_or_else(|| { size.unwrap_or_else(|| {

View file

@ -33,7 +33,7 @@ use style::logical_geometry::LogicalSize;
use style::properties::style_structs::Background; use style::properties::style_structs::Background;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::ServoRestyleDamage;
use style::values::computed::LengthPercentageOrAuto; use style::values::computed::NonNegativeLengthPercentageOrAuto;
use style::values::CSSFloat; use style::values::CSSFloat;
#[allow(unsafe_code)] #[allow(unsafe_code)]
@ -301,15 +301,15 @@ impl Flow for TableFlow {
self.column_intrinsic_inline_sizes self.column_intrinsic_inline_sizes
.push(ColumnIntrinsicInlineSize { .push(ColumnIntrinsicInlineSize {
minimum_length: match *specified_inline_size { minimum_length: match *specified_inline_size {
LengthPercentageOrAuto::Auto => Au(0), NonNegativeLengthPercentageOrAuto::Auto => Au(0),
LengthPercentageOrAuto::LengthPercentage(ref lp) => { NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => {
lp.maybe_to_used_value(None).unwrap_or(Au(0)) lp.maybe_to_used_value(None).unwrap_or(Au(0))
}, },
}, },
percentage: match *specified_inline_size { percentage: match *specified_inline_size {
LengthPercentageOrAuto::Auto => 0.0, NonNegativeLengthPercentageOrAuto::Auto => 0.0,
LengthPercentageOrAuto::LengthPercentage(ref lp) => { NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => {
lp.as_percentage().map_or(0.0, |p| p.0) lp.0.as_percentage().map_or(0.0, |p| p.0)
}, },
}, },
preferred: Au(0), preferred: Au(0),

View file

@ -12,7 +12,6 @@ use crate::display_list::{
use crate::flow::{Flow, FlowClass, FlowFlags, GetBaseFlow, OpaqueFlow}; use crate::flow::{Flow, FlowClass, FlowFlags, GetBaseFlow, OpaqueFlow};
use crate::fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; use crate::fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use crate::layout_debug; use crate::layout_debug;
use crate::model::MaybeAuto;
use crate::table::InternalTable; use crate::table::InternalTable;
use crate::table_row::{CollapsedBorder, CollapsedBorderProvenance}; use crate::table_row::{CollapsedBorder, CollapsedBorderProvenance};
use app_units::Au; use app_units::Au;
@ -22,6 +21,7 @@ use script_layout_interface::wrapper_traits::ThreadSafeLayoutNode;
use std::fmt; use std::fmt;
use style::logical_geometry::{LogicalMargin, LogicalRect, LogicalSize, WritingMode}; use style::logical_geometry::{LogicalMargin, LogicalRect, LogicalSize, WritingMode};
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::values::computed::length::NonNegativeLengthPercentageOrAuto;
use style::values::computed::Color; use style::values::computed::Color;
use style::values::generics::box_::VerticalAlign; use style::values::generics::box_::VerticalAlign;
use style::values::specified::BorderStyle; use style::values::specified::BorderStyle;
@ -162,8 +162,12 @@ impl TableCellFlow {
// Call after block size calculation // Call after block size calculation
pub fn total_block_size(&mut self) -> Au { pub fn total_block_size(&mut self) -> Au {
// TODO: Percentage block-size // TODO: Percentage block-size
let specified = MaybeAuto::from_style(self.fragment().style().content_block_size(), Au(0)) let specified = self
.specified_or_zero(); .fragment()
.style()
.content_block_size()
.to_used_value(Au(0))
.unwrap_or(Au(0));
specified + self.fragment().border_padding.block_start_end() specified + self.fragment().border_padding.block_start_end()
} }
} }
@ -198,11 +202,11 @@ impl Flow for TableCellFlow {
); );
self.block_flow.bubble_inline_sizes_for_block(true); self.block_flow.bubble_inline_sizes_for_block(true);
let specified_inline_size = MaybeAuto::from_style( let specified_inline_size = match self.block_flow.fragment.style().content_inline_size() {
self.block_flow.fragment.style().content_inline_size(), NonNegativeLengthPercentageOrAuto::Auto => Au(0),
Au(0), NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => lp.to_used_value(Au(0)),
) };
.specified_or_zero();
if self if self
.block_flow .block_flow
.base .base

View file

@ -14,7 +14,7 @@ use euclid::Point2D;
use std::fmt; use std::fmt;
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::values::computed::LengthPercentageOrAuto; use style::values::computed::NonNegativeLengthPercentageOrAuto;
#[allow(unsafe_code)] #[allow(unsafe_code)]
unsafe impl crate::flow::HasBaseFlow for TableColGroupFlow {} unsafe impl crate::flow::HasBaseFlow for TableColGroupFlow {}
@ -34,7 +34,7 @@ pub struct TableColGroupFlow {
/// The specified inline-sizes of table columns. (We use `LengthPercentageOrAuto` here in /// The specified inline-sizes of table columns. (We use `LengthPercentageOrAuto` here in
/// lieu of `ColumnInlineSize` because column groups do not establish minimum or preferred /// lieu of `ColumnInlineSize` because column groups do not establish minimum or preferred
/// inline sizes.) /// inline sizes.)
pub inline_sizes: Vec<LengthPercentageOrAuto>, pub inline_sizes: Vec<NonNegativeLengthPercentageOrAuto>,
} }
impl TableColGroupFlow { impl TableColGroupFlow {

View file

@ -15,7 +15,6 @@ use crate::flow::{
use crate::flow_list::MutFlowListIterator; use crate::flow_list::MutFlowListIterator;
use crate::fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; use crate::fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use crate::layout_debug; use crate::layout_debug;
use crate::model::MaybeAuto;
use crate::table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, VecExt}; use crate::table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, VecExt};
use crate::table_cell::{CollapsedBordersForCell, TableCellFlow}; use crate::table_cell::{CollapsedBordersForCell, TableCellFlow};
use app_units::Au; use app_units::Au;
@ -30,7 +29,7 @@ use style::computed_values::border_spacing::T as BorderSpacing;
use style::computed_values::border_top_style::T as BorderStyle; use style::computed_values::border_top_style::T as BorderStyle;
use style::logical_geometry::{LogicalSize, PhysicalSide, WritingMode}; use style::logical_geometry::{LogicalSize, PhysicalSide, WritingMode};
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::values::computed::{Color, LengthPercentageOrAuto}; use style::values::computed::{Color, NonNegativeLengthPercentageOrAuto};
#[allow(unsafe_code)] #[allow(unsafe_code)]
unsafe impl crate::flow::HasBaseFlow for TableRowFlow {} unsafe impl crate::flow::HasBaseFlow for TableRowFlow {}
@ -208,16 +207,15 @@ impl TableRowFlow {
&mut max_block_size, &mut max_block_size,
); );
let mut block_size = max_block_size;
// TODO: Percentage block-size // TODO: Percentage block-size
block_size = match MaybeAuto::from_style( let block_size = self
self.block_flow.fragment.style().content_block_size(), .block_flow
Au(0), .fragment
) { .style()
MaybeAuto::Auto => block_size, .content_block_size()
MaybeAuto::Specified(value) => max(value, block_size), .to_used_value(Au(0))
}; .unwrap_or(max_block_size);
block_size max(block_size, max_block_size)
} }
pub fn assign_block_size_to_self_and_children( pub fn assign_block_size_to_self_and_children(
@ -431,23 +429,23 @@ impl Flow for TableRowFlow {
let child_base = kid.mut_base(); let child_base = kid.mut_base();
let child_column_inline_size = ColumnIntrinsicInlineSize { let child_column_inline_size = ColumnIntrinsicInlineSize {
minimum_length: match child_specified_inline_size { minimum_length: match child_specified_inline_size {
LengthPercentageOrAuto::Auto => None, NonNegativeLengthPercentageOrAuto::Auto => None,
LengthPercentageOrAuto::LengthPercentage(ref lp) => { NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => {
lp.maybe_to_used_value(None) lp.0.maybe_to_used_value(None)
}, },
} }
.unwrap_or(child_base.intrinsic_inline_sizes.minimum_inline_size), .unwrap_or(child_base.intrinsic_inline_sizes.minimum_inline_size),
percentage: match child_specified_inline_size { percentage: match child_specified_inline_size {
LengthPercentageOrAuto::Auto => 0.0, NonNegativeLengthPercentageOrAuto::Auto => 0.0,
LengthPercentageOrAuto::LengthPercentage(ref lp) => { NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => {
lp.as_percentage().map_or(0.0, |p| p.0) lp.0.as_percentage().map_or(0.0, |p| p.0)
}, },
}, },
preferred: child_base.intrinsic_inline_sizes.preferred_inline_size, preferred: child_base.intrinsic_inline_sizes.preferred_inline_size,
constrained: match child_specified_inline_size { constrained: match child_specified_inline_size {
LengthPercentageOrAuto::Auto => false, NonNegativeLengthPercentageOrAuto::Auto => false,
LengthPercentageOrAuto::LengthPercentage(ref lp) => { NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => {
lp.maybe_to_used_value(None).is_some() lp.0.maybe_to_used_value(None).is_some()
}, },
}, },
}; };

View file

@ -33,7 +33,7 @@ use style::computed_values::{position, table_layout};
use style::context::SharedStyleContext; use style::context::SharedStyleContext;
use style::logical_geometry::{LogicalRect, LogicalSize}; use style::logical_geometry::{LogicalRect, LogicalSize};
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::values::computed::LengthPercentageOrAuto; use style::values::computed::NonNegativeLengthPercentageOrAuto;
use style::values::CSSFloat; use style::values::CSSFloat;
#[derive(Clone, Copy, Debug, Serialize)] #[derive(Clone, Copy, Debug, Serialize)]
@ -201,7 +201,7 @@ impl TableWrapperFlow {
// says "the basic idea is the same as the shrink-to-fit width that CSS2.1 defines". So we // says "the basic idea is the same as the shrink-to-fit width that CSS2.1 defines". So we
// just use the shrink-to-fit inline size. // just use the shrink-to-fit inline size.
let available_inline_size = match self.block_flow.fragment.style().content_inline_size() { let available_inline_size = match self.block_flow.fragment.style().content_inline_size() {
LengthPercentageOrAuto::Auto => { NonNegativeLengthPercentageOrAuto::Auto => {
self.block_flow self.block_flow
.get_shrink_to_fit_inline_size(available_inline_size) - .get_shrink_to_fit_inline_size(available_inline_size) -
table_border_padding table_border_padding
@ -840,12 +840,8 @@ fn initial_computed_inline_size(
preferred_width_of_all_columns: Au, preferred_width_of_all_columns: Au,
table_border_padding: Au, table_border_padding: Au,
) -> MaybeAuto { ) -> MaybeAuto {
let inline_size_from_style = MaybeAuto::from_style( match block.fragment.style.content_inline_size() {
block.fragment.style.content_inline_size(), NonNegativeLengthPercentageOrAuto::Auto => {
containing_block_inline_size,
);
match inline_size_from_style {
MaybeAuto::Auto => {
if preferred_width_of_all_columns + table_border_padding <= containing_block_inline_size if preferred_width_of_all_columns + table_border_padding <= containing_block_inline_size
{ {
MaybeAuto::Specified(preferred_width_of_all_columns + table_border_padding) MaybeAuto::Specified(preferred_width_of_all_columns + table_border_padding)
@ -855,10 +851,13 @@ fn initial_computed_inline_size(
MaybeAuto::Auto MaybeAuto::Auto
} }
}, },
MaybeAuto::Specified(inline_size_from_style) => MaybeAuto::Specified(max( NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => {
inline_size_from_style - table_border_padding, let used = lp.to_used_value(containing_block_inline_size);
MaybeAuto::Specified(max(
used - table_border_padding,
minimum_width_of_all_columns, minimum_width_of_all_columns,
)), ))
},
} }
} }

View file

@ -29,7 +29,6 @@ use js::rust::wrappers::ObjectClassName;
use msg::constellation_msg::PipelineId; use msg::constellation_msg::PipelineId;
use std::ffi::CStr; use std::ffi::CStr;
use std::str; use std::str;
use style::properties::longhands::{margin_bottom, margin_left, margin_right, margin_top};
use uuid::Uuid; use uuid::Uuid;
#[allow(unsafe_code)] #[allow(unsafe_code)]
@ -178,10 +177,10 @@ fn determine_auto_margins(window: &Window, node: &Node) -> AutoMargins {
let style = window.style_query(node.to_trusted_node_address()).unwrap(); let style = window.style_query(node.to_trusted_node_address()).unwrap();
let margin = style.get_margin(); let margin = style.get_margin();
AutoMargins { AutoMargins {
top: margin.margin_top == margin_top::computed_value::T::Auto, top: margin.margin_top.is_auto(),
right: margin.margin_right == margin_right::computed_value::T::Auto, right: margin.margin_right.is_auto(),
bottom: margin.margin_bottom == margin_bottom::computed_value::T::Auto, bottom: margin.margin_bottom.is_auto(),
left: margin.margin_left == margin_left::computed_value::T::Auto, left: margin.margin_left.is_auto(),
} }
} }

View file

@ -718,9 +718,11 @@ impl LayoutElementHelpers for LayoutDom<Element> {
specified::NoCalcLength::ServoCharacterWidth(specified::CharacterWidth(size)); specified::NoCalcLength::ServoCharacterWidth(specified::CharacterWidth(size));
hints.push(from_declaration( hints.push(from_declaration(
shared_lock, shared_lock,
PropertyDeclaration::Width(specified::LengthPercentageOrAuto::LengthPercentage( PropertyDeclaration::Width(
specified::NonNegativeLengthPercentageOrAuto::LengthPercentage(NonNegative(
specified::LengthPercentage::Length(value), specified::LengthPercentage::Length(value),
)), )),
),
)); ));
} }
@ -745,20 +747,22 @@ impl LayoutElementHelpers for LayoutDom<Element> {
match width { match width {
LengthOrPercentageOrAuto::Auto => {}, LengthOrPercentageOrAuto::Auto => {},
LengthOrPercentageOrAuto::Percentage(percentage) => { LengthOrPercentageOrAuto::Percentage(percentage) => {
let width_value = specified::LengthPercentageOrAuto::LengthPercentage( let width_value =
specified::NonNegativeLengthPercentageOrAuto::LengthPercentage(NonNegative(
specified::LengthPercentage::Percentage(computed::Percentage(percentage)), specified::LengthPercentage::Percentage(computed::Percentage(percentage)),
); ));
hints.push(from_declaration( hints.push(from_declaration(
shared_lock, shared_lock,
PropertyDeclaration::Width(width_value), PropertyDeclaration::Width(width_value),
)); ));
}, },
LengthOrPercentageOrAuto::Length(length) => { LengthOrPercentageOrAuto::Length(length) => {
let width_value = specified::LengthPercentageOrAuto::LengthPercentage( let width_value =
specified::NonNegativeLengthPercentageOrAuto::LengthPercentage(NonNegative(
specified::LengthPercentage::Length(specified::NoCalcLength::Absolute( specified::LengthPercentage::Length(specified::NoCalcLength::Absolute(
specified::AbsoluteLength::Px(length.to_f32_px()), specified::AbsoluteLength::Px(length.to_f32_px()),
)), )),
); ));
hints.push(from_declaration( hints.push(from_declaration(
shared_lock, shared_lock,
PropertyDeclaration::Width(width_value), PropertyDeclaration::Width(width_value),
@ -779,20 +783,22 @@ impl LayoutElementHelpers for LayoutDom<Element> {
match height { match height {
LengthOrPercentageOrAuto::Auto => {}, LengthOrPercentageOrAuto::Auto => {},
LengthOrPercentageOrAuto::Percentage(percentage) => { LengthOrPercentageOrAuto::Percentage(percentage) => {
let height_value = specified::LengthPercentageOrAuto::LengthPercentage( let height_value =
specified::NonNegativeLengthPercentageOrAuto::LengthPercentage(NonNegative(
specified::LengthPercentage::Percentage(computed::Percentage(percentage)), specified::LengthPercentage::Percentage(computed::Percentage(percentage)),
); ));
hints.push(from_declaration( hints.push(from_declaration(
shared_lock, shared_lock,
PropertyDeclaration::Height(height_value), PropertyDeclaration::Height(height_value),
)); ));
}, },
LengthOrPercentageOrAuto::Length(length) => { LengthOrPercentageOrAuto::Length(length) => {
let height_value = specified::LengthPercentageOrAuto::LengthPercentage( let height_value =
specified::NonNegativeLengthPercentageOrAuto::LengthPercentage(NonNegative(
specified::LengthPercentage::Length(specified::NoCalcLength::Absolute( specified::LengthPercentage::Length(specified::NoCalcLength::Absolute(
specified::AbsoluteLength::Px(length.to_f32_px()), specified::AbsoluteLength::Px(length.to_f32_px()),
)), )),
); ));
hints.push(from_declaration( hints.push(from_declaration(
shared_lock, shared_lock,
PropertyDeclaration::Height(height_value), PropertyDeclaration::Height(height_value),
@ -819,9 +825,11 @@ impl LayoutElementHelpers for LayoutDom<Element> {
specified::NoCalcLength::ServoCharacterWidth(specified::CharacterWidth(cols)); specified::NoCalcLength::ServoCharacterWidth(specified::CharacterWidth(cols));
hints.push(from_declaration( hints.push(from_declaration(
shared_lock, shared_lock,
PropertyDeclaration::Width(specified::LengthPercentageOrAuto::LengthPercentage( PropertyDeclaration::Width(
specified::NonNegativeLengthPercentageOrAuto::LengthPercentage(NonNegative(
specified::LengthPercentage::Length(value), specified::LengthPercentage::Length(value),
)), )),
),
)); ));
} }
@ -843,9 +851,11 @@ impl LayoutElementHelpers for LayoutDom<Element> {
)); ));
hints.push(from_declaration( hints.push(from_declaration(
shared_lock, shared_lock,
PropertyDeclaration::Height(specified::LengthPercentageOrAuto::LengthPercentage( PropertyDeclaration::Height(
specified::NonNegativeLengthPercentageOrAuto::LengthPercentage(NonNegative(
specified::LengthPercentage::Length(value), specified::LengthPercentage::Length(value),
)), )),
),
)); ));
} }

View file

@ -8,6 +8,7 @@
#![feature(drain_filter)] #![feature(drain_filter)]
#![feature(plugin)] #![feature(plugin)]
#![feature(try_from)] #![feature(try_from)]
#![feature(type_alias_enum_variants)]
#![deny(unsafe_code)] #![deny(unsafe_code)]
#![allow(non_snake_case)] #![allow(non_snake_case)]
#![doc = "The script crate contains all matters DOM."] #![doc = "The script crate contains all matters DOM."]

View file

@ -7,11 +7,17 @@ autogen_warning = """/* DO NOT MODIFY THIS MANUALLY! This file was generated usi
* a. Alternatively, you can clone `https://github.com/eqrion/cbindgen` and use a tagged release * a. Alternatively, you can clone `https://github.com/eqrion/cbindgen` and use a tagged release
* 2. Run `rustup run nightly cbindgen toolkit/library/rust/ --lockfile Cargo.lock --crate style -o layout/style/ServoStyleConsts.h` * 2. Run `rustup run nightly cbindgen toolkit/library/rust/ --lockfile Cargo.lock --crate style -o layout/style/ServoStyleConsts.h`
*/ */
#include "nsCoord.h"
#include "Units.h"
#include "mozilla/gfx/Types.h"
class nsAtom; class nsAtom;
namespace mozilla { namespace mozilla {
class WritingMode;
enum LogicalSide : uint8_t;
namespace css { namespace css {
struct URLValue; struct URLValue;
} }
// Work-around weird cbindgen renaming. // Work-around weird cbindgen renaming.
typedef css::URLValue StyleURLValue; typedef css::URLValue StyleURLValue;
typedef nsAtom StylensAtom; typedef nsAtom StylensAtom;
@ -27,7 +33,7 @@ namespaces = ["mozilla"]
[parse] [parse]
parse_deps = true parse_deps = true
include = ["cssparser"] include = ["cssparser", "style_traits"]
[struct] [struct]
derive_eq = true derive_eq = true
@ -69,5 +75,46 @@ include = [
"Resize", "Resize",
"Overflow", "Overflow",
"LengthPercentage", "LengthPercentage",
"NonNegativeLengthPercentage",
"LengthPercentageOrAuto",
"Rect",
"IntersectionObserverRootMargin",
] ]
item_types = ["enums", "structs", "typedefs"] item_types = ["enums", "structs", "typedefs"]
[export.body]
"LengthPercentage" = """
// Defined in nsStyleCoord.h
static constexpr inline StyleLengthPercentage Zero();
inline bool HasPercent() const;
inline bool ConvertsToLength() const;
inline nscoord ToLength() const;
inline bool ConvertsToPercentage() 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;
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;
"""
"Rect" = """
// Defined in nsStyleCoord.h
template<typename Predicate> inline bool All(Predicate) const;
template<typename Predicate> inline bool Any(Predicate) const;
// Defined in WritingModes.h
inline const T& Get(mozilla::Side) const;
inline const T& Get(mozilla::WritingMode, mozilla::LogicalSide) const;
inline const T& GetIStart(mozilla::WritingMode) const;
inline const T& GetBStart(mozilla::WritingMode) const;
inline const T& GetIEnd(mozilla::WritingMode) const;
inline const T& GetBEnd(mozilla::WritingMode) const;
"""

View file

@ -27,6 +27,7 @@ use crate::values::computed::{LengthPercentageOrAuto, NonNegativeLengthPercentag
use crate::values::generics::box_::VerticalAlign; use crate::values::generics::box_::VerticalAlign;
use crate::values::generics::grid::{TrackListValue, TrackSize}; use crate::values::generics::grid::{TrackListValue, TrackSize};
use crate::values::generics::image::{CompatMode, GradientItem, Image as GenericImage}; 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::rect::Rect;
use crate::values::generics::NonNegative; use crate::values::generics::NonNegative;
use app_units::Au; use app_units::Au;
@ -62,19 +63,19 @@ impl From<nsStyleCoord_CalcValue> for LengthPercentage {
} }
} }
impl LengthPercentageOrAuto { impl NonNegativeLengthPercentageOrAuto {
/// Convert this value in an appropriate `nsStyleCoord::CalcValue`. /// Convert this value in an appropriate `nsStyleCoord::CalcValue`.
pub fn to_calc_value(&self) -> Option<nsStyleCoord_CalcValue> { pub fn to_calc_value(&self) -> Option<nsStyleCoord_CalcValue> {
match *self { match *self {
LengthPercentageOrAuto::LengthPercentage(len) => Some(From::from(len)), GenericLengthPercentageOrAuto::LengthPercentage(ref len) => Some(From::from(len.0)),
LengthPercentageOrAuto::Auto => None, GenericLengthPercentageOrAuto::Auto => None,
} }
} }
} }
impl From<nsStyleCoord_CalcValue> for LengthPercentageOrAuto { impl From<nsStyleCoord_CalcValue> for LengthPercentageOrAuto {
fn from(other: nsStyleCoord_CalcValue) -> LengthPercentageOrAuto { fn from(other: nsStyleCoord_CalcValue) -> LengthPercentageOrAuto {
LengthPercentageOrAuto::LengthPercentage(LengthPercentage::from(other)) GenericLengthPercentageOrAuto::LengthPercentage(LengthPercentage::from(other))
} }
} }
@ -82,7 +83,7 @@ impl From<nsStyleCoord_CalcValue> for LengthPercentageOrAuto {
// disappear as we move more stuff to cbindgen. // disappear as we move more stuff to cbindgen.
impl From<nsStyleCoord_CalcValue> for NonNegativeLengthPercentageOrAuto { impl From<nsStyleCoord_CalcValue> for NonNegativeLengthPercentageOrAuto {
fn from(other: nsStyleCoord_CalcValue) -> Self { fn from(other: nsStyleCoord_CalcValue) -> Self {
NonNegative(LengthPercentageOrAuto::LengthPercentage( GenericLengthPercentageOrAuto::LengthPercentage(NonNegative(
LengthPercentage::with_clamping_mode( LengthPercentage::with_clamping_mode(
Au(other.mLength).into(), Au(other.mLength).into(),
if other.mHasPercent { if other.mHasPercent {

View file

@ -14,15 +14,15 @@ use crate::media_queries::Device;
use crate::values::computed::basic_shape::ShapeRadius as ComputedShapeRadius; use crate::values::computed::basic_shape::ShapeRadius as ComputedShapeRadius;
use crate::values::computed::FlexBasis as ComputedFlexBasis; use crate::values::computed::FlexBasis as ComputedFlexBasis;
use crate::values::computed::{Angle, ExtremumLength, Length, LengthPercentage}; use crate::values::computed::{Angle, ExtremumLength, Length, LengthPercentage};
use crate::values::computed::{LengthPercentageOrAuto, Percentage};
use crate::values::computed::{LengthPercentageOrNone, Number, NumberOrPercentage};
use crate::values::computed::{MaxLength as ComputedMaxLength, MozLength as ComputedMozLength}; use crate::values::computed::{MaxLength as ComputedMaxLength, MozLength as ComputedMozLength};
use crate::values::computed::{NonNegativeLengthPercentage, Percentage};
use crate::values::computed::{Number, NumberOrPercentage};
use crate::values::generics::basic_shape::ShapeRadius; use crate::values::generics::basic_shape::ShapeRadius;
use crate::values::generics::box_::Perspective; use crate::values::generics::box_::Perspective;
use crate::values::generics::flex::FlexBasis; use crate::values::generics::flex::FlexBasis;
use crate::values::generics::gecko::ScrollSnapPoint; use crate::values::generics::gecko::ScrollSnapPoint;
use crate::values::generics::grid::{TrackBreadth, TrackKeyword}; use crate::values::generics::grid::{TrackBreadth, TrackKeyword};
use crate::values::generics::length::{MaxLength, MozLength}; use crate::values::generics::length::{LengthPercentageOrAuto, MaxLength, MozLength};
use crate::values::generics::{CounterStyleOrNone, NonNegative}; use crate::values::generics::{CounterStyleOrNone, NonNegative};
use crate::values::{Auto, Either, None_, Normal}; use crate::values::{Auto, Either, None_, Normal};
use crate::Atom; use crate::Atom;
@ -183,7 +183,10 @@ impl GeckoStyleCoordConvertible for Length {
} }
} }
impl GeckoStyleCoordConvertible for LengthPercentageOrAuto { impl<LengthPercentage> GeckoStyleCoordConvertible for LengthPercentageOrAuto<LengthPercentage>
where
LengthPercentage: GeckoStyleCoordConvertible,
{
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
match *self { match *self {
LengthPercentageOrAuto::Auto => coord.set_value(CoordDataValue::Auto), LengthPercentageOrAuto::Auto => coord.set_value(CoordDataValue::Auto),
@ -200,23 +203,6 @@ impl GeckoStyleCoordConvertible for LengthPercentageOrAuto {
} }
} }
impl GeckoStyleCoordConvertible for LengthPercentageOrNone {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
match *self {
LengthPercentageOrNone::None => coord.set_value(CoordDataValue::None),
LengthPercentageOrNone::LengthPercentage(ref lp) => lp.to_gecko_style_coord(coord),
}
}
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
match coord.as_value() {
CoordDataValue::None => Some(LengthPercentageOrNone::None),
_ => LengthPercentage::from_gecko_style_coord(coord)
.map(LengthPercentageOrNone::LengthPercentage),
}
}
}
impl<L: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for TrackBreadth<L> { impl<L: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for TrackBreadth<L> {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
match *self { match *self {
@ -367,34 +353,40 @@ impl GeckoStyleCoordConvertible for ExtremumLength {
impl GeckoStyleCoordConvertible for ComputedMozLength { impl GeckoStyleCoordConvertible for ComputedMozLength {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
match *self { match *self {
MozLength::LengthPercentageOrAuto(ref lpoa) => lpoa.to_gecko_style_coord(coord), MozLength::LengthPercentage(ref lpoa) => lpoa.to_gecko_style_coord(coord),
MozLength::Auto => coord.set_value(CoordDataValue::Auto),
MozLength::ExtremumLength(ref e) => e.to_gecko_style_coord(coord), MozLength::ExtremumLength(ref e) => e.to_gecko_style_coord(coord),
} }
} }
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> { fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
LengthPercentageOrAuto::from_gecko_style_coord(coord) if let CoordDataValue::Auto = coord.as_value() {
.map(MozLength::LengthPercentageOrAuto) return Some(MozLength::Auto);
.or_else(|| { }
if let Some(lp) = NonNegativeLengthPercentage::from_gecko_style_coord(coord) {
return Some(MozLength::LengthPercentage(lp));
}
ExtremumLength::from_gecko_style_coord(coord).map(MozLength::ExtremumLength) ExtremumLength::from_gecko_style_coord(coord).map(MozLength::ExtremumLength)
})
} }
} }
impl GeckoStyleCoordConvertible for ComputedMaxLength { impl GeckoStyleCoordConvertible for ComputedMaxLength {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
match *self { match *self {
MaxLength::LengthPercentageOrNone(ref lpon) => lpon.to_gecko_style_coord(coord), MaxLength::LengthPercentage(ref lpon) => lpon.to_gecko_style_coord(coord),
MaxLength::None => coord.set_value(CoordDataValue::None),
MaxLength::ExtremumLength(ref e) => e.to_gecko_style_coord(coord), MaxLength::ExtremumLength(ref e) => e.to_gecko_style_coord(coord),
} }
} }
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> { fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
LengthPercentageOrNone::from_gecko_style_coord(coord) if let CoordDataValue::None = coord.as_value() {
.map(MaxLength::LengthPercentageOrNone) return Some(MaxLength::None);
.or_else(|| { }
if let Some(lp) = NonNegativeLengthPercentage::from_gecko_style_coord(coord) {
return Some(MaxLength::LengthPercentage(lp));
}
ExtremumLength::from_gecko_style_coord(coord).map(MaxLength::ExtremumLength) ExtremumLength::from_gecko_style_coord(coord).map(MaxLength::ExtremumLength)
})
} }
} }

View file

@ -629,6 +629,10 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
{ {
if let Some(display) = builder.get_box_if_mutated() {
display.generate_combined_transform();
}
if let Some(bg) = builder.get_background_if_mutated() { if let Some(bg) = builder.get_background_if_mutated() {
bg.fill_arrays(); bg.fill_arrays();
} }

View file

@ -80,7 +80,6 @@ pub struct ComputedValues(crate::gecko_bindings::structs::mozilla::ComputedStyle
impl ComputedValues { impl ComputedValues {
pub fn new( pub fn new(
device: &Device,
pseudo: Option<<&PseudoElement>, pseudo: Option<<&PseudoElement>,
custom_properties: Option<Arc<CustomPropertiesMap>>, custom_properties: Option<Arc<CustomPropertiesMap>>,
writing_mode: WritingMode, writing_mode: WritingMode,
@ -100,10 +99,7 @@ impl ComputedValues {
% for style_struct in data.style_structs: % for style_struct in data.style_structs:
${style_struct.ident}, ${style_struct.ident},
% endfor % endfor
).to_outer( ).to_outer(pseudo)
device.pres_context(),
pseudo.map(|p| p.pseudo_info())
)
} }
pub fn default_values(pres_context: RawGeckoPresContextBorrowed) -> Arc<Self> { pub fn default_values(pres_context: RawGeckoPresContextBorrowed) -> Arc<Self> {
@ -116,7 +112,7 @@ impl ComputedValues {
% for style_struct in data.style_structs: % for style_struct in data.style_structs:
style_structs::${style_struct.name}::default(pres_context), style_structs::${style_struct.name}::default(pres_context),
% endfor % endfor
).to_outer(pres_context, None) ).to_outer(None)
} }
pub fn pseudo(&self) -> Option<PseudoElement> { pub fn pseudo(&self) -> Option<PseudoElement> {
@ -190,10 +186,9 @@ impl Clone for ComputedValuesInner {
} }
} }
type PseudoInfo = (*mut structs::nsAtom, structs::CSSPseudoElementType);
impl ComputedValuesInner { impl ComputedValuesInner {
pub fn new(custom_properties: Option<Arc<CustomPropertiesMap>>, pub fn new(
custom_properties: Option<Arc<CustomPropertiesMap>>,
writing_mode: WritingMode, writing_mode: WritingMode,
flags: ComputedValueFlags, flags: ComputedValueFlags,
rules: Option<StrongRuleNode>, rules: Option<StrongRuleNode>,
@ -202,12 +197,12 @@ impl ComputedValuesInner {
${style_struct.ident}: Arc<style_structs::${style_struct.name}>, ${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
% endfor % endfor
) -> Self { ) -> Self {
ComputedValuesInner { Self {
custom_properties: custom_properties, custom_properties,
writing_mode: writing_mode, writing_mode,
rules: rules, rules,
visited_style: visited_style.map(|x| Arc::into_raw_offset(x)), visited_style: visited_style.map(Arc::into_raw_offset),
flags: flags, flags,
% for style_struct in data.style_structs: % for style_struct in data.style_structs:
${style_struct.gecko_name}: Arc::into_raw_offset(${style_struct.ident}), ${style_struct.gecko_name}: Arc::into_raw_offset(${style_struct.ident}),
% endfor % endfor
@ -216,29 +211,16 @@ impl ComputedValuesInner {
fn to_outer( fn to_outer(
self, self,
pres_context: RawGeckoPresContextBorrowed, pseudo: Option<<&PseudoElement>,
info: Option<PseudoInfo>
) -> Arc<ComputedValues> { ) -> Arc<ComputedValues> {
let (tag, ty) = if let Some(info) = info { let (pseudo_tag, pseudo_ty) = match pseudo {
info Some(p) => p.pseudo_info(),
} else { None => (ptr::null_mut(), structs::CSSPseudoElementType::NotPseudo),
(ptr::null_mut(), structs::CSSPseudoElementType::NotPseudo)
}; };
let arc = unsafe {
unsafe { self.to_outer_helper(pres_context, ty, tag) }
}
unsafe fn to_outer_helper(
self,
pres_context: bindings::RawGeckoPresContextBorrowed,
pseudo_ty: structs::CSSPseudoElementType,
pseudo_tag: *mut structs::nsAtom
) -> Arc<ComputedValues> {
let arc = {
let arc: Arc<ComputedValues> = Arc::new(uninitialized()); let arc: Arc<ComputedValues> = Arc::new(uninitialized());
bindings::Gecko_ComputedStyle_Init( bindings::Gecko_ComputedStyle_Init(
&arc.0 as *const _ as *mut _, &arc.0 as *const _ as *mut _,
pres_context,
&self, &self,
pseudo_ty, pseudo_ty,
pseudo_tag pseudo_tag
@ -790,11 +772,12 @@ def set_gecko_property(ffi_name, expr):
<%def name="impl_split_style_coord(ident, gecko_ffi_name, index)"> <%def name="impl_split_style_coord(ident, gecko_ffi_name, index)">
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) { pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
v.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data_at_mut(${index})); self.gecko.${gecko_ffi_name}.${index} = v;
} }
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub fn copy_${ident}_from(&mut self, other: &Self) { pub fn copy_${ident}_from(&mut self, other: &Self) {
self.gecko.${gecko_ffi_name}.data_at_mut(${index}).copy_from(&other.gecko.${gecko_ffi_name}.data_at(${index})); self.gecko.${gecko_ffi_name}.${index} =
other.gecko.${gecko_ffi_name}.${index};
} }
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub fn reset_${ident}(&mut self, other: &Self) { pub fn reset_${ident}(&mut self, other: &Self) {
@ -803,9 +786,7 @@ def set_gecko_property(ffi_name, expr):
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
use crate::properties::longhands::${ident}::computed_value::T; self.gecko.${gecko_ffi_name}.${index}
T::from_gecko_style_coord(&self.gecko.${gecko_ffi_name}.data_at(${index}))
.expect("clone for ${ident} failed")
} }
</%def> </%def>
@ -1407,14 +1388,13 @@ impl Clone for ${style_struct.gecko_struct_name} {
"FlexBasis": impl_style_coord, "FlexBasis": impl_style_coord,
"Length": impl_absolute_length, "Length": impl_absolute_length,
"LengthOrNormal": impl_style_coord, "LengthOrNormal": impl_style_coord,
"LengthPercentage": impl_style_coord, "LengthPercentage": impl_simple,
"LengthPercentageOrAuto": impl_style_coord, "LengthPercentageOrAuto": impl_style_coord,
"LengthPercentageOrNone": impl_style_coord,
"MaxLength": impl_style_coord, "MaxLength": impl_style_coord,
"MozLength": impl_style_coord, "MozLength": impl_style_coord,
"MozScriptMinSize": impl_absolute_length, "MozScriptMinSize": impl_absolute_length,
"MozScriptSizeMultiplier": impl_simple, "MozScriptSizeMultiplier": impl_simple,
"NonNegativeLengthPercentage": impl_style_coord, "NonNegativeLengthPercentage": impl_simple,
"NonNegativeNumber": impl_simple, "NonNegativeNumber": impl_simple,
"Number": impl_simple, "Number": impl_simple,
"Opacity": impl_simple, "Opacity": impl_simple,
@ -3023,6 +3003,11 @@ fn static_assert() {
will-change shape-outside contain touch-action will-change shape-outside contain touch-action
translate scale""" %> translate scale""" %>
<%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}"> <%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}">
#[inline]
pub fn generate_combined_transform(&mut self) {
unsafe { bindings::Gecko_StyleDisplay_GenerateCombinedTransform(&mut self.gecko) };
}
#[inline] #[inline]
pub fn set_display(&mut self, v: longhands::display::computed_value::T) { pub fn set_display(&mut self, v: longhands::display::computed_value::T) {
self.gecko.mDisplay = v; self.gecko.mDisplay = v;
@ -3845,11 +3830,11 @@ fn static_assert() {
BackgroundSize::Explicit { width: explicit_width, height: explicit_height } => { BackgroundSize::Explicit { width: explicit_width, height: explicit_height } => {
let mut w_type = nsStyleImageLayers_Size_DimensionType::eAuto; let mut w_type = nsStyleImageLayers_Size_DimensionType::eAuto;
let mut h_type = nsStyleImageLayers_Size_DimensionType::eAuto; let mut h_type = nsStyleImageLayers_Size_DimensionType::eAuto;
if let Some(w) = explicit_width.0.to_calc_value() { if let Some(w) = explicit_width.to_calc_value() {
width = w; width = w;
w_type = nsStyleImageLayers_Size_DimensionType::eLengthPercentage; w_type = nsStyleImageLayers_Size_DimensionType::eLengthPercentage;
} }
if let Some(h) = explicit_height.0.to_calc_value() { if let Some(h) = explicit_height.to_calc_value() {
height = h; height = h;
h_type = nsStyleImageLayers_Size_DimensionType::eLengthPercentage; h_type = nsStyleImageLayers_Size_DimensionType::eLengthPercentage;
} }

View file

@ -34,7 +34,7 @@ ${helpers.single_keyword(
spec="Internal (not web-exposed)", spec="Internal (not web-exposed)",
)} )}
// An internal-only attribute for elements in a top layer // An internal-only property for elements in a top layer
// https://fullscreen.spec.whatwg.org/#top-layer // https://fullscreen.spec.whatwg.org/#top-layer
${helpers.single_keyword( ${helpers.single_keyword(
"-servo-top-layer", "-servo-top-layer",
@ -602,6 +602,8 @@ ${helpers.predefined_type(
products="gecko", products="gecko",
animation_value_type="none", animation_value_type="none",
gecko_ffi_name="mBinding", gecko_ffi_name="mBinding",
gecko_pref="layout.css.moz-binding.content.enabled",
enabled_in="chrome",
spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-binding)", spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-binding)",
)} )}

View file

@ -13,7 +13,7 @@
${helpers.predefined_type( ${helpers.predefined_type(
side, side,
"LengthPercentageOrAuto", "LengthPercentageOrAuto",
"computed::LengthPercentageOrAuto::Auto", "computed::LengthPercentageOrAuto::auto()",
spec="https://www.w3.org/TR/CSS2/visuren.html#propdef-%s" % side, spec="https://www.w3.org/TR/CSS2/visuren.html#propdef-%s" % side,
flags="GETCS_NEEDS_LAYOUT_FLUSH", flags="GETCS_NEEDS_LAYOUT_FLUSH",
animation_value_type="ComputedValue", animation_value_type="ComputedValue",
@ -27,7 +27,7 @@
${helpers.predefined_type( ${helpers.predefined_type(
"inset-%s" % side, "inset-%s" % side,
"LengthPercentageOrAuto", "LengthPercentageOrAuto",
"computed::LengthPercentageOrAuto::Auto", "computed::LengthPercentageOrAuto::auto()",
spec="https://drafts.csswg.org/css-logical-props/#propdef-inset-%s" % side, spec="https://drafts.csswg.org/css-logical-props/#propdef-inset-%s" % side,
flags="GETCS_NEEDS_LAYOUT_FLUSH", flags="GETCS_NEEDS_LAYOUT_FLUSH",
alias="offset-%s:layout.css.offset-logical-properties.enabled" % side, alias="offset-%s:layout.css.offset-logical-properties.enabled" % side,
@ -270,6 +270,30 @@ ${helpers.predefined_type(
animation_value_type="MozLength", animation_value_type="MozLength",
servo_restyle_damage="reflow", servo_restyle_damage="reflow",
)} )}
% else:
// servo versions (no keyword support)
${helpers.predefined_type(
size,
"NonNegativeLengthPercentageOrAuto",
"computed::NonNegativeLengthPercentageOrAuto::auto()",
spec=spec % size,
logical_group="size",
allow_quirks=not logical,
animation_value_type="ComputedValue", logical = logical,
servo_restyle_damage="reflow",
)}
${helpers.predefined_type(
"min-%s" % size,
"NonNegativeLengthPercentage",
"computed::NonNegativeLengthPercentage::zero()",
spec=spec % ("min-%s" % size),
logical_group="min-size",
animation_value_type="ComputedValue",
logical=logical,
allow_quirks=not logical,
servo_restyle_damage="reflow",
)}
% endif
${helpers.predefined_type( ${helpers.predefined_type(
"max-%s" % size, "max-%s" % size,
"MaxLength", "MaxLength",
@ -281,44 +305,6 @@ ${helpers.predefined_type(
animation_value_type="MaxLength", animation_value_type="MaxLength",
servo_restyle_damage="reflow", servo_restyle_damage="reflow",
)} )}
% else:
// servo versions (no keyword support)
${helpers.predefined_type(
size,
"LengthPercentageOrAuto",
"computed::LengthPercentageOrAuto::Auto",
"parse_non_negative",
spec=spec % size,
logical_group="size",
allow_quirks=not logical,
animation_value_type="ComputedValue", logical = logical,
servo_restyle_damage="reflow",
)}
${helpers.predefined_type(
"min-%s" % size,
"LengthPercentage",
"computed::LengthPercentage::zero()",
"parse_non_negative",
spec=spec % ("min-%s" % size),
logical_group="min-size",
animation_value_type="ComputedValue",
logical=logical,
allow_quirks=not logical,
servo_restyle_damage="reflow",
)}
${helpers.predefined_type(
"max-%s" % size,
"LengthPercentageOrNone",
"computed::LengthPercentageOrNone::None",
"parse_non_negative",
spec=spec % ("max-%s" % size),
logical_group="max-size",
animation_value_type="ComputedValue",
logical=logical,
allow_quirks=not logical,
servo_restyle_damage="reflow",
)}
% endif
% endfor % endfor
${helpers.single_keyword( ${helpers.single_keyword(

View file

@ -2890,7 +2890,6 @@ impl ComputedValues {
impl ComputedValues { impl ComputedValues {
/// Create a new refcounted `ComputedValues` /// Create a new refcounted `ComputedValues`
pub fn new( pub fn new(
_: &Device,
_: Option<<&PseudoElement>, _: Option<<&PseudoElement>,
custom_properties: Option<Arc<crate::custom_properties::CustomPropertiesMap>>, custom_properties: Option<Arc<crate::custom_properties::CustomPropertiesMap>>,
writing_mode: WritingMode, writing_mode: WritingMode,
@ -3017,7 +3016,7 @@ impl ComputedValuesInner {
/// Get the logical computed inline size. /// Get the logical computed inline size.
#[inline] #[inline]
pub fn content_inline_size(&self) -> computed::LengthPercentageOrAuto { pub fn content_inline_size(&self) -> computed::NonNegativeLengthPercentageOrAuto {
let position_style = self.get_position(); let position_style = self.get_position();
if self.writing_mode.is_vertical() { if self.writing_mode.is_vertical() {
position_style.height position_style.height
@ -3028,35 +3027,35 @@ impl ComputedValuesInner {
/// Get the logical computed block size. /// Get the logical computed block size.
#[inline] #[inline]
pub fn content_block_size(&self) -> computed::LengthPercentageOrAuto { pub fn content_block_size(&self) -> computed::NonNegativeLengthPercentageOrAuto {
let position_style = self.get_position(); let position_style = self.get_position();
if self.writing_mode.is_vertical() { position_style.width } else { position_style.height } if self.writing_mode.is_vertical() { position_style.width } else { position_style.height }
} }
/// Get the logical computed min inline size. /// Get the logical computed min inline size.
#[inline] #[inline]
pub fn min_inline_size(&self) -> computed::LengthPercentage { pub fn min_inline_size(&self) -> computed::NonNegativeLengthPercentage {
let position_style = self.get_position(); let position_style = self.get_position();
if self.writing_mode.is_vertical() { position_style.min_height } else { position_style.min_width } if self.writing_mode.is_vertical() { position_style.min_height } else { position_style.min_width }
} }
/// Get the logical computed min block size. /// Get the logical computed min block size.
#[inline] #[inline]
pub fn min_block_size(&self) -> computed::LengthPercentage { pub fn min_block_size(&self) -> computed::NonNegativeLengthPercentage {
let position_style = self.get_position(); let position_style = self.get_position();
if self.writing_mode.is_vertical() { position_style.min_width } else { position_style.min_height } if self.writing_mode.is_vertical() { position_style.min_width } else { position_style.min_height }
} }
/// Get the logical computed max inline size. /// Get the logical computed max inline size.
#[inline] #[inline]
pub fn max_inline_size(&self) -> computed::LengthPercentageOrNone { pub fn max_inline_size(&self) -> computed::MaxLength {
let position_style = self.get_position(); let position_style = self.get_position();
if self.writing_mode.is_vertical() { position_style.max_height } else { position_style.max_width } if self.writing_mode.is_vertical() { position_style.max_height } else { position_style.max_width }
} }
/// Get the logical computed max block size. /// Get the logical computed max block size.
#[inline] #[inline]
pub fn max_block_size(&self) -> computed::LengthPercentageOrNone { pub fn max_block_size(&self) -> computed::MaxLength {
let position_style = self.get_position(); let position_style = self.get_position();
if self.writing_mode.is_vertical() { position_style.max_width } else { position_style.max_height } if self.writing_mode.is_vertical() { position_style.max_width } else { position_style.max_height }
} }
@ -3655,7 +3654,6 @@ impl<'a> StyleBuilder<'a> {
/// Turns this `StyleBuilder` into a proper `ComputedValues` instance. /// Turns this `StyleBuilder` into a proper `ComputedValues` instance.
pub fn build(self) -> Arc<ComputedValues> { pub fn build(self) -> Arc<ComputedValues> {
ComputedValues::new( ComputedValues::new(
self.device,
self.pseudo, self.pseudo,
self.custom_properties, self.custom_properties,
self.writing_mode, self.writing_mode,

View file

@ -11,16 +11,17 @@ use crate::context::QuirksMode;
use crate::error_reporting::ContextualParseError; use crate::error_reporting::ContextualParseError;
use crate::font_metrics::get_metrics_provider_for_product; use crate::font_metrics::get_metrics_provider_for_product;
use crate::media_queries::Device; use crate::media_queries::Device;
use crate::parser::ParserContext; use crate::parser::{Parse, ParserContext};
use crate::properties::StyleBuilder; use crate::properties::StyleBuilder;
use crate::rule_cache::RuleCacheConditions; use crate::rule_cache::RuleCacheConditions;
use crate::shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard}; use crate::shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard};
use crate::str::CssStringWriter; use crate::str::CssStringWriter;
use crate::stylesheets::{Origin, StylesheetInDocument}; use crate::stylesheets::{Origin, StylesheetInDocument};
use crate::values::computed::{Context, ToComputedValue}; use crate::values::computed::{Context, ToComputedValue};
use crate::values::specified::{ use crate::values::generics::length::LengthPercentageOrAuto;
self, LengthPercentageOrAuto, NoCalcLength, ViewportPercentageLength, use crate::values::generics::NonNegative;
}; use crate::values::specified::{self, NoCalcLength};
use crate::values::specified::{NonNegativeLengthPercentageOrAuto, ViewportPercentageLength};
use app_units::Au; use app_units::Au;
use cssparser::CowRcStr; use cssparser::CowRcStr;
use cssparser::{parse_important, AtRuleParser, DeclarationListParser, DeclarationParser, Parser}; use cssparser::{parse_important, AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
@ -151,7 +152,7 @@ trait FromMeta: Sized {
#[cfg_attr(feature = "servo", derive(MallocSizeOf))] #[cfg_attr(feature = "servo", derive(MallocSizeOf))]
#[derive(Clone, Debug, PartialEq, ToCss)] #[derive(Clone, Debug, PartialEq, ToCss)]
pub enum ViewportLength { pub enum ViewportLength {
Specified(LengthPercentageOrAuto), Specified(NonNegativeLengthPercentageOrAuto),
ExtendToZoom, ExtendToZoom,
} }
@ -159,9 +160,9 @@ impl FromMeta for ViewportLength {
fn from_meta(value: &str) -> Option<ViewportLength> { fn from_meta(value: &str) -> Option<ViewportLength> {
macro_rules! specified { macro_rules! specified {
($value:expr) => { ($value:expr) => {
ViewportLength::Specified(LengthPercentageOrAuto::LengthPercentage( ViewportLength::Specified(LengthPercentageOrAuto::LengthPercentage(NonNegative(
specified::LengthPercentage::Length($value), specified::LengthPercentage::Length($value),
)) )))
}; };
} }
@ -188,7 +189,7 @@ impl ViewportLength {
) -> Result<Self, ParseError<'i>> { ) -> Result<Self, ParseError<'i>> {
// we explicitly do not accept 'extend-to-zoom', since it is a UA // we explicitly do not accept 'extend-to-zoom', since it is a UA
// internal value for <META> viewport translation // internal value for <META> viewport translation
LengthPercentageOrAuto::parse_non_negative(context, input).map(ViewportLength::Specified) NonNegativeLengthPercentageOrAuto::parse(context, input).map(ViewportLength::Specified)
} }
} }

View file

@ -4,10 +4,8 @@
//! Animation implementation for various length-related types. //! Animation implementation for various length-related types.
use super::{Animate, Procedure, ToAnimatedValue}; use super::{Animate, Procedure};
use crate::values::computed::length::LengthPercentage; use crate::values::computed::length::LengthPercentage;
use crate::values::computed::MaxLength as ComputedMaxLength;
use crate::values::computed::MozLength as ComputedMozLength;
use crate::values::computed::Percentage; use crate::values::computed::Percentage;
/// <https://drafts.csswg.org/css-transitions/#animtype-lpcalc> /// <https://drafts.csswg.org/css-transitions/#animtype-lpcalc>
@ -38,51 +36,3 @@ impl Animate for LengthPercentage {
)) ))
} }
} }
// FIXME(emilio): These should use NonNegative<> instead.
impl ToAnimatedValue for ComputedMaxLength {
type AnimatedValue = Self;
#[inline]
fn to_animated_value(self) -> Self {
self
}
#[inline]
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
use crate::values::computed::LengthPercentageOrNone;
use crate::values::generics::length::MaxLength as GenericMaxLength;
match animated {
GenericMaxLength::LengthPercentageOrNone(lpn) => {
let result = match lpn {
LengthPercentageOrNone::LengthPercentage(len) => {
LengthPercentageOrNone::LengthPercentage(len.clamp_to_non_negative())
},
LengthPercentageOrNone::None => lpn,
};
GenericMaxLength::LengthPercentageOrNone(result)
},
_ => animated,
}
}
}
impl ToAnimatedValue for ComputedMozLength {
type AnimatedValue = Self;
#[inline]
fn to_animated_value(self) -> Self {
self
}
#[inline]
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
use crate::values::generics::length::MozLength as GenericMozLength;
match animated {
GenericMozLength::LengthPercentageOrAuto(lpa) => {
GenericMozLength::LengthPercentageOrAuto(lpa.clamp_to_non_negative())
},
_ => animated,
}
}
}

View file

@ -4,20 +4,21 @@
//! Computed types for CSS values related to backgrounds. //! Computed types for CSS values related to backgrounds.
use crate::values::computed::length::NonNegativeLengthPercentageOrAuto; use crate::values::computed::length::NonNegativeLengthPercentage;
use crate::values::generics::background::BackgroundSize as GenericBackgroundSize; use crate::values::generics::background::BackgroundSize as GenericBackgroundSize;
use crate::values::generics::length::LengthPercentageOrAuto;
pub use crate::values::specified::background::BackgroundRepeat; pub use crate::values::specified::background::BackgroundRepeat;
/// A computed value for the `background-size` property. /// A computed value for the `background-size` property.
pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentageOrAuto>; pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentage>;
impl BackgroundSize { impl BackgroundSize {
/// Returns `auto auto`. /// Returns `auto auto`.
pub fn auto() -> Self { pub fn auto() -> Self {
GenericBackgroundSize::Explicit { GenericBackgroundSize::Explicit {
width: NonNegativeLengthPercentageOrAuto::auto(), width: LengthPercentageOrAuto::auto(),
height: NonNegativeLengthPercentageOrAuto::auto(), height: LengthPercentageOrAuto::auto(),
} }
} }
} }

View file

@ -7,13 +7,15 @@
use super::{Context, Number, Percentage, ToComputedValue}; use super::{Context, Number, Percentage, ToComputedValue};
use crate::values::animated::ToAnimatedValue; use crate::values::animated::ToAnimatedValue;
use crate::values::distance::{ComputeSquaredDistance, SquaredDistance}; use crate::values::distance::{ComputeSquaredDistance, SquaredDistance};
use crate::values::generics::length::MaxLength as GenericMaxLength; use crate::values::generics::length as generics;
use crate::values::generics::length::MozLength as GenericMozLength; use crate::values::generics::length::{
MaxLength as GenericMaxLength, MozLength as GenericMozLength,
};
use crate::values::generics::transform::IsZeroLength; use crate::values::generics::transform::IsZeroLength;
use crate::values::generics::NonNegative; use crate::values::generics::NonNegative;
use crate::values::specified::length::ViewportPercentageLength; use crate::values::specified::length::ViewportPercentageLength;
use crate::values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength}; use crate::values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength};
use crate::values::{specified, Auto, CSSFloat, Either, IsAuto, Normal}; use crate::values::{specified, Auto, CSSFloat, Either, Normal};
use app_units::Au; use app_units::Au;
use ordered_float::NotNan; use ordered_float::NotNan;
use std::fmt::{self, Write}; use std::fmt::{self, Write};
@ -73,11 +75,12 @@ impl ToComputedValue for specified::Length {
/// https://drafts.csswg.org/css-values-4/#typedef-length-percentage /// https://drafts.csswg.org/css-values-4/#typedef-length-percentage
#[allow(missing_docs)] #[allow(missing_docs)]
#[derive(Clone, Copy, Debug, MallocSizeOf, ToAnimatedZero)] #[derive(Clone, Copy, Debug, MallocSizeOf, ToAnimatedZero)]
#[repr(C)]
pub struct LengthPercentage { pub struct LengthPercentage {
#[animation(constant)]
pub clamping_mode: AllowedNumericType,
length: Length, length: Length,
percentage: Percentage, percentage: Percentage,
#[animation(constant)]
pub clamping_mode: AllowedNumericType,
/// Whether we specified a percentage or not. /// Whether we specified a percentage or not.
#[animation(constant)] #[animation(constant)]
pub has_percentage: bool, pub has_percentage: bool,
@ -451,150 +454,61 @@ impl IsZeroLength for LengthPercentage {
} }
} }
#[allow(missing_docs)] /// Some boilerplate to share between negative and non-negative
#[css(derive_debug)] /// length-percentage or auto.
#[derive( macro_rules! computed_length_percentage_or_auto {
Animate, Clone, ComputeSquaredDistance, Copy, MallocSizeOf, PartialEq, ToAnimatedZero, ToCss, ($inner:ty) => {
)]
pub enum LengthPercentageOrAuto {
LengthPercentage(LengthPercentage),
Auto,
}
impl LengthPercentageOrAuto {
/// Returns the `0` value. /// Returns the `0` value.
#[inline] #[inline]
pub fn zero() -> Self { pub fn zero() -> Self {
LengthPercentageOrAuto::LengthPercentage(LengthPercentage::zero()) generics::LengthPercentageOrAuto::LengthPercentage(<$inner>::zero())
} }
}
/// A wrapper of LengthPercentageOrAuto, whose value must be >= 0. /// Returns the used value.
pub type NonNegativeLengthPercentageOrAuto = NonNegative<LengthPercentageOrAuto>;
impl IsAuto for NonNegativeLengthPercentageOrAuto {
#[inline] #[inline]
fn is_auto(&self) -> bool { pub fn to_used_value(&self, percentage_basis: Au) -> Option<Au> {
*self == Self::auto() match *self {
generics::GenericLengthPercentageOrAuto::Auto => None,
generics::GenericLengthPercentageOrAuto::LengthPercentage(ref lp) => {
Some(lp.to_used_value(percentage_basis))
} }
}
impl NonNegativeLengthPercentageOrAuto {
/// `auto`
#[inline]
pub fn auto() -> Self {
NonNegative(LengthPercentageOrAuto::Auto)
} }
}
impl ToAnimatedValue for NonNegativeLengthPercentageOrAuto {
type AnimatedValue = LengthPercentageOrAuto;
#[inline]
fn to_animated_value(self) -> Self::AnimatedValue {
self.0
} }
#[inline]
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
NonNegative(animated.clamp_to_non_negative())
}
}
impl LengthPercentageOrAuto {
/// Returns true if the computed value is absolute 0 or 0%. /// Returns true if the computed value is absolute 0 or 0%.
#[inline] #[inline]
pub fn is_definitely_zero(&self) -> bool { pub fn is_definitely_zero(&self) -> bool {
use self::LengthPercentageOrAuto::*; use values::generics::length::LengthPercentageOrAuto::*;
match *self { match *self {
LengthPercentage(ref l) => l.is_definitely_zero(), LengthPercentage(ref l) => l.is_definitely_zero(),
Auto => false, Auto => false,
} }
} }
}
}
/// A computed type for `<length-percentage> | auto`.
pub type LengthPercentageOrAuto = generics::GenericLengthPercentageOrAuto<LengthPercentage>;
impl LengthPercentageOrAuto {
/// Clamps the value to a non-negative value. /// Clamps the value to a non-negative value.
pub fn clamp_to_non_negative(self) -> Self { pub fn clamp_to_non_negative(self) -> Self {
use self::LengthPercentageOrAuto::*; use values::generics::length::LengthPercentageOrAuto::*;
match self { match self {
LengthPercentage(l) => LengthPercentage(l.clamp_to_non_negative()), LengthPercentage(l) => LengthPercentage(l.clamp_to_non_negative()),
Auto => Auto, Auto => Auto,
} }
} }
computed_length_percentage_or_auto!(LengthPercentage);
} }
impl ToComputedValue for specified::LengthPercentageOrAuto { /// A wrapper of LengthPercentageOrAuto, whose value must be >= 0.
type ComputedValue = LengthPercentageOrAuto; pub type NonNegativeLengthPercentageOrAuto =
generics::LengthPercentageOrAuto<NonNegativeLengthPercentage>;
#[inline] impl NonNegativeLengthPercentageOrAuto {
fn to_computed_value(&self, context: &Context) -> LengthPercentageOrAuto { computed_length_percentage_or_auto!(NonNegativeLengthPercentage);
match *self {
specified::LengthPercentageOrAuto::LengthPercentage(ref value) => {
LengthPercentageOrAuto::LengthPercentage(value.to_computed_value(context))
},
specified::LengthPercentageOrAuto::Auto => LengthPercentageOrAuto::Auto,
}
}
#[inline]
fn from_computed_value(computed: &LengthPercentageOrAuto) -> Self {
match *computed {
LengthPercentageOrAuto::Auto => specified::LengthPercentageOrAuto::Auto,
LengthPercentageOrAuto::LengthPercentage(ref value) => {
specified::LengthPercentageOrAuto::LengthPercentage(
ToComputedValue::from_computed_value(value),
)
},
}
}
}
#[allow(missing_docs)]
#[css(derive_debug)]
#[derive(
Animate, Clone, ComputeSquaredDistance, Copy, MallocSizeOf, PartialEq, ToAnimatedZero, ToCss,
)]
pub enum LengthPercentageOrNone {
LengthPercentage(LengthPercentage),
None,
}
impl LengthPercentageOrNone {
/// Returns the used value.
pub fn to_used_value(&self, containing_length: Au) -> Option<Au> {
match *self {
LengthPercentageOrNone::None => None,
LengthPercentageOrNone::LengthPercentage(ref lp) => {
Some(lp.to_used_value(containing_length))
},
}
}
}
// FIXME(emilio): Derive this.
impl ToComputedValue for specified::LengthPercentageOrNone {
type ComputedValue = LengthPercentageOrNone;
#[inline]
fn to_computed_value(&self, context: &Context) -> LengthPercentageOrNone {
match *self {
specified::LengthPercentageOrNone::LengthPercentage(ref value) => {
LengthPercentageOrNone::LengthPercentage(value.to_computed_value(context))
},
specified::LengthPercentageOrNone::None => LengthPercentageOrNone::None,
}
}
#[inline]
fn from_computed_value(computed: &LengthPercentageOrNone) -> Self {
match *computed {
LengthPercentageOrNone::None => specified::LengthPercentageOrNone::None,
LengthPercentageOrNone::LengthPercentage(value) => {
specified::LengthPercentageOrNone::LengthPercentage(
ToComputedValue::from_computed_value(&value),
)
},
}
}
} }
/// A wrapper of LengthPercentage, whose value must be >= 0. /// A wrapper of LengthPercentage, whose value must be >= 0.
@ -628,13 +542,6 @@ impl From<LengthPercentage> for NonNegativeLengthPercentage {
} }
} }
impl From<NonNegativeLengthPercentage> for LengthPercentage {
#[inline]
fn from(lp: NonNegativeLengthPercentage) -> LengthPercentage {
lp.0
}
}
// TODO(emilio): This is a really generic impl which is only needed to implement // TODO(emilio): This is a really generic impl which is only needed to implement
// Animated and co for Spacing<>. Get rid of this, probably? // Animated and co for Spacing<>. Get rid of this, probably?
impl From<Au> for LengthPercentage { impl From<Au> for LengthPercentage {
@ -648,7 +555,7 @@ impl NonNegativeLengthPercentage {
/// Get zero value. /// Get zero value.
#[inline] #[inline]
pub fn zero() -> Self { pub fn zero() -> Self {
NonNegative::<LengthPercentage>(LengthPercentage::zero()) NonNegative(LengthPercentage::zero())
} }
/// Returns true if the computed value is absolute 0 or 0%. /// Returns true if the computed value is absolute 0 or 0%.
@ -660,7 +567,26 @@ impl NonNegativeLengthPercentage {
/// Returns the used value. /// Returns the used value.
#[inline] #[inline]
pub fn to_used_value(&self, containing_length: Au) -> Au { pub fn to_used_value(&self, containing_length: Au) -> Au {
self.0.to_used_value(containing_length) let resolved = self.0.to_used_value(containing_length);
::std::cmp::max(resolved, Au(0))
}
/// Convert the computed value into used value.
#[inline]
pub fn maybe_to_used_value(&self, containing_length: Option<Au>) -> Option<Au> {
let resolved = self.0.maybe_to_used_value(containing_length)?;
Some(::std::cmp::max(resolved, Au(0)))
}
}
#[cfg(feature = "servo")]
impl MaxLength {
/// Convert the computed value into used value.
pub fn to_used_value(&self, percentage_basis: Au) -> Option<Au> {
match *self {
GenericMaxLength::None => None,
GenericMaxLength::LengthPercentage(ref lp) => Some(lp.to_used_value(percentage_basis)),
}
} }
} }
@ -678,6 +604,7 @@ impl NonNegativeLengthPercentage {
ToAnimatedValue, ToAnimatedValue,
ToAnimatedZero, ToAnimatedZero,
)] )]
#[repr(C)]
pub struct CSSPixelLength(CSSFloat); pub struct CSSPixelLength(CSSFloat);
impl CSSPixelLength { impl CSSPixelLength {
@ -878,6 +805,8 @@ pub type NonNegativeLengthPercentageOrNormal = Either<NonNegativeLengthPercentag
Parse, Parse,
PartialEq, PartialEq,
SpecifiedValueInfo, SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue, ToComputedValue,
ToCss, ToCss,
)] )]
@ -892,23 +821,7 @@ pub enum ExtremumLength {
} }
/// A computed value for `min-width`, `min-height`, `width` or `height` property. /// A computed value for `min-width`, `min-height`, `width` or `height` property.
pub type MozLength = GenericMozLength<LengthPercentageOrAuto>; pub type MozLength = GenericMozLength<NonNegativeLengthPercentage>;
impl MozLength {
/// Returns the `auto` value.
#[inline]
pub fn auto() -> Self {
GenericMozLength::LengthPercentageOrAuto(LengthPercentageOrAuto::Auto)
}
}
/// A computed value for `max-width` or `min-height` property. /// A computed value for `max-width` or `min-height` property.
pub type MaxLength = GenericMaxLength<LengthPercentageOrNone>; pub type MaxLength = GenericMaxLength<NonNegativeLengthPercentage>;
impl MaxLength {
/// Returns the `none` value.
#[inline]
pub fn none() -> Self {
GenericMaxLength::LengthPercentageOrNone(LengthPercentageOrNone::None)
}
}

View file

@ -62,7 +62,7 @@ pub use self::gecko::ScrollSnapPoint;
pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, MozImageRect}; pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, MozImageRect};
pub use self::length::{CSSPixelLength, ExtremumLength, NonNegativeLength}; pub use self::length::{CSSPixelLength, ExtremumLength, NonNegativeLength};
pub use self::length::{Length, LengthOrNumber, LengthPercentage}; pub use self::length::{Length, LengthOrNumber, LengthPercentage};
pub use self::length::{LengthPercentageOrAuto, LengthPercentageOrNone, MaxLength, MozLength}; pub use self::length::{LengthPercentageOrAuto, MaxLength, MozLength};
pub use self::length::{NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto}; pub use self::length::{NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto};
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
pub use self::list::ListStyleType; pub use self::list::ListStyleType;

View file

@ -4,7 +4,7 @@
//! Generic types for CSS values related to backgrounds. //! Generic types for CSS values related to backgrounds.
use crate::values::IsAuto; use crate::values::generics::length::LengthPercentageOrAuto;
use std::fmt::{self, Write}; use std::fmt::{self, Write};
use style_traits::{CssWriter, ToCss}; use style_traits::{CssWriter, ToCss};
@ -22,13 +22,13 @@ use style_traits::{CssWriter, ToCss};
ToAnimatedZero, ToAnimatedZero,
ToComputedValue, ToComputedValue,
)] )]
pub enum BackgroundSize<LengthPercentageOrAuto> { pub enum BackgroundSize<LengthPercentage> {
/// `<width> <height>` /// `<width> <height>`
Explicit { Explicit {
/// Explicit width. /// Explicit width.
width: LengthPercentageOrAuto, width: LengthPercentageOrAuto<LengthPercentage>,
/// Explicit height. /// Explicit height.
height: LengthPercentageOrAuto, height: LengthPercentageOrAuto<LengthPercentage>,
}, },
/// `cover` /// `cover`
#[animation(error)] #[animation(error)]
@ -38,9 +38,9 @@ pub enum BackgroundSize<LengthPercentageOrAuto> {
Contain, Contain,
} }
impl<LengthPercentageOrAuto> ToCss for BackgroundSize<LengthPercentageOrAuto> impl<LengthPercentage> ToCss for BackgroundSize<LengthPercentage>
where where
LengthPercentageOrAuto: ToCss + IsAuto, LengthPercentage: ToCss,
{ {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where where

View file

@ -4,7 +4,75 @@
//! Generic types for CSS values related to length. //! Generic types for CSS values related to length.
use crate::parser::{Parse, ParserContext};
use crate::values::computed::ExtremumLength; use crate::values::computed::ExtremumLength;
use cssparser::Parser;
use style_traits::ParseError;
/// A `<length-percentage> | auto` value.
#[allow(missing_docs)]
#[derive(
Animate,
Clone,
ComputeSquaredDistance,
Copy,
Debug,
MallocSizeOf,
PartialEq,
SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue,
ToCss,
)]
#[repr(C, u8)]
pub enum GenericLengthPercentageOrAuto<LengthPercent> {
LengthPercentage(LengthPercent),
Auto,
}
pub use self::GenericLengthPercentageOrAuto as LengthPercentageOrAuto;
impl<LengthPercentage> LengthPercentageOrAuto<LengthPercentage> {
/// `auto` value.
#[inline]
pub fn auto() -> Self {
LengthPercentageOrAuto::Auto
}
/// Whether this is the `auto` value.
#[inline]
pub fn is_auto(&self) -> bool {
matches!(*self, LengthPercentageOrAuto::Auto)
}
/// A helper function to parse this with quirks or not and so forth.
pub fn parse_with<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
parser: impl FnOnce(
&ParserContext,
&mut Parser<'i, 't>,
) -> Result<LengthPercentage, ParseError<'i>>,
) -> Result<Self, ParseError<'i>> {
if input.try(|i| i.expect_ident_matching("auto")).is_ok() {
return Ok(LengthPercentageOrAuto::Auto);
}
Ok(LengthPercentageOrAuto::LengthPercentage(parser(
context, input,
)?))
}
}
impl<LengthPercentage: Parse> Parse for LengthPercentageOrAuto<LengthPercentage> {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
Self::parse_with(context, input, LengthPercentage::parse)
}
}
/// A generic value for the `width`, `height`, `min-width`, or `min-height` property. /// A generic value for the `width`, `height`, `min-width`, or `min-height` property.
/// ///
@ -13,25 +81,35 @@ use crate::values::computed::ExtremumLength;
/// ///
/// Note that it only accepts non-negative values. /// Note that it only accepts non-negative values.
#[allow(missing_docs)] #[allow(missing_docs)]
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
#[derive( #[derive(
Animate, Animate,
Clone, Clone,
ComputeSquaredDistance, ComputeSquaredDistance,
Copy, Copy,
Debug, Debug,
MallocSizeOf,
PartialEq, PartialEq,
SpecifiedValueInfo, SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero, ToAnimatedZero,
ToComputedValue, ToComputedValue,
ToCss, ToCss,
)] )]
pub enum MozLength<LengthPercentageOrAuto> { pub enum MozLength<LengthPercentage> {
LengthPercentageOrAuto(LengthPercentageOrAuto), LengthPercentage(LengthPercentage),
Auto,
#[animation(error)] #[animation(error)]
ExtremumLength(ExtremumLength), ExtremumLength(ExtremumLength),
} }
impl<LengthPercentage> MozLength<LengthPercentage> {
/// `auto` value.
#[inline]
pub fn auto() -> Self {
MozLength::Auto
}
}
/// A generic value for the `max-width` or `max-height` property. /// A generic value for the `max-width` or `max-height` property.
#[allow(missing_docs)] #[allow(missing_docs)]
#[cfg_attr(feature = "servo", derive(MallocSizeOf))] #[cfg_attr(feature = "servo", derive(MallocSizeOf))]
@ -43,12 +121,23 @@ pub enum MozLength<LengthPercentageOrAuto> {
Debug, Debug,
PartialEq, PartialEq,
SpecifiedValueInfo, SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero, ToAnimatedZero,
ToComputedValue, ToComputedValue,
ToCss, ToCss,
)] )]
pub enum MaxLength<LengthPercentageOrNone> { pub enum MaxLength<LengthPercentage> {
LengthPercentageOrNone(LengthPercentageOrNone), LengthPercentage(LengthPercentage),
None,
#[cfg(feature = "gecko")]
#[animation(error)] #[animation(error)]
ExtremumLength(ExtremumLength), ExtremumLength(ExtremumLength),
} }
impl<LengthPercentage> MaxLength<LengthPercentage> {
/// `none` value.
#[inline]
pub fn none() -> Self {
MaxLength::None
}
}

View file

@ -174,6 +174,7 @@ impl SpecifiedValueInfo for CounterStyleOrNone {
ToComputedValue, ToComputedValue,
ToCss, ToCss,
)] )]
#[repr(transparent)]
pub struct NonNegative<T>(pub T); pub struct NonNegative<T>(pub T);
/// A wrapper of greater-than-or-equal-to-one values. /// A wrapper of greater-than-or-equal-to-one values.

View file

@ -23,6 +23,7 @@ use style_traits::{CssWriter, ParseError, ToCss};
ToAnimatedValue, ToAnimatedValue,
ToComputedValue, ToComputedValue,
)] )]
#[repr(C)]
pub struct Rect<T>(pub T, pub T, pub T, pub T); pub struct Rect<T>(pub T, pub T, pub T, pub T);
impl<T> Rect<T> { impl<T> Rect<T> {

View file

@ -6,14 +6,16 @@
use crate::parser::{Parse, ParserContext}; use crate::parser::{Parse, ParserContext};
use crate::values::generics::background::BackgroundSize as GenericBackgroundSize; use crate::values::generics::background::BackgroundSize as GenericBackgroundSize;
use crate::values::specified::length::NonNegativeLengthPercentageOrAuto; use crate::values::specified::length::{
NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto,
};
use cssparser::Parser; use cssparser::Parser;
use selectors::parser::SelectorParseErrorKind; use selectors::parser::SelectorParseErrorKind;
use std::fmt::{self, Write}; use std::fmt::{self, Write};
use style_traits::{CssWriter, ParseError, ToCss}; use style_traits::{CssWriter, ParseError, ToCss};
/// A specified value for the `background-size` property. /// A specified value for the `background-size` property.
pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentageOrAuto>; pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentage>;
impl Parse for BackgroundSize { impl Parse for BackgroundSize {
fn parse<'i, 't>( fn parse<'i, 't>(

View file

@ -4,21 +4,19 @@
//! Specified types for legacy Gecko-only properties. //! Specified types for legacy Gecko-only properties.
use crate::gecko::values::GeckoStyleCoordConvertible;
use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut};
use crate::parser::{Parse, ParserContext}; use crate::parser::{Parse, ParserContext};
use crate::values::computed;
use crate::values::computed::length::CSSPixelLength; use crate::values::computed::length::CSSPixelLength;
use crate::values::computed::{self, LengthPercentage};
use crate::values::generics::gecko::ScrollSnapPoint as GenericScrollSnapPoint; use crate::values::generics::gecko::ScrollSnapPoint as GenericScrollSnapPoint;
use crate::values::generics::rect::Rect; use crate::values::generics::rect::Rect;
use crate::values::specified::length::LengthPercentage; use crate::values::specified::length::LengthPercentage as SpecifiedLengthPercentage;
use cssparser::{Parser, Token}; use cssparser::{Parser, Token};
use std::fmt; use std::fmt;
use style_traits::values::SequenceWriter; use style_traits::values::SequenceWriter;
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
/// A specified type for scroll snap points. /// A specified type for scroll snap points.
pub type ScrollSnapPoint = GenericScrollSnapPoint<LengthPercentage>; pub type ScrollSnapPoint = GenericScrollSnapPoint<SpecifiedLengthPercentage>;
impl Parse for ScrollSnapPoint { impl Parse for ScrollSnapPoint {
fn parse<'i, 't>( fn parse<'i, 't>(
@ -29,26 +27,17 @@ impl Parse for ScrollSnapPoint {
return Ok(GenericScrollSnapPoint::None); return Ok(GenericScrollSnapPoint::None);
} }
input.expect_function_matching("repeat")?; input.expect_function_matching("repeat")?;
let length = // FIXME(emilio): This won't clamp properly when animating.
input.parse_nested_block(|i| LengthPercentage::parse_non_negative(context, i))?; let length = input
.parse_nested_block(|i| SpecifiedLengthPercentage::parse_non_negative(context, i))?;
Ok(GenericScrollSnapPoint::Repeat(length)) Ok(GenericScrollSnapPoint::Repeat(length))
} }
} }
/// A component of an IntersectionObserverRootMargin. fn parse_pixel_or_percent<'i, 't>(
#[derive(Clone, Copy, Debug, PartialEq, ToCss)]
pub enum PixelOrPercentage {
/// An absolute length in pixels (px)
Pixel(CSSPixelLength),
/// A percentage (%)
Percentage(computed::Percentage),
}
impl Parse for PixelOrPercentage {
fn parse<'i, 't>(
_context: &ParserContext, _context: &ParserContext,
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> { ) -> Result<LengthPercentage, ParseError<'i>> {
let location = input.current_source_location(); let location = input.current_source_location();
let token = input.next()?; let token = input.next()?;
let value = match *token { let value = match *token {
@ -56,35 +45,16 @@ impl Parse for PixelOrPercentage {
value, ref unit, .. value, ref unit, ..
} => { } => {
match_ignore_ascii_case! { unit, match_ignore_ascii_case! { unit,
"px" => Ok(PixelOrPercentage::Pixel(CSSPixelLength::new(value))), "px" => Ok(LengthPercentage::new(CSSPixelLength::new(value), None)),
_ => Err(()), _ => Err(()),
} }
}, },
Token::Percentage { unit_value, .. } => Ok(PixelOrPercentage::Percentage( Token::Percentage { unit_value, .. } => Ok(LengthPercentage::new_percent(
computed::Percentage(unit_value), computed::Percentage(unit_value),
)), )),
_ => Err(()), _ => Err(()),
}; };
value.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) value.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
}
}
impl GeckoStyleCoordConvertible for PixelOrPercentage {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
match *self {
PixelOrPercentage::Pixel(ref l) => l.to_gecko_style_coord(coord),
PixelOrPercentage::Percentage(ref pc) => pc.to_gecko_style_coord(coord),
}
}
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
CSSPixelLength::from_gecko_style_coord(coord)
.map(PixelOrPercentage::Pixel)
.or_else(|| {
computed::Percentage::from_gecko_style_coord(coord)
.map(PixelOrPercentage::Percentage)
})
}
} }
/// The value of an IntersectionObserver's rootMargin property. /// The value of an IntersectionObserver's rootMargin property.
@ -93,14 +63,15 @@ impl GeckoStyleCoordConvertible for PixelOrPercentage {
/// calc() values are not allowed. /// calc() values are not allowed.
/// ///
/// <https://w3c.github.io/IntersectionObserver/#parse-a-root-margin> /// <https://w3c.github.io/IntersectionObserver/#parse-a-root-margin>
pub struct IntersectionObserverRootMargin(pub Rect<PixelOrPercentage>); #[repr(transparent)]
pub struct IntersectionObserverRootMargin(pub Rect<LengthPercentage>);
impl Parse for IntersectionObserverRootMargin { impl Parse for IntersectionObserverRootMargin {
fn parse<'i, 't>( fn parse<'i, 't>(
context: &ParserContext, context: &ParserContext,
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> { ) -> Result<Self, ParseError<'i>> {
let rect = Rect::parse_with(context, input, PixelOrPercentage::parse)?; let rect = Rect::parse_with(context, input, parse_pixel_or_percent)?;
Ok(IntersectionObserverRootMargin(rect)) Ok(IntersectionObserverRootMargin(rect))
} }
} }

View file

@ -10,12 +10,14 @@ use super::{AllowQuirks, Number, Percentage, ToComputedValue};
use crate::font_metrics::FontMetricsQueryResult; use crate::font_metrics::FontMetricsQueryResult;
use crate::parser::{Parse, ParserContext}; use crate::parser::{Parse, ParserContext};
use crate::values::computed::{self, CSSPixelLength, Context, ExtremumLength}; use crate::values::computed::{self, CSSPixelLength, Context, ExtremumLength};
use crate::values::generics::length::MaxLength as GenericMaxLength; use crate::values::generics::length as generics;
use crate::values::generics::length::MozLength as GenericMozLength; use crate::values::generics::length::{
MaxLength as GenericMaxLength, MozLength as GenericMozLength,
};
use crate::values::generics::transform::IsZeroLength; use crate::values::generics::transform::IsZeroLength;
use crate::values::generics::NonNegative; use crate::values::generics::NonNegative;
use crate::values::specified::calc::CalcNode; use crate::values::specified::calc::CalcNode;
use crate::values::{Auto, CSSFloat, Either, IsAuto, Normal}; use crate::values::{Auto, CSSFloat, Either, Normal};
use app_units::Au; use app_units::Au;
use cssparser::{Parser, Token}; use cssparser::{Parser, Token};
use euclid::Size2D; use euclid::Size2D;
@ -785,6 +787,16 @@ impl From<computed::Percentage> for LengthPercentage {
} }
} }
impl Parse for LengthPercentage {
#[inline]
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
Self::parse_quirky(context, input, AllowQuirks::No)
}
}
impl LengthPercentage { impl LengthPercentage {
#[inline] #[inline]
/// Returns a `zero` length. /// Returns a `zero` length.
@ -844,12 +856,26 @@ impl LengthPercentage {
Ok(LengthPercentage::Calc(Box::new(calc))) Ok(LengthPercentage::Calc(Box::new(calc)))
} }
/// Parses allowing the unitless length quirk.
/// <https://quirks.spec.whatwg.org/#the-unitless-length-quirk>
#[inline]
pub fn parse_quirky<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
allow_quirks: AllowQuirks,
) -> Result<Self, ParseError<'i>> {
Self::parse_internal(context, input, AllowedNumericType::All, allow_quirks)
}
/// Parse a non-negative length. /// Parse a non-negative length.
///
/// FIXME(emilio): This should be not public and we should use
/// NonNegativeLengthPercentage instead.
#[inline] #[inline]
pub fn parse_non_negative<'i, 't>( pub fn parse_non_negative<'i, 't>(
context: &ParserContext, context: &ParserContext,
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
) -> Result<LengthPercentage, ParseError<'i>> { ) -> Result<Self, ParseError<'i>> {
Self::parse_non_negative_quirky(context, input, AllowQuirks::No) Self::parse_non_negative_quirky(context, input, AllowQuirks::No)
} }
@ -859,7 +885,7 @@ impl LengthPercentage {
context: &ParserContext, context: &ParserContext,
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
allow_quirks: AllowQuirks, allow_quirks: AllowQuirks,
) -> Result<LengthPercentage, ParseError<'i>> { ) -> Result<Self, ParseError<'i>> {
Self::parse_internal( Self::parse_internal(
context, context,
input, input,
@ -869,29 +895,6 @@ impl LengthPercentage {
} }
} }
impl Parse for LengthPercentage {
#[inline]
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
Self::parse_quirky(context, input, AllowQuirks::No)
}
}
impl LengthPercentage {
/// Parses a length or a percentage, allowing the unitless length quirk.
/// <https://quirks.spec.whatwg.org/#the-unitless-length-quirk>
#[inline]
pub fn parse_quirky<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
allow_quirks: AllowQuirks,
) -> Result<Self, ParseError<'i>> {
Self::parse_internal(context, input, AllowedNumericType::All, allow_quirks)
}
}
impl IsZeroLength for LengthPercentage { impl IsZeroLength for LengthPercentage {
#[inline] #[inline]
fn is_zero_length(&self) -> bool { fn is_zero_length(&self) -> bool {
@ -903,189 +906,64 @@ impl IsZeroLength for LengthPercentage {
} }
} }
/// Either a `<length>`, a `<percentage>`, or the `auto` keyword. /// A specified type for `<length-percentage> | auto`.
#[allow(missing_docs)] pub type LengthPercentageOrAuto = generics::LengthPercentageOrAuto<LengthPercentage>;
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)]
pub enum LengthPercentageOrAuto {
LengthPercentage(LengthPercentage),
Auto,
}
impl LengthPercentageOrAuto { impl LengthPercentageOrAuto {
fn parse_internal<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
num_context: AllowedNumericType,
allow_quirks: AllowQuirks,
) -> Result<Self, ParseError<'i>> {
if input.try(|i| i.expect_ident_matching("auto")).is_ok() {
return Ok(LengthPercentageOrAuto::Auto);
}
Ok(LengthPercentageOrAuto::LengthPercentage(
LengthPercentage::parse_internal(context, input, num_context, allow_quirks)?,
))
}
/// Parse a non-negative length, percentage, or auto.
#[inline]
pub fn parse_non_negative<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<LengthPercentageOrAuto, ParseError<'i>> {
Self::parse_non_negative_quirky(context, input, AllowQuirks::No)
}
/// Parse a non-negative length, percentage, or auto.
#[inline]
pub fn parse_non_negative_quirky<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
allow_quirks: AllowQuirks,
) -> Result<Self, ParseError<'i>> {
Self::parse_internal(
context,
input,
AllowedNumericType::NonNegative,
allow_quirks,
)
}
/// Returns the `auto` value.
pub fn auto() -> Self {
LengthPercentageOrAuto::Auto
}
/// Returns a value representing a `0` length. /// Returns a value representing a `0` length.
pub fn zero() -> Self { pub fn zero() -> Self {
LengthPercentageOrAuto::LengthPercentage(LengthPercentage::zero()) generics::LengthPercentageOrAuto::LengthPercentage(LengthPercentage::zero())
} }
/// Returns a value representing `0%`. /// Returns a value representing `0%`.
#[inline] #[inline]
pub fn zero_percent() -> Self { pub fn zero_percent() -> Self {
LengthPercentageOrAuto::LengthPercentage(LengthPercentage::zero_percent()) generics::LengthPercentageOrAuto::LengthPercentage(LengthPercentage::zero_percent())
} }
/// Parses, with quirks. /// Parses a length or a percentage, allowing the unitless length quirk.
/// <https://quirks.spec.whatwg.org/#the-unitless-length-quirk>
#[inline] #[inline]
pub fn parse_quirky<'i, 't>( pub fn parse_quirky<'i, 't>(
context: &ParserContext, context: &ParserContext,
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
allow_quirks: AllowQuirks, allow_quirks: AllowQuirks,
) -> Result<Self, ParseError<'i>> { ) -> Result<Self, ParseError<'i>> {
Self::parse_internal(context, input, AllowedNumericType::All, allow_quirks) Self::parse_with(context, input, |context, input| {
} LengthPercentage::parse_quirky(context, input, allow_quirks)
} })
impl Parse for LengthPercentageOrAuto {
#[inline]
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
Self::parse_quirky(context, input, AllowQuirks::No)
} }
} }
/// A wrapper of LengthPercentageOrAuto, whose value must be >= 0. /// A wrapper of LengthPercentageOrAuto, whose value must be >= 0.
pub type NonNegativeLengthPercentageOrAuto = NonNegative<LengthPercentageOrAuto>; pub type NonNegativeLengthPercentageOrAuto =
generics::LengthPercentageOrAuto<NonNegativeLengthPercentage>;
impl IsAuto for NonNegativeLengthPercentageOrAuto {
#[inline]
fn is_auto(&self) -> bool {
*self == Self::auto()
}
}
impl NonNegativeLengthPercentageOrAuto { impl NonNegativeLengthPercentageOrAuto {
/// 0 /// Returns a value representing a `0` length.
#[inline]
pub fn zero() -> Self { pub fn zero() -> Self {
NonNegative(LengthPercentageOrAuto::zero()) generics::LengthPercentageOrAuto::LengthPercentage(NonNegativeLengthPercentage::zero())
} }
/// 0% /// Returns a value representing `0%`.
#[inline] #[inline]
pub fn zero_percent() -> Self { pub fn zero_percent() -> Self {
NonNegative(LengthPercentageOrAuto::zero_percent()) generics::LengthPercentageOrAuto::LengthPercentage(
} NonNegativeLengthPercentage::zero_percent(),
/// `auto`
#[inline]
pub fn auto() -> Self {
NonNegative(LengthPercentageOrAuto::Auto)
}
}
impl Parse for NonNegativeLengthPercentageOrAuto {
#[inline]
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
Ok(NonNegative(LengthPercentageOrAuto::parse_non_negative(
context, input,
)?))
}
}
/// Either a `<length>`, a `<percentage>`, or the `none` keyword.
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)]
#[allow(missing_docs)]
pub enum LengthPercentageOrNone {
LengthPercentage(LengthPercentage),
None,
}
impl LengthPercentageOrNone {
fn parse_internal<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
num_context: AllowedNumericType,
allow_quirks: AllowQuirks,
) -> Result<Self, ParseError<'i>> {
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
return Ok(LengthPercentageOrNone::None);
}
Ok(LengthPercentageOrNone::LengthPercentage(
LengthPercentage::parse_internal(context, input, num_context, allow_quirks)?,
))
}
/// Parse a non-negative LengthPercentageOrNone.
#[inline]
pub fn parse_non_negative<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
Self::parse_non_negative_quirky(context, input, AllowQuirks::No)
}
/// Parse a non-negative LengthPercentageOrNone, with quirks.
#[inline]
pub fn parse_non_negative_quirky<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
allow_quirks: AllowQuirks,
) -> Result<Self, ParseError<'i>> {
Self::parse_internal(
context,
input,
AllowedNumericType::NonNegative,
allow_quirks,
) )
} }
}
impl Parse for LengthPercentageOrNone { /// Parses a non-negative length-percentage, allowing the unitless length
/// quirk.
#[inline] #[inline]
fn parse<'i, 't>( pub fn parse_quirky<'i, 't>(
context: &ParserContext, context: &ParserContext,
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
allow_quirks: AllowQuirks,
) -> Result<Self, ParseError<'i>> { ) -> Result<Self, ParseError<'i>> {
Self::parse_internal(context, input, AllowedNumericType::All, AllowQuirks::No) Self::parse_with(context, input, |context, input| {
NonNegativeLengthPercentage::parse_quirky(context, input, allow_quirks)
})
} }
} }
@ -1101,7 +979,7 @@ pub type NonNegativeLengthPercentageOrNormal = Either<NonNegativeLengthPercentag
impl From<NoCalcLength> for NonNegativeLengthPercentage { impl From<NoCalcLength> for NonNegativeLengthPercentage {
#[inline] #[inline]
fn from(len: NoCalcLength) -> Self { fn from(len: NoCalcLength) -> Self {
NonNegative::<LengthPercentage>(LengthPercentage::from(len)) NonNegative(LengthPercentage::from(len))
} }
} }
@ -1111,7 +989,7 @@ impl Parse for NonNegativeLengthPercentage {
context: &ParserContext, context: &ParserContext,
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> { ) -> Result<Self, ParseError<'i>> {
LengthPercentage::parse_non_negative(context, input).map(NonNegative::<LengthPercentage>) Self::parse_quirky(context, input, AllowQuirks::No)
} }
} }
@ -1119,7 +997,13 @@ impl NonNegativeLengthPercentage {
#[inline] #[inline]
/// Returns a `zero` length. /// Returns a `zero` length.
pub fn zero() -> Self { pub fn zero() -> Self {
NonNegative::<LengthPercentage>(LengthPercentage::zero()) NonNegative(LengthPercentage::zero())
}
#[inline]
/// Returns a `0%` value.
pub fn zero_percent() -> Self {
NonNegative(LengthPercentage::zero_percent())
} }
/// Parses a length or a percentage, allowing the unitless length quirk. /// Parses a length or a percentage, allowing the unitless length quirk.
@ -1130,8 +1014,7 @@ impl NonNegativeLengthPercentage {
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
allow_quirks: AllowQuirks, allow_quirks: AllowQuirks,
) -> Result<Self, ParseError<'i>> { ) -> Result<Self, ParseError<'i>> {
LengthPercentage::parse_non_negative_quirky(context, input, allow_quirks) LengthPercentage::parse_non_negative_quirky(context, input, allow_quirks).map(NonNegative)
.map(NonNegative::<LengthPercentage>)
} }
} }
@ -1168,7 +1051,7 @@ impl LengthOrNumber {
} }
/// A specified value for `min-width`, `min-height`, `width` or `height` property. /// A specified value for `min-width`, `min-height`, `width` or `height` property.
pub type MozLength = GenericMozLength<LengthPercentageOrAuto>; pub type MozLength = GenericMozLength<NonNegativeLengthPercentage>;
impl Parse for MozLength { impl Parse for MozLength {
fn parse<'i, 't>( fn parse<'i, 't>(
@ -1190,26 +1073,23 @@ impl MozLength {
return Ok(GenericMozLength::ExtremumLength(l)); return Ok(GenericMozLength::ExtremumLength(l));
} }
let length = if input.try(|i| i.expect_ident_matching("auto")).is_ok() {
LengthPercentageOrAuto::parse_non_negative_quirky(context, input, allow_quirks)?; return Ok(GenericMozLength::Auto);
Ok(GenericMozLength::LengthPercentageOrAuto(length))
} }
/// Returns `auto`. let length = NonNegativeLengthPercentage::parse_quirky(context, input, allow_quirks)?;
#[inline] Ok(GenericMozLength::LengthPercentage(length))
pub fn auto() -> Self {
GenericMozLength::LengthPercentageOrAuto(LengthPercentageOrAuto::auto())
} }
/// Returns `0%`. /// Returns `0%`.
#[inline] #[inline]
pub fn zero_percent() -> Self { pub fn zero_percent() -> Self {
GenericMozLength::LengthPercentageOrAuto(LengthPercentageOrAuto::zero_percent()) GenericMozLength::LengthPercentage(NonNegativeLengthPercentage::zero_percent())
} }
} }
/// A specified value for `max-width` or `max-height` property. /// A specified value for `max-width` or `max-height` property.
pub type MaxLength = GenericMaxLength<LengthPercentageOrNone>; pub type MaxLength = GenericMaxLength<NonNegativeLengthPercentage>;
impl Parse for MaxLength { impl Parse for MaxLength {
fn parse<'i, 't>( fn parse<'i, 't>(
@ -1227,12 +1107,18 @@ impl MaxLength {
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
allow_quirks: AllowQuirks, allow_quirks: AllowQuirks,
) -> Result<Self, ParseError<'i>> { ) -> Result<Self, ParseError<'i>> {
#[cfg(feature = "gecko")]
{
if let Ok(l) = input.try(ExtremumLength::parse) { if let Ok(l) = input.try(ExtremumLength::parse) {
return Ok(GenericMaxLength::ExtremumLength(l)); return Ok(GenericMaxLength::ExtremumLength(l));
} }
}
let length = if input.try(|i| i.expect_ident_matching("none")).is_ok() {
LengthPercentageOrNone::parse_non_negative_quirky(context, input, allow_quirks)?; return Ok(GenericMaxLength::None);
Ok(GenericMaxLength::LengthPercentageOrNone(length)) }
let length = NonNegativeLengthPercentage::parse_quirky(context, input, allow_quirks)?;
Ok(GenericMaxLength::LengthPercentage(length))
} }
} }

View file

@ -59,7 +59,7 @@ pub use self::image::{GradientItem, GradientKind, Image, ImageLayer, MozImageRec
pub use self::length::{AbsoluteLength, CalcLengthPercentage, CharacterWidth}; pub use self::length::{AbsoluteLength, CalcLengthPercentage, CharacterWidth};
pub use self::length::{FontRelativeLength, Length, LengthOrNumber}; pub use self::length::{FontRelativeLength, Length, LengthOrNumber};
pub use self::length::{LengthPercentage, LengthPercentageOrAuto}; pub use self::length::{LengthPercentage, LengthPercentageOrAuto};
pub use self::length::{LengthPercentageOrNone, MaxLength, MozLength}; pub use self::length::{MaxLength, MozLength};
pub use self::length::{NoCalcLength, ViewportPercentageLength}; pub use self::length::{NoCalcLength, ViewportPercentageLength};
pub use self::length::{NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto}; pub use self::length::{NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto};
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]

View file

@ -303,7 +303,7 @@ textarea { white-space: pre-wrap; }
/* intentionally not !important */ /* intentionally not !important */
object-fit:contain; object-fit:contain;
/* The internal-only -servo-top-layer attribute is used /* The internal-only -servo-top-layer property is used
to implement https://fullscreen.spec.whatwg.org/#top-layer */ to implement https://fullscreen.spec.whatwg.org/#top-layer */
-servo-top-layer: top; -servo-top-layer: top;
} }

View file

@ -14,8 +14,9 @@ use style::parser::ParserContext;
use style::shared_lock::{SharedRwLock, StylesheetGuards}; use style::shared_lock::{SharedRwLock, StylesheetGuards};
use style::stylesheets::viewport_rule::*; use style::stylesheets::viewport_rule::*;
use style::stylesheets::{CssRuleType, Origin, Stylesheet, StylesheetInDocument}; use style::stylesheets::{CssRuleType, Origin, Stylesheet, StylesheetInDocument};
use style::values::generics::length::LengthPercentageOrAuto::{self, Auto};
use style::values::generics::NonNegative;
use style::values::specified::LengthPercentage; use style::values::specified::LengthPercentage;
use style::values::specified::LengthPercentageOrAuto::{self, Auto};
use style::values::specified::NoCalcLength::{self, ViewportPercentage}; use style::values::specified::NoCalcLength::{self, ViewportPercentage};
use style::values::specified::ViewportPercentageLength::Vw; use style::values::specified::ViewportPercentageLength::Vw;
use style_traits::viewport::*; use style_traits::viewport::*;
@ -97,14 +98,14 @@ macro_rules! assert_decl_len {
macro_rules! viewport_length { macro_rules! viewport_length {
($value:expr, px) => { ($value:expr, px) => {
ViewportLength::Specified(LengthPercentageOrAuto::LengthPercentage( ViewportLength::Specified(LengthPercentageOrAuto::LengthPercentage(NonNegative(
LengthPercentage::Length(NoCalcLength::from_px($value)), LengthPercentage::Length(NoCalcLength::from_px($value)),
)) )))
}; };
($value:expr, vw) => { ($value:expr, vw) => {
ViewportLength::Specified(LengthPercentageOrAuto::LengthPercentage( ViewportLength::Specified(LengthPercentageOrAuto::LengthPercentage(NonNegative(
LengthPercentage::Length(ViewportPercentage(Vw($value))), LengthPercentage::Length(ViewportPercentage(Vw($value))),
)) )))
}; };
} }