diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2019-02-10 17:00:26 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-10 17:00:26 -0500 |
commit | aeeaf9dda1936acc82ab039fd6fdd887e6add043 (patch) | |
tree | fb16f7cd6bc983f2ac00f54767d102d0e2a186ab | |
parent | a019ed1f80e9ecfe20d797d8e1304771e0fb0af7 (diff) | |
parent | 6daebcc5dfc4e57d2f9e9450aa01b8c67dd34986 (diff) | |
download | servo-aeeaf9dda1936acc82ab039fd6fdd887e6add043.tar.gz servo-aeeaf9dda1936acc82ab039fd6fdd887e6add043.zip |
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 -->
40 files changed, 662 insertions, 792 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs index 0e4bf140d42..3d19ed1072a 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -67,7 +67,9 @@ use style::context::SharedStyleContext; use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect, LogicalSize, WritingMode}; use style::properties::ComputedValues; use style::servo::restyle_damage::ServoRestyleDamage; -use style::values::computed::{LengthPercentageOrAuto, LengthPercentageOrNone}; +use style::values::computed::{ + LengthPercentageOrAuto, MaxLength, NonNegativeLengthPercentageOrAuto, +}; /// Information specific to floated blocks. #[derive(Clone, Serialize)] @@ -419,15 +421,15 @@ impl CandidateBSizeIterator { // `min-height` and `max-height`, percentage values are ignored. let block_size = match fragment.style.content_block_size() { - LengthPercentageOrAuto::Auto => MaybeAuto::Auto, - LengthPercentageOrAuto::LengthPercentage(ref lp) => { + NonNegativeLengthPercentageOrAuto::Auto => MaybeAuto::Auto, + NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => { MaybeAuto::from_option(lp.maybe_to_used_value(block_container_block_size)) }, }; let max_block_size = match fragment.style.max_block_size() { - LengthPercentageOrNone::None => None, - LengthPercentageOrNone::LengthPercentage(ref lp) => { + MaxLength::None => None, + MaxLength::LengthPercentage(ref lp) => { 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(); match content_block_size { - LengthPercentageOrAuto::Auto => { + NonNegativeLengthPercentageOrAuto::Auto => { let container_size = containing_block_size?; let (block_start, block_end) = { let position = self.fragment.style().logical_position(); @@ -1435,7 +1437,7 @@ impl BlockFlow { (_, _) => None, } }, - LengthPercentageOrAuto::LengthPercentage(ref lp) => { + NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => { lp.maybe_to_used_value(containing_block_size) }, } @@ -1797,15 +1799,12 @@ impl BlockFlow { .to_used_value(self.base.block_container_inline_size); let specified_inline_size = self.fragment.style().content_inline_size(); let container_size = self.base.block_container_inline_size; - let inline_size = if let MaybeAuto::Specified(size) = - MaybeAuto::from_style(specified_inline_size, container_size) - { - match self.fragment.style().get_position().box_sizing { + let inline_size = match specified_inline_size.to_used_value(container_size) { + Some(size) => match self.fragment.style().get_position().box_sizing { BoxSizing::BorderBox => size, BoxSizing::ContentBox => size + self.fragment.border_padding.inline_start_end(), - } - } else { - max(min_inline_size, min(available_inline_size, max_inline_size)) + }, + None => max(min_inline_size, min(available_inline_size, max_inline_size)), }; 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 // page set `max-width` in order to avoid hitting floats. The search box on Google // SERPs falls into this category. - if self.fragment.style.max_inline_size() != LengthPercentageOrNone::None { + if self.fragment.style.max_inline_size() != MaxLength::None { return; } @@ -2156,9 +2155,10 @@ impl Flow for BlockFlow { fn bubble_inline_sizes(&mut self) { // If this block has a fixed width, just use that for the minimum and preferred 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 { - LengthPercentageOrAuto::Auto => true, - LengthPercentageOrAuto::LengthPercentage(ref lp) => { + NonNegativeLengthPercentageOrAuto::Auto => true, + NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => { lp.maybe_to_used_value(None).is_none() }, }; @@ -2846,9 +2846,16 @@ pub trait ISizeAndMarginsComputer { parent_flow_inline_size: Au, shared_context: &SharedStyleContext, ) -> MaybeAuto { - MaybeAuto::from_style( - block.fragment().style().content_inline_size(), - self.containing_block_inline_size(block, parent_flow_inline_size, shared_context), + MaybeAuto::from_option( + block + .fragment() + .style() + .content_inline_size() + .to_used_value(self.containing_block_inline_size( + block, + parent_flow_inline_size, + shared_context, + )), ) } diff --git a/components/layout/display_list/background.rs b/components/layout/display_list/background.rs index d914a97e1bf..368818471d5 100644 --- a/components/layout/display_list/background.rs +++ b/components/layout/display_list/background.rs @@ -5,16 +5,14 @@ // FIXME(rust-lang/rust#26264): Remove GenericBackgroundSize. use crate::display_list::border; -use crate::model::MaybeAuto; use app_units::Au; use euclid::{Point2D, Rect, SideOffsets2D, Size2D}; 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_origin::single_value::T as BackgroundOrigin; 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::NonNegative; use style::values::specified::background::BackgroundRepeatKeyword; use webrender_api::BorderRadius; @@ -60,10 +58,12 @@ fn compute_background_image_size( None => match bg_size { GenericBackgroundSize::Cover | GenericBackgroundSize::Contain => bounds_size, GenericBackgroundSize::Explicit { width, height } => Size2D::new( - MaybeAuto::from_style(width.0, bounds_size.width) - .specified_or_default(bounds_size.width), - MaybeAuto::from_style(height.0, bounds_size.height) - .specified_or_default(bounds_size.height), + width + .to_used_value(bounds_size.width) + .unwrap_or(bounds_size.width), + height + .to_used_value(bounds_size.height) + .unwrap_or(bounds_size.height), ), }, Some(own_size) => { @@ -88,30 +88,34 @@ fn compute_background_image_size( ( GenericBackgroundSize::Explicit { width, - height: NonNegative(LengthPercentageOrAuto::Auto), + height: NonNegativeLengthPercentageOrAuto::Auto, }, _, ) => { - let width = MaybeAuto::from_style(width.0, bounds_size.width) - .specified_or_default(own_size.width); + let width = width + .to_used_value(bounds_size.width) + .unwrap_or(own_size.width); Size2D::new(width, width.scale_by(image_aspect_ratio.recip())) }, ( GenericBackgroundSize::Explicit { - width: NonNegative(LengthPercentageOrAuto::Auto), + width: NonNegativeLengthPercentageOrAuto::Auto, height, }, _, ) => { - let height = MaybeAuto::from_style(height.0, bounds_size.height) - .specified_or_default(own_size.height); + let height = height + .to_used_value(bounds_size.height) + .unwrap_or(own_size.height); Size2D::new(height.scale_by(image_aspect_ratio), height) }, (GenericBackgroundSize::Explicit { width, height }, _) => Size2D::new( - MaybeAuto::from_style(width.0, bounds_size.width) - .specified_or_default(own_size.width), - MaybeAuto::from_style(height.0, bounds_size.height) - .specified_or_default(own_size.height), + width + .to_used_value(bounds_size.width) + .unwrap_or(own_size.width), + height + .to_used_value(bounds_size.height) + .unwrap_or(own_size.height), ), } }, diff --git a/components/layout/display_list/builder.rs b/components/layout/display_list/builder.rs index e348086e39a..6de5ac8498c 100644 --- a/components/layout/display_list/builder.rs +++ b/components/layout/display_list/builder.rs @@ -764,10 +764,12 @@ impl Fragment { get_cyclic(&style.get_background().background_size.0, i).clone(); let size = match background_size { BackgroundSize::Explicit { width, height } => Size2D::new( - MaybeAuto::from_style(width.0, bounding_box_size.width) - .specified_or_default(bounding_box_size.width), - MaybeAuto::from_style(height.0, bounding_box_size.height) - .specified_or_default(bounding_box_size.height), + width + .to_used_value(bounding_box_size.width) + .unwrap_or(bounding_box_size.width), + height + .to_used_value(bounding_box_size.height) + .unwrap_or(bounding_box_size.height), ), _ => bounding_box_size, }; diff --git a/components/layout/flex.rs b/components/layout/flex.rs index fd85b0c24c1..770a02c594b 100644 --- a/components/layout/flex.rs +++ b/components/layout/flex.rs @@ -29,7 +29,9 @@ use style::logical_geometry::{Direction, LogicalSize}; use style::properties::ComputedValues; use style::servo::restyle_damage::ServoRestyleDamage; 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; /// 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, /// containing block size, min constraint, and max constraint pub fn new( - size: LengthPercentageOrAuto, + size: NonNegativeLengthPercentageOrAuto, content_size: Option<Au>, - min: LengthPercentage, - max: LengthPercentageOrNone, + min: NonNegativeLengthPercentage, + max: MaxLength, ) -> AxisSize { match size { - LengthPercentageOrAuto::Auto => { + NonNegativeLengthPercentageOrAuto::Auto => { 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) { Some(length) => AxisSize::Definite(length), None => AxisSize::Infinite, @@ -70,7 +72,7 @@ impl AxisSize { /// is definite after flex size resolving. fn from_flex_basis( flex_basis: FlexBasis, - main_length: LengthPercentageOrAuto, + main_length: NonNegativeLengthPercentageOrAuto, containing_length: Au, ) -> MaybeAuto { let width = match flex_basis { @@ -78,9 +80,16 @@ fn from_flex_basis( GenericFlexBasis::Width(width) => width, }; - match width.0 { - LengthPercentageOrAuto::Auto => MaybeAuto::from_style(main_length, containing_length), - other => MaybeAuto::from_style(other, containing_length), + let width = match width { + NonNegativeLengthPercentageOrAuto::Auto => main_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; match direction { Direction::Inline => { - if margin.inline_start == LengthPercentageOrAuto::Auto { + if margin.inline_start.is_auto() { margin_count += 1; } - if margin.inline_end == LengthPercentageOrAuto::Auto { + if margin.inline_end.is_auto() { margin_count += 1; } }, Direction::Block => { - if margin.block_start == LengthPercentageOrAuto::Auto { + if margin.block_start.is_auto() { margin_count += 1; } - if margin.block_end == LengthPercentageOrAuto::Auto { + if margin.block_end.is_auto() { margin_count += 1; } }, @@ -816,7 +825,7 @@ impl FlexFlow { // cross size of item should equal to the line size if any auto margin exists. // https://drafts.csswg.org/css-flexbox/#algo-cross-margins 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) { Au(0) } else { @@ -830,7 +839,7 @@ impl FlexFlow { let self_align = block.fragment.style().get_position().align_self; 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); block.base.block_container_explicit_block_size = Some(line.cross_size); diff --git a/components/layout/floats.rs b/components/layout/floats.rs index 5a58e27f9d1..e3274c1ed91 100644 --- a/components/layout/floats.rs +++ b/components/layout/floats.rs @@ -10,7 +10,7 @@ use std::cmp::{max, min}; use std::fmt; use style::computed_values::float::T as StyleFloat; use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode}; -use style::values::computed::LengthPercentageOrAuto; +use style::values::computed::NonNegativeLengthPercentageOrAuto; /// The kind of float: left or right. #[derive(Clone, Copy, Debug, Serialize)] @@ -549,9 +549,9 @@ impl SpeculatedFloatPlacement { // might flow around this float. let inline_size = flow.as_block().fragment.style.content_inline_size(); let fixed = match inline_size { - LengthPercentageOrAuto::Auto => false, - LengthPercentageOrAuto::LengthPercentage(ref lp) => { - lp.is_definitely_zero() || lp.maybe_to_used_value(None).is_some() + NonNegativeLengthPercentageOrAuto::Auto => false, + NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => { + lp.0.is_definitely_zero() || lp.0.maybe_to_used_value(None).is_some() }, }; if !fixed { diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index db4fd8f4625..1efd40003e6 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -61,7 +61,9 @@ use style::selector_parser::RestyleDamage; use style::servo::restyle_damage::ServoRestyleDamage; use style::str::char_is_whitespace; 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::transform; use webrender_api::{self, LayoutTransform}; @@ -985,8 +987,10 @@ impl Fragment { if flags.contains( QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED, ) { - specified = - MaybeAuto::from_style(style.content_inline_size(), Au(0)).specified_or_zero(); + specified = style + .content_inline_size() + .to_used_value(Au(0)) + .unwrap_or(Au(0)); 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)) { specified = min(specified, max) @@ -1611,8 +1615,8 @@ impl Fragment { SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Svg(_) => { let inline_size = match self.style.content_inline_size() { - LengthPercentageOrAuto::Auto => None, - LengthPercentageOrAuto::LengthPercentage(ref lp) => { + NonNegativeLengthPercentageOrAuto::Auto => None, + NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => { lp.maybe_to_used_value(None) }, }; diff --git a/components/layout/lib.rs b/components/layout/lib.rs index f8afdc79190..974ef7c803b 100644 --- a/components/layout/lib.rs +++ b/components/layout/lib.rs @@ -3,6 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #![deny(unsafe_code)] +#![feature(type_alias_enum_variants)] #[macro_use] extern crate bitflags; diff --git a/components/layout/model.rs b/components/layout/model.rs index 0650c8887a1..b5a79d8a383 100644 --- a/components/layout/model.rs +++ b/components/layout/model.rs @@ -11,8 +11,10 @@ use std::cmp::{max, min}; use std::fmt; use style::logical_geometry::{LogicalMargin, WritingMode}; use style::properties::ComputedValues; -use style::values::computed::LengthPercentageOrNone; -use style::values::computed::{LengthPercentage, LengthPercentageOrAuto}; +use style::values::computed::MaxLength; +use style::values::computed::{ + LengthPercentageOrAuto, NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto, +}; /// A collapsible margin. See CSS 2.1 § 8.3.1. #[derive(Clone, Copy, Debug)] @@ -135,8 +137,8 @@ impl MarginCollapseInfo { MarginCollapseState::AccumulatingCollapsibleTopMargin => { may_collapse_through = may_collapse_through && match fragment.style().content_block_size() { - LengthPercentageOrAuto::Auto => true, - LengthPercentageOrAuto::LengthPercentage(ref lp) => { + NonNegativeLengthPercentageOrAuto::Auto => true, + NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => { lp.is_definitely_zero() || 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. /// /// `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 { - LengthPercentageOrAuto::Auto => MaybeAuto::Auto, - LengthPercentageOrAuto::LengthPercentage(ref lp) => { - MaybeAuto::from_option(lp.maybe_to_used_value(container_size)) + NonNegativeLengthPercentageOrAuto::Auto => MaybeAuto::Auto, + NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => { + MaybeAuto::from_option(lp.0.maybe_to_used_value(container_size)) }, } } @@ -566,8 +571,8 @@ impl SizeConstraint { /// Create a `SizeConstraint` for an axis. pub fn new( container_size: Option<Au>, - min_size: LengthPercentage, - max_size: LengthPercentageOrNone, + min_size: NonNegativeLengthPercentage, + max_size: MaxLength, border: Option<Au>, ) -> SizeConstraint { let mut min_size = min_size @@ -575,10 +580,8 @@ impl SizeConstraint { .unwrap_or(Au(0)); let mut max_size = match max_size { - LengthPercentageOrNone::None => None, - LengthPercentageOrNone::LengthPercentage(ref lp) => { - lp.maybe_to_used_value(container_size) - }, + MaxLength::None => None, + MaxLength::LengthPercentage(ref lp) => lp.maybe_to_used_value(container_size), }; // Make sure max size is not smaller than min size. diff --git a/components/layout/multicol.rs b/components/layout/multicol.rs index 14ea36626f9..feb267103b0 100644 --- a/components/layout/multicol.rs +++ b/components/layout/multicol.rs @@ -19,7 +19,7 @@ use std::fmt; use std::sync::Arc; use style::logical_geometry::LogicalSize; 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::Either; @@ -155,16 +155,14 @@ impl Flow for MulticolFlow { available_block_size: { let style = &self.block_flow.fragment.style; let size = match style.content_block_size() { - LengthPercentageOrAuto::Auto => None, - LengthPercentageOrAuto::LengthPercentage(ref lp) => { + NonNegativeLengthPercentageOrAuto::Auto => None, + NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => { lp.maybe_to_used_value(None) }, }; let size = size.or_else(|| match style.max_block_size() { - LengthPercentageOrNone::None => None, - LengthPercentageOrNone::LengthPercentage(ref lp) => { - lp.maybe_to_used_value(None) - }, + MaxLength::None => None, + MaxLength::LengthPercentage(ref lp) => lp.maybe_to_used_value(None), }); size.unwrap_or_else(|| { diff --git a/components/layout/table.rs b/components/layout/table.rs index f7bf902e452..7aa8f2a89d4 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -33,7 +33,7 @@ use style::logical_geometry::LogicalSize; use style::properties::style_structs::Background; use style::properties::ComputedValues; use style::servo::restyle_damage::ServoRestyleDamage; -use style::values::computed::LengthPercentageOrAuto; +use style::values::computed::NonNegativeLengthPercentageOrAuto; use style::values::CSSFloat; #[allow(unsafe_code)] @@ -301,15 +301,15 @@ impl Flow for TableFlow { self.column_intrinsic_inline_sizes .push(ColumnIntrinsicInlineSize { minimum_length: match *specified_inline_size { - LengthPercentageOrAuto::Auto => Au(0), - LengthPercentageOrAuto::LengthPercentage(ref lp) => { + NonNegativeLengthPercentageOrAuto::Auto => Au(0), + NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => { lp.maybe_to_used_value(None).unwrap_or(Au(0)) }, }, percentage: match *specified_inline_size { - LengthPercentageOrAuto::Auto => 0.0, - LengthPercentageOrAuto::LengthPercentage(ref lp) => { - lp.as_percentage().map_or(0.0, |p| p.0) + NonNegativeLengthPercentageOrAuto::Auto => 0.0, + NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => { + lp.0.as_percentage().map_or(0.0, |p| p.0) }, }, preferred: Au(0), diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs index d72a6670576..3bcc39f0193 100644 --- a/components/layout/table_cell.rs +++ b/components/layout/table_cell.rs @@ -12,7 +12,6 @@ use crate::display_list::{ use crate::flow::{Flow, FlowClass, FlowFlags, GetBaseFlow, OpaqueFlow}; use crate::fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; use crate::layout_debug; -use crate::model::MaybeAuto; use crate::table::InternalTable; use crate::table_row::{CollapsedBorder, CollapsedBorderProvenance}; use app_units::Au; @@ -22,6 +21,7 @@ use script_layout_interface::wrapper_traits::ThreadSafeLayoutNode; use std::fmt; use style::logical_geometry::{LogicalMargin, LogicalRect, LogicalSize, WritingMode}; use style::properties::ComputedValues; +use style::values::computed::length::NonNegativeLengthPercentageOrAuto; use style::values::computed::Color; use style::values::generics::box_::VerticalAlign; use style::values::specified::BorderStyle; @@ -162,8 +162,12 @@ impl TableCellFlow { // Call after block size calculation pub fn total_block_size(&mut self) -> Au { // TODO: Percentage block-size - let specified = MaybeAuto::from_style(self.fragment().style().content_block_size(), Au(0)) - .specified_or_zero(); + let specified = self + .fragment() + .style() + .content_block_size() + .to_used_value(Au(0)) + .unwrap_or(Au(0)); 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); - let specified_inline_size = MaybeAuto::from_style( - self.block_flow.fragment.style().content_inline_size(), - Au(0), - ) - .specified_or_zero(); + let specified_inline_size = match self.block_flow.fragment.style().content_inline_size() { + NonNegativeLengthPercentageOrAuto::Auto => Au(0), + NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => lp.to_used_value(Au(0)), + }; + if self .block_flow .base diff --git a/components/layout/table_colgroup.rs b/components/layout/table_colgroup.rs index 6bb5cbe620b..1097d6dae38 100644 --- a/components/layout/table_colgroup.rs +++ b/components/layout/table_colgroup.rs @@ -14,7 +14,7 @@ use euclid::Point2D; use std::fmt; use style::logical_geometry::LogicalSize; use style::properties::ComputedValues; -use style::values::computed::LengthPercentageOrAuto; +use style::values::computed::NonNegativeLengthPercentageOrAuto; #[allow(unsafe_code)] 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 /// lieu of `ColumnInlineSize` because column groups do not establish minimum or preferred /// inline sizes.) - pub inline_sizes: Vec<LengthPercentageOrAuto>, + pub inline_sizes: Vec<NonNegativeLengthPercentageOrAuto>, } impl TableColGroupFlow { diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 22db572c166..78768f5a1ab 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -15,7 +15,6 @@ use crate::flow::{ use crate::flow_list::MutFlowListIterator; use crate::fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; use crate::layout_debug; -use crate::model::MaybeAuto; use crate::table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, VecExt}; use crate::table_cell::{CollapsedBordersForCell, TableCellFlow}; 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::logical_geometry::{LogicalSize, PhysicalSide, WritingMode}; use style::properties::ComputedValues; -use style::values::computed::{Color, LengthPercentageOrAuto}; +use style::values::computed::{Color, NonNegativeLengthPercentageOrAuto}; #[allow(unsafe_code)] unsafe impl crate::flow::HasBaseFlow for TableRowFlow {} @@ -208,16 +207,15 @@ impl TableRowFlow { &mut max_block_size, ); - let mut block_size = max_block_size; // TODO: Percentage block-size - block_size = match MaybeAuto::from_style( - self.block_flow.fragment.style().content_block_size(), - Au(0), - ) { - MaybeAuto::Auto => block_size, - MaybeAuto::Specified(value) => max(value, block_size), - }; - block_size + let block_size = self + .block_flow + .fragment + .style() + .content_block_size() + .to_used_value(Au(0)) + .unwrap_or(max_block_size); + max(block_size, max_block_size) } 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_column_inline_size = ColumnIntrinsicInlineSize { minimum_length: match child_specified_inline_size { - LengthPercentageOrAuto::Auto => None, - LengthPercentageOrAuto::LengthPercentage(ref lp) => { - lp.maybe_to_used_value(None) + NonNegativeLengthPercentageOrAuto::Auto => None, + NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => { + lp.0.maybe_to_used_value(None) }, } .unwrap_or(child_base.intrinsic_inline_sizes.minimum_inline_size), percentage: match child_specified_inline_size { - LengthPercentageOrAuto::Auto => 0.0, - LengthPercentageOrAuto::LengthPercentage(ref lp) => { - lp.as_percentage().map_or(0.0, |p| p.0) + NonNegativeLengthPercentageOrAuto::Auto => 0.0, + NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => { + lp.0.as_percentage().map_or(0.0, |p| p.0) }, }, preferred: child_base.intrinsic_inline_sizes.preferred_inline_size, constrained: match child_specified_inline_size { - LengthPercentageOrAuto::Auto => false, - LengthPercentageOrAuto::LengthPercentage(ref lp) => { - lp.maybe_to_used_value(None).is_some() + NonNegativeLengthPercentageOrAuto::Auto => false, + NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => { + lp.0.maybe_to_used_value(None).is_some() }, }, }; diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs index 9e8f137e70a..b63da7d56e5 100644 --- a/components/layout/table_wrapper.rs +++ b/components/layout/table_wrapper.rs @@ -33,7 +33,7 @@ use style::computed_values::{position, table_layout}; use style::context::SharedStyleContext; use style::logical_geometry::{LogicalRect, LogicalSize}; use style::properties::ComputedValues; -use style::values::computed::LengthPercentageOrAuto; +use style::values::computed::NonNegativeLengthPercentageOrAuto; use style::values::CSSFloat; #[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 // just use the shrink-to-fit inline size. let available_inline_size = match self.block_flow.fragment.style().content_inline_size() { - LengthPercentageOrAuto::Auto => { + NonNegativeLengthPercentageOrAuto::Auto => { self.block_flow .get_shrink_to_fit_inline_size(available_inline_size) - table_border_padding @@ -840,12 +840,8 @@ fn initial_computed_inline_size( preferred_width_of_all_columns: Au, table_border_padding: Au, ) -> MaybeAuto { - let inline_size_from_style = MaybeAuto::from_style( - block.fragment.style.content_inline_size(), - containing_block_inline_size, - ); - match inline_size_from_style { - MaybeAuto::Auto => { + match block.fragment.style.content_inline_size() { + NonNegativeLengthPercentageOrAuto::Auto => { if preferred_width_of_all_columns + table_border_padding <= containing_block_inline_size { MaybeAuto::Specified(preferred_width_of_all_columns + table_border_padding) @@ -855,10 +851,13 @@ fn initial_computed_inline_size( MaybeAuto::Auto } }, - MaybeAuto::Specified(inline_size_from_style) => MaybeAuto::Specified(max( - inline_size_from_style - table_border_padding, - minimum_width_of_all_columns, - )), + NonNegativeLengthPercentageOrAuto::LengthPercentage(ref lp) => { + let used = lp.to_used_value(containing_block_inline_size); + MaybeAuto::Specified(max( + used - table_border_padding, + minimum_width_of_all_columns, + )) + }, } } diff --git a/components/script/devtools.rs b/components/script/devtools.rs index 58b0a7d20a7..7a24d959980 100644 --- a/components/script/devtools.rs +++ b/components/script/devtools.rs @@ -29,7 +29,6 @@ use js::rust::wrappers::ObjectClassName; use msg::constellation_msg::PipelineId; use std::ffi::CStr; use std::str; -use style::properties::longhands::{margin_bottom, margin_left, margin_right, margin_top}; use uuid::Uuid; #[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 margin = style.get_margin(); AutoMargins { - top: margin.margin_top == margin_top::computed_value::T::Auto, - right: margin.margin_right == margin_right::computed_value::T::Auto, - bottom: margin.margin_bottom == margin_bottom::computed_value::T::Auto, - left: margin.margin_left == margin_left::computed_value::T::Auto, + top: margin.margin_top.is_auto(), + right: margin.margin_right.is_auto(), + bottom: margin.margin_bottom.is_auto(), + left: margin.margin_left.is_auto(), } } diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 234a10f9448..dbcab42f11f 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -718,9 +718,11 @@ impl LayoutElementHelpers for LayoutDom<Element> { specified::NoCalcLength::ServoCharacterWidth(specified::CharacterWidth(size)); hints.push(from_declaration( shared_lock, - PropertyDeclaration::Width(specified::LengthPercentageOrAuto::LengthPercentage( - specified::LengthPercentage::Length(value), - )), + PropertyDeclaration::Width( + specified::NonNegativeLengthPercentageOrAuto::LengthPercentage(NonNegative( + specified::LengthPercentage::Length(value), + )), + ), )); } @@ -745,20 +747,22 @@ impl LayoutElementHelpers for LayoutDom<Element> { match width { LengthOrPercentageOrAuto::Auto => {}, LengthOrPercentageOrAuto::Percentage(percentage) => { - let width_value = specified::LengthPercentageOrAuto::LengthPercentage( - specified::LengthPercentage::Percentage(computed::Percentage(percentage)), - ); + let width_value = + specified::NonNegativeLengthPercentageOrAuto::LengthPercentage(NonNegative( + specified::LengthPercentage::Percentage(computed::Percentage(percentage)), + )); hints.push(from_declaration( shared_lock, PropertyDeclaration::Width(width_value), )); }, LengthOrPercentageOrAuto::Length(length) => { - let width_value = specified::LengthPercentageOrAuto::LengthPercentage( - specified::LengthPercentage::Length(specified::NoCalcLength::Absolute( - specified::AbsoluteLength::Px(length.to_f32_px()), - )), - ); + let width_value = + specified::NonNegativeLengthPercentageOrAuto::LengthPercentage(NonNegative( + specified::LengthPercentage::Length(specified::NoCalcLength::Absolute( + specified::AbsoluteLength::Px(length.to_f32_px()), + )), + )); hints.push(from_declaration( shared_lock, PropertyDeclaration::Width(width_value), @@ -779,20 +783,22 @@ impl LayoutElementHelpers for LayoutDom<Element> { match height { LengthOrPercentageOrAuto::Auto => {}, LengthOrPercentageOrAuto::Percentage(percentage) => { - let height_value = specified::LengthPercentageOrAuto::LengthPercentage( - specified::LengthPercentage::Percentage(computed::Percentage(percentage)), - ); + let height_value = + specified::NonNegativeLengthPercentageOrAuto::LengthPercentage(NonNegative( + specified::LengthPercentage::Percentage(computed::Percentage(percentage)), + )); hints.push(from_declaration( shared_lock, PropertyDeclaration::Height(height_value), )); }, LengthOrPercentageOrAuto::Length(length) => { - let height_value = specified::LengthPercentageOrAuto::LengthPercentage( - specified::LengthPercentage::Length(specified::NoCalcLength::Absolute( - specified::AbsoluteLength::Px(length.to_f32_px()), - )), - ); + let height_value = + specified::NonNegativeLengthPercentageOrAuto::LengthPercentage(NonNegative( + specified::LengthPercentage::Length(specified::NoCalcLength::Absolute( + specified::AbsoluteLength::Px(length.to_f32_px()), + )), + )); hints.push(from_declaration( shared_lock, PropertyDeclaration::Height(height_value), @@ -819,9 +825,11 @@ impl LayoutElementHelpers for LayoutDom<Element> { specified::NoCalcLength::ServoCharacterWidth(specified::CharacterWidth(cols)); hints.push(from_declaration( shared_lock, - PropertyDeclaration::Width(specified::LengthPercentageOrAuto::LengthPercentage( - specified::LengthPercentage::Length(value), - )), + PropertyDeclaration::Width( + specified::NonNegativeLengthPercentageOrAuto::LengthPercentage(NonNegative( + specified::LengthPercentage::Length(value), + )), + ), )); } @@ -843,9 +851,11 @@ impl LayoutElementHelpers for LayoutDom<Element> { )); hints.push(from_declaration( shared_lock, - PropertyDeclaration::Height(specified::LengthPercentageOrAuto::LengthPercentage( - specified::LengthPercentage::Length(value), - )), + PropertyDeclaration::Height( + specified::NonNegativeLengthPercentageOrAuto::LengthPercentage(NonNegative( + specified::LengthPercentage::Length(value), + )), + ), )); } diff --git a/components/script/lib.rs b/components/script/lib.rs index ce427aa3a56..1332e604fdb 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -8,6 +8,7 @@ #![feature(drain_filter)] #![feature(plugin)] #![feature(try_from)] +#![feature(type_alias_enum_variants)] #![deny(unsafe_code)] #![allow(non_snake_case)] #![doc = "The script crate contains all matters DOM."] diff --git a/components/style/cbindgen.toml b/components/style/cbindgen.toml index 25004b2def6..4c0b631d31d 100644 --- a/components/style/cbindgen.toml +++ b/components/style/cbindgen.toml @@ -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 * 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; namespace mozilla { + class WritingMode; + enum LogicalSide : uint8_t; namespace css { struct URLValue; } + // Work-around weird cbindgen renaming. typedef css::URLValue StyleURLValue; typedef nsAtom StylensAtom; @@ -27,7 +33,7 @@ namespaces = ["mozilla"] [parse] parse_deps = true -include = ["cssparser"] +include = ["cssparser", "style_traits"] [struct] derive_eq = true @@ -69,5 +75,46 @@ include = [ "Resize", "Overflow", "LengthPercentage", + "NonNegativeLengthPercentage", + "LengthPercentageOrAuto", + "Rect", + "IntersectionObserverRootMargin", ] 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; +""" diff --git a/components/style/gecko/conversions.rs b/components/style/gecko/conversions.rs index 0f6ac89c9f2..ccaa16c844c 100644 --- a/components/style/gecko/conversions.rs +++ b/components/style/gecko/conversions.rs @@ -27,6 +27,7 @@ use crate::values::computed::{LengthPercentageOrAuto, NonNegativeLengthPercentag use crate::values::generics::box_::VerticalAlign; use crate::values::generics::grid::{TrackListValue, TrackSize}; use crate::values::generics::image::{CompatMode, GradientItem, Image as GenericImage}; +use crate::values::generics::length::LengthPercentageOrAuto as GenericLengthPercentageOrAuto; use crate::values::generics::rect::Rect; use crate::values::generics::NonNegative; use app_units::Au; @@ -62,19 +63,19 @@ impl From<nsStyleCoord_CalcValue> for LengthPercentage { } } -impl LengthPercentageOrAuto { +impl NonNegativeLengthPercentageOrAuto { /// Convert this value in an appropriate `nsStyleCoord::CalcValue`. pub fn to_calc_value(&self) -> Option<nsStyleCoord_CalcValue> { match *self { - LengthPercentageOrAuto::LengthPercentage(len) => Some(From::from(len)), - LengthPercentageOrAuto::Auto => None, + GenericLengthPercentageOrAuto::LengthPercentage(ref len) => Some(From::from(len.0)), + GenericLengthPercentageOrAuto::Auto => None, } } } impl From<nsStyleCoord_CalcValue> for 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. impl From<nsStyleCoord_CalcValue> for NonNegativeLengthPercentageOrAuto { fn from(other: nsStyleCoord_CalcValue) -> Self { - NonNegative(LengthPercentageOrAuto::LengthPercentage( + GenericLengthPercentageOrAuto::LengthPercentage(NonNegative( LengthPercentage::with_clamping_mode( Au(other.mLength).into(), if other.mHasPercent { diff --git a/components/style/gecko/values.rs b/components/style/gecko/values.rs index 42177bf0858..ac3495a7504 100644 --- a/components/style/gecko/values.rs +++ b/components/style/gecko/values.rs @@ -14,15 +14,15 @@ use crate::media_queries::Device; use crate::values::computed::basic_shape::ShapeRadius as ComputedShapeRadius; use crate::values::computed::FlexBasis as ComputedFlexBasis; use crate::values::computed::{Angle, ExtremumLength, Length, LengthPercentage}; -use crate::values::computed::{LengthPercentageOrAuto, Percentage}; -use crate::values::computed::{LengthPercentageOrNone, Number, NumberOrPercentage}; 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::box_::Perspective; use crate::values::generics::flex::FlexBasis; use crate::values::generics::gecko::ScrollSnapPoint; use crate::values::generics::grid::{TrackBreadth, TrackKeyword}; -use crate::values::generics::length::{MaxLength, MozLength}; +use crate::values::generics::length::{LengthPercentageOrAuto, MaxLength, MozLength}; use crate::values::generics::{CounterStyleOrNone, NonNegative}; use crate::values::{Auto, Either, None_, Normal}; 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) { match *self { 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> { fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { match *self { @@ -367,34 +353,40 @@ impl GeckoStyleCoordConvertible for ExtremumLength { impl GeckoStyleCoordConvertible for ComputedMozLength { fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { 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), } } fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> { - LengthPercentageOrAuto::from_gecko_style_coord(coord) - .map(MozLength::LengthPercentageOrAuto) - .or_else(|| { - ExtremumLength::from_gecko_style_coord(coord).map(MozLength::ExtremumLength) - }) + if let CoordDataValue::Auto = coord.as_value() { + return Some(MozLength::Auto); + } + if let Some(lp) = NonNegativeLengthPercentage::from_gecko_style_coord(coord) { + return Some(MozLength::LengthPercentage(lp)); + } + ExtremumLength::from_gecko_style_coord(coord).map(MozLength::ExtremumLength) } } impl GeckoStyleCoordConvertible for ComputedMaxLength { fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { 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), } } fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> { - LengthPercentageOrNone::from_gecko_style_coord(coord) - .map(MaxLength::LengthPercentageOrNone) - .or_else(|| { - ExtremumLength::from_gecko_style_coord(coord).map(MaxLength::ExtremumLength) - }) + if let CoordDataValue::None = coord.as_value() { + return Some(MaxLength::None); + } + if let Some(lp) = NonNegativeLengthPercentage::from_gecko_style_coord(coord) { + return Some(MaxLength::LengthPercentage(lp)); + } + ExtremumLength::from_gecko_style_coord(coord).map(MaxLength::ExtremumLength) } } diff --git a/components/style/properties/cascade.rs b/components/style/properties/cascade.rs index 7fdbb7177e9..d881524deb5 100644 --- a/components/style/properties/cascade.rs +++ b/components/style/properties/cascade.rs @@ -629,6 +629,10 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> { #[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() { bg.fill_arrays(); } diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 9bb95ba9dfe..297357446a2 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -80,7 +80,6 @@ pub struct ComputedValues(crate::gecko_bindings::structs::mozilla::ComputedStyle impl ComputedValues { pub fn new( - device: &Device, pseudo: Option<<&PseudoElement>, custom_properties: Option<Arc<CustomPropertiesMap>>, writing_mode: WritingMode, @@ -100,10 +99,7 @@ impl ComputedValues { % for style_struct in data.style_structs: ${style_struct.ident}, % endfor - ).to_outer( - device.pres_context(), - pseudo.map(|p| p.pseudo_info()) - ) + ).to_outer(pseudo) } pub fn default_values(pres_context: RawGeckoPresContextBorrowed) -> Arc<Self> { @@ -116,7 +112,7 @@ impl ComputedValues { % for style_struct in data.style_structs: style_structs::${style_struct.name}::default(pres_context), % endfor - ).to_outer(pres_context, None) + ).to_outer(None) } pub fn pseudo(&self) -> Option<PseudoElement> { @@ -190,24 +186,23 @@ impl Clone for ComputedValuesInner { } } -type PseudoInfo = (*mut structs::nsAtom, structs::CSSPseudoElementType); - impl ComputedValuesInner { - pub fn new(custom_properties: Option<Arc<CustomPropertiesMap>>, - writing_mode: WritingMode, - flags: ComputedValueFlags, - rules: Option<StrongRuleNode>, - visited_style: Option<Arc<ComputedValues>>, - % for style_struct in data.style_structs: - ${style_struct.ident}: Arc<style_structs::${style_struct.name}>, - % endfor + pub fn new( + custom_properties: Option<Arc<CustomPropertiesMap>>, + writing_mode: WritingMode, + flags: ComputedValueFlags, + rules: Option<StrongRuleNode>, + visited_style: Option<Arc<ComputedValues>>, + % for style_struct in data.style_structs: + ${style_struct.ident}: Arc<style_structs::${style_struct.name}>, + % endfor ) -> Self { - ComputedValuesInner { - custom_properties: custom_properties, - writing_mode: writing_mode, - rules: rules, - visited_style: visited_style.map(|x| Arc::into_raw_offset(x)), - flags: flags, + Self { + custom_properties, + writing_mode, + rules, + visited_style: visited_style.map(Arc::into_raw_offset), + flags, % for style_struct in data.style_structs: ${style_struct.gecko_name}: Arc::into_raw_offset(${style_struct.ident}), % endfor @@ -216,29 +211,16 @@ impl ComputedValuesInner { fn to_outer( self, - pres_context: RawGeckoPresContextBorrowed, - info: Option<PseudoInfo> + pseudo: Option<<&PseudoElement>, ) -> Arc<ComputedValues> { - let (tag, ty) = if let Some(info) = info { - info - } else { - (ptr::null_mut(), structs::CSSPseudoElementType::NotPseudo) + let (pseudo_tag, pseudo_ty) = match pseudo { + Some(p) => p.pseudo_info(), + None => (ptr::null_mut(), structs::CSSPseudoElementType::NotPseudo), }; - - 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 = unsafe { let arc: Arc<ComputedValues> = Arc::new(uninitialized()); bindings::Gecko_ComputedStyle_Init( &arc.0 as *const _ as *mut _, - pres_context, &self, pseudo_ty, pseudo_tag @@ -790,11 +772,12 @@ def set_gecko_property(ffi_name, expr): <%def name="impl_split_style_coord(ident, gecko_ffi_name, index)"> #[allow(non_snake_case)] 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)] 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)] pub fn reset_${ident}(&mut self, other: &Self) { @@ -803,9 +786,7 @@ def set_gecko_property(ffi_name, expr): #[allow(non_snake_case)] pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { - use crate::properties::longhands::${ident}::computed_value::T; - T::from_gecko_style_coord(&self.gecko.${gecko_ffi_name}.data_at(${index})) - .expect("clone for ${ident} failed") + self.gecko.${gecko_ffi_name}.${index} } </%def> @@ -1407,14 +1388,13 @@ impl Clone for ${style_struct.gecko_struct_name} { "FlexBasis": impl_style_coord, "Length": impl_absolute_length, "LengthOrNormal": impl_style_coord, - "LengthPercentage": impl_style_coord, + "LengthPercentage": impl_simple, "LengthPercentageOrAuto": impl_style_coord, - "LengthPercentageOrNone": impl_style_coord, "MaxLength": impl_style_coord, "MozLength": impl_style_coord, "MozScriptMinSize": impl_absolute_length, "MozScriptSizeMultiplier": impl_simple, - "NonNegativeLengthPercentage": impl_style_coord, + "NonNegativeLengthPercentage": impl_simple, "NonNegativeNumber": impl_simple, "Number": impl_simple, "Opacity": impl_simple, @@ -3024,6 +3004,11 @@ fn static_assert() { translate scale""" %> <%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] pub fn set_display(&mut self, v: longhands::display::computed_value::T) { self.gecko.mDisplay = v; self.gecko.mOriginalDisplay = v; @@ -3845,11 +3830,11 @@ fn static_assert() { BackgroundSize::Explicit { width: explicit_width, height: explicit_height } => { let mut w_type = nsStyleImageLayers_Size_DimensionType::eAuto; let mut h_type = nsStyleImageLayers_Size_DimensionType::eAuto; - if let Some(w) = explicit_width.0.to_calc_value() { + if let Some(w) = explicit_width.to_calc_value() { width = w; 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; h_type = nsStyleImageLayers_Size_DimensionType::eLengthPercentage; } diff --git a/components/style/properties/longhands/box.mako.rs b/components/style/properties/longhands/box.mako.rs index f956dd2f606..223db1d6e7c 100644 --- a/components/style/properties/longhands/box.mako.rs +++ b/components/style/properties/longhands/box.mako.rs @@ -34,7 +34,7 @@ ${helpers.single_keyword( 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 ${helpers.single_keyword( "-servo-top-layer", @@ -602,6 +602,8 @@ ${helpers.predefined_type( products="gecko", animation_value_type="none", 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)", )} diff --git a/components/style/properties/longhands/position.mako.rs b/components/style/properties/longhands/position.mako.rs index cc5515dbac7..2a0f86d056a 100644 --- a/components/style/properties/longhands/position.mako.rs +++ b/components/style/properties/longhands/position.mako.rs @@ -13,7 +13,7 @@ ${helpers.predefined_type( side, "LengthPercentageOrAuto", - "computed::LengthPercentageOrAuto::Auto", + "computed::LengthPercentageOrAuto::auto()", spec="https://www.w3.org/TR/CSS2/visuren.html#propdef-%s" % side, flags="GETCS_NEEDS_LAYOUT_FLUSH", animation_value_type="ComputedValue", @@ -27,7 +27,7 @@ ${helpers.predefined_type( "inset-%s" % side, "LengthPercentageOrAuto", - "computed::LengthPercentageOrAuto::Auto", + "computed::LengthPercentageOrAuto::auto()", spec="https://drafts.csswg.org/css-logical-props/#propdef-inset-%s" % side, flags="GETCS_NEEDS_LAYOUT_FLUSH", alias="offset-%s:layout.css.offset-logical-properties.enabled" % side, @@ -270,24 +270,12 @@ ${helpers.predefined_type( animation_value_type="MozLength", servo_restyle_damage="reflow", )} - ${helpers.predefined_type( - "max-%s" % size, - "MaxLength", - "computed::MaxLength::none()", - logical=logical, - logical_group="max-size", - allow_quirks=not logical, - spec=spec % size, - animation_value_type="MaxLength", - servo_restyle_damage="reflow", - )} % else: // servo versions (no keyword support) ${helpers.predefined_type( size, - "LengthPercentageOrAuto", - "computed::LengthPercentageOrAuto::Auto", - "parse_non_negative", + "NonNegativeLengthPercentageOrAuto", + "computed::NonNegativeLengthPercentageOrAuto::auto()", spec=spec % size, logical_group="size", allow_quirks=not logical, @@ -296,9 +284,8 @@ ${helpers.predefined_type( )} ${helpers.predefined_type( "min-%s" % size, - "LengthPercentage", - "computed::LengthPercentage::zero()", - "parse_non_negative", + "NonNegativeLengthPercentage", + "computed::NonNegativeLengthPercentage::zero()", spec=spec % ("min-%s" % size), logical_group="min-size", animation_value_type="ComputedValue", @@ -306,19 +293,18 @@ ${helpers.predefined_type( 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 + ${helpers.predefined_type( + "max-%s" % size, + "MaxLength", + "computed::MaxLength::none()", + logical=logical, + logical_group="max-size", + allow_quirks=not logical, + spec=spec % size, + animation_value_type="MaxLength", + servo_restyle_damage="reflow", + )} % endfor ${helpers.single_keyword( diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 6a263c8ca35..62d27922ccb 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -2890,7 +2890,6 @@ impl ComputedValues { impl ComputedValues { /// Create a new refcounted `ComputedValues` pub fn new( - _: &Device, _: Option<<&PseudoElement>, custom_properties: Option<Arc<crate::custom_properties::CustomPropertiesMap>>, writing_mode: WritingMode, @@ -3017,7 +3016,7 @@ impl ComputedValuesInner { /// Get the logical computed inline size. #[inline] - pub fn content_inline_size(&self) -> computed::LengthPercentageOrAuto { + pub fn content_inline_size(&self) -> computed::NonNegativeLengthPercentageOrAuto { let position_style = self.get_position(); if self.writing_mode.is_vertical() { position_style.height @@ -3028,35 +3027,35 @@ impl ComputedValuesInner { /// Get the logical computed block size. #[inline] - pub fn content_block_size(&self) -> computed::LengthPercentageOrAuto { + pub fn content_block_size(&self) -> computed::NonNegativeLengthPercentageOrAuto { let position_style = self.get_position(); if self.writing_mode.is_vertical() { position_style.width } else { position_style.height } } /// Get the logical computed min inline size. #[inline] - pub fn min_inline_size(&self) -> computed::LengthPercentage { + pub fn min_inline_size(&self) -> computed::NonNegativeLengthPercentage { let position_style = self.get_position(); if self.writing_mode.is_vertical() { position_style.min_height } else { position_style.min_width } } /// Get the logical computed min block size. #[inline] - pub fn min_block_size(&self) -> computed::LengthPercentage { + pub fn min_block_size(&self) -> computed::NonNegativeLengthPercentage { let position_style = self.get_position(); if self.writing_mode.is_vertical() { position_style.min_width } else { position_style.min_height } } /// Get the logical computed max inline size. #[inline] - pub fn max_inline_size(&self) -> computed::LengthPercentageOrNone { + pub fn max_inline_size(&self) -> computed::MaxLength { let position_style = self.get_position(); if self.writing_mode.is_vertical() { position_style.max_height } else { position_style.max_width } } /// Get the logical computed max block size. #[inline] - pub fn max_block_size(&self) -> computed::LengthPercentageOrNone { + pub fn max_block_size(&self) -> computed::MaxLength { let position_style = self.get_position(); 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. pub fn build(self) -> Arc<ComputedValues> { ComputedValues::new( - self.device, self.pseudo, self.custom_properties, self.writing_mode, diff --git a/components/style/stylesheets/viewport_rule.rs b/components/style/stylesheets/viewport_rule.rs index 862399e065c..8325216519d 100644 --- a/components/style/stylesheets/viewport_rule.rs +++ b/components/style/stylesheets/viewport_rule.rs @@ -11,16 +11,17 @@ use crate::context::QuirksMode; use crate::error_reporting::ContextualParseError; use crate::font_metrics::get_metrics_provider_for_product; use crate::media_queries::Device; -use crate::parser::ParserContext; +use crate::parser::{Parse, ParserContext}; use crate::properties::StyleBuilder; use crate::rule_cache::RuleCacheConditions; use crate::shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard}; use crate::str::CssStringWriter; use crate::stylesheets::{Origin, StylesheetInDocument}; use crate::values::computed::{Context, ToComputedValue}; -use crate::values::specified::{ - self, LengthPercentageOrAuto, NoCalcLength, ViewportPercentageLength, -}; +use crate::values::generics::length::LengthPercentageOrAuto; +use crate::values::generics::NonNegative; +use crate::values::specified::{self, NoCalcLength}; +use crate::values::specified::{NonNegativeLengthPercentageOrAuto, ViewportPercentageLength}; use app_units::Au; use cssparser::CowRcStr; use cssparser::{parse_important, AtRuleParser, DeclarationListParser, DeclarationParser, Parser}; @@ -151,7 +152,7 @@ trait FromMeta: Sized { #[cfg_attr(feature = "servo", derive(MallocSizeOf))] #[derive(Clone, Debug, PartialEq, ToCss)] pub enum ViewportLength { - Specified(LengthPercentageOrAuto), + Specified(NonNegativeLengthPercentageOrAuto), ExtendToZoom, } @@ -159,9 +160,9 @@ impl FromMeta for ViewportLength { fn from_meta(value: &str) -> Option<ViewportLength> { macro_rules! specified { ($value:expr) => { - ViewportLength::Specified(LengthPercentageOrAuto::LengthPercentage( + ViewportLength::Specified(LengthPercentageOrAuto::LengthPercentage(NonNegative( specified::LengthPercentage::Length($value), - )) + ))) }; } @@ -188,7 +189,7 @@ impl ViewportLength { ) -> Result<Self, ParseError<'i>> { // we explicitly do not accept 'extend-to-zoom', since it is a UA // internal value for <META> viewport translation - LengthPercentageOrAuto::parse_non_negative(context, input).map(ViewportLength::Specified) + NonNegativeLengthPercentageOrAuto::parse(context, input).map(ViewportLength::Specified) } } diff --git a/components/style/values/animated/length.rs b/components/style/values/animated/length.rs index dd678f5c395..73957618cea 100644 --- a/components/style/values/animated/length.rs +++ b/components/style/values/animated/length.rs @@ -4,10 +4,8 @@ //! 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::MaxLength as ComputedMaxLength; -use crate::values::computed::MozLength as ComputedMozLength; use crate::values::computed::Percentage; /// <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, - } - } -} diff --git a/components/style/values/computed/background.rs b/components/style/values/computed/background.rs index 08f10c9c1ec..dc23915a74b 100644 --- a/components/style/values/computed/background.rs +++ b/components/style/values/computed/background.rs @@ -4,20 +4,21 @@ //! 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::length::LengthPercentageOrAuto; pub use crate::values::specified::background::BackgroundRepeat; /// A computed value for the `background-size` property. -pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentageOrAuto>; +pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentage>; impl BackgroundSize { /// Returns `auto auto`. pub fn auto() -> Self { GenericBackgroundSize::Explicit { - width: NonNegativeLengthPercentageOrAuto::auto(), - height: NonNegativeLengthPercentageOrAuto::auto(), + width: LengthPercentageOrAuto::auto(), + height: LengthPercentageOrAuto::auto(), } } } diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index 1fd42301e3b..313b4151d2b 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -7,13 +7,15 @@ use super::{Context, Number, Percentage, ToComputedValue}; use crate::values::animated::ToAnimatedValue; use crate::values::distance::{ComputeSquaredDistance, SquaredDistance}; -use crate::values::generics::length::MaxLength as GenericMaxLength; -use crate::values::generics::length::MozLength as GenericMozLength; +use crate::values::generics::length as generics; +use crate::values::generics::length::{ + MaxLength as GenericMaxLength, MozLength as GenericMozLength, +}; use crate::values::generics::transform::IsZeroLength; use crate::values::generics::NonNegative; use crate::values::specified::length::ViewportPercentageLength; 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 ordered_float::NotNan; use std::fmt::{self, Write}; @@ -73,11 +75,12 @@ impl ToComputedValue for specified::Length { /// https://drafts.csswg.org/css-values-4/#typedef-length-percentage #[allow(missing_docs)] #[derive(Clone, Copy, Debug, MallocSizeOf, ToAnimatedZero)] +#[repr(C)] pub struct LengthPercentage { - #[animation(constant)] - pub clamping_mode: AllowedNumericType, length: Length, percentage: Percentage, + #[animation(constant)] + pub clamping_mode: AllowedNumericType, /// Whether we specified a percentage or not. #[animation(constant)] pub has_percentage: bool, @@ -451,150 +454,61 @@ impl IsZeroLength for LengthPercentage { } } -#[allow(missing_docs)] -#[css(derive_debug)] -#[derive( - Animate, Clone, ComputeSquaredDistance, Copy, MallocSizeOf, PartialEq, ToAnimatedZero, ToCss, -)] -pub enum LengthPercentageOrAuto { - LengthPercentage(LengthPercentage), - Auto, -} - -impl LengthPercentageOrAuto { - /// Returns the `0` value. - #[inline] - pub fn zero() -> Self { - LengthPercentageOrAuto::LengthPercentage(LengthPercentage::zero()) - } -} - -/// A wrapper of LengthPercentageOrAuto, whose value must be >= 0. -pub type NonNegativeLengthPercentageOrAuto = NonNegative<LengthPercentageOrAuto>; +/// Some boilerplate to share between negative and non-negative +/// length-percentage or auto. +macro_rules! computed_length_percentage_or_auto { + ($inner:ty) => { + /// Returns the `0` value. + #[inline] + pub fn zero() -> Self { + generics::LengthPercentageOrAuto::LengthPercentage(<$inner>::zero()) + } -impl IsAuto for NonNegativeLengthPercentageOrAuto { - #[inline] - fn is_auto(&self) -> bool { - *self == Self::auto() - } -} + /// Returns the used value. + #[inline] + pub fn to_used_value(&self, percentage_basis: Au) -> Option<Au> { + 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) + /// Returns true if the computed value is absolute 0 or 0%. + #[inline] + pub fn is_definitely_zero(&self) -> bool { + use values::generics::length::LengthPercentageOrAuto::*; + match *self { + LengthPercentage(ref l) => l.is_definitely_zero(), + Auto => false, + } + } } } -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()) - } -} +/// A computed type for `<length-percentage> | auto`. +pub type LengthPercentageOrAuto = generics::GenericLengthPercentageOrAuto<LengthPercentage>; impl LengthPercentageOrAuto { - /// Returns true if the computed value is absolute 0 or 0%. - #[inline] - pub fn is_definitely_zero(&self) -> bool { - use self::LengthPercentageOrAuto::*; - match *self { - LengthPercentage(ref l) => l.is_definitely_zero(), - Auto => false, - } - } - /// Clamps the value to a non-negative value. pub fn clamp_to_non_negative(self) -> Self { - use self::LengthPercentageOrAuto::*; + use values::generics::length::LengthPercentageOrAuto::*; match self { LengthPercentage(l) => LengthPercentage(l.clamp_to_non_negative()), Auto => Auto, } } -} - -impl ToComputedValue for specified::LengthPercentageOrAuto { - type ComputedValue = LengthPercentageOrAuto; - - #[inline] - fn to_computed_value(&self, context: &Context) -> LengthPercentageOrAuto { - 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, + computed_length_percentage_or_auto!(LengthPercentage); } -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, - } - } +/// A wrapper of LengthPercentageOrAuto, whose value must be >= 0. +pub type NonNegativeLengthPercentageOrAuto = + generics::LengthPercentageOrAuto<NonNegativeLengthPercentage>; - #[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), - ) - }, - } - } +impl NonNegativeLengthPercentageOrAuto { + computed_length_percentage_or_auto!(NonNegativeLengthPercentage); } /// 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 // Animated and co for Spacing<>. Get rid of this, probably? impl From<Au> for LengthPercentage { @@ -648,7 +555,7 @@ impl NonNegativeLengthPercentage { /// Get zero value. #[inline] pub fn zero() -> Self { - NonNegative::<LengthPercentage>(LengthPercentage::zero()) + NonNegative(LengthPercentage::zero()) } /// Returns true if the computed value is absolute 0 or 0%. @@ -660,7 +567,26 @@ impl NonNegativeLengthPercentage { /// Returns the used value. #[inline] 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, ToAnimatedZero, )] +#[repr(C)] pub struct CSSPixelLength(CSSFloat); impl CSSPixelLength { @@ -878,6 +805,8 @@ pub type NonNegativeLengthPercentageOrNormal = Either<NonNegativeLengthPercentag Parse, PartialEq, SpecifiedValueInfo, + ToAnimatedValue, + ToAnimatedZero, ToComputedValue, ToCss, )] @@ -892,23 +821,7 @@ pub enum ExtremumLength { } /// A computed value for `min-width`, `min-height`, `width` or `height` property. -pub type MozLength = GenericMozLength<LengthPercentageOrAuto>; - -impl MozLength { - /// Returns the `auto` value. - #[inline] - pub fn auto() -> Self { - GenericMozLength::LengthPercentageOrAuto(LengthPercentageOrAuto::Auto) - } -} +pub type MozLength = GenericMozLength<NonNegativeLengthPercentage>; /// A computed value for `max-width` or `min-height` property. -pub type MaxLength = GenericMaxLength<LengthPercentageOrNone>; - -impl MaxLength { - /// Returns the `none` value. - #[inline] - pub fn none() -> Self { - GenericMaxLength::LengthPercentageOrNone(LengthPercentageOrNone::None) - } -} +pub type MaxLength = GenericMaxLength<NonNegativeLengthPercentage>; diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 02ccf01e25e..ab8edd2b746 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -62,7 +62,7 @@ pub use self::gecko::ScrollSnapPoint; pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, MozImageRect}; pub use self::length::{CSSPixelLength, ExtremumLength, NonNegativeLength}; pub use self::length::{Length, LengthOrNumber, LengthPercentage}; -pub use self::length::{LengthPercentageOrAuto, LengthPercentageOrNone, MaxLength, MozLength}; +pub use self::length::{LengthPercentageOrAuto, MaxLength, MozLength}; pub use self::length::{NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto}; #[cfg(feature = "gecko")] pub use self::list::ListStyleType; diff --git a/components/style/values/generics/background.rs b/components/style/values/generics/background.rs index 4a7ee4b9b95..d739329e4fc 100644 --- a/components/style/values/generics/background.rs +++ b/components/style/values/generics/background.rs @@ -4,7 +4,7 @@ //! Generic types for CSS values related to backgrounds. -use crate::values::IsAuto; +use crate::values::generics::length::LengthPercentageOrAuto; use std::fmt::{self, Write}; use style_traits::{CssWriter, ToCss}; @@ -22,13 +22,13 @@ use style_traits::{CssWriter, ToCss}; ToAnimatedZero, ToComputedValue, )] -pub enum BackgroundSize<LengthPercentageOrAuto> { +pub enum BackgroundSize<LengthPercentage> { /// `<width> <height>` Explicit { /// Explicit width. - width: LengthPercentageOrAuto, + width: LengthPercentageOrAuto<LengthPercentage>, /// Explicit height. - height: LengthPercentageOrAuto, + height: LengthPercentageOrAuto<LengthPercentage>, }, /// `cover` #[animation(error)] @@ -38,9 +38,9 @@ pub enum BackgroundSize<LengthPercentageOrAuto> { Contain, } -impl<LengthPercentageOrAuto> ToCss for BackgroundSize<LengthPercentageOrAuto> +impl<LengthPercentage> ToCss for BackgroundSize<LengthPercentage> where - LengthPercentageOrAuto: ToCss + IsAuto, + LengthPercentage: ToCss, { fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where diff --git a/components/style/values/generics/length.rs b/components/style/values/generics/length.rs index 006739462aa..61be27e4fd2 100644 --- a/components/style/values/generics/length.rs +++ b/components/style/values/generics/length.rs @@ -4,7 +4,75 @@ //! Generic types for CSS values related to length. +use crate::parser::{Parse, ParserContext}; 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. /// @@ -13,25 +81,35 @@ use crate::values::computed::ExtremumLength; /// /// Note that it only accepts non-negative values. #[allow(missing_docs)] -#[cfg_attr(feature = "servo", derive(MallocSizeOf))] #[derive( Animate, Clone, ComputeSquaredDistance, Copy, Debug, + MallocSizeOf, PartialEq, SpecifiedValueInfo, + ToAnimatedValue, ToAnimatedZero, ToComputedValue, ToCss, )] -pub enum MozLength<LengthPercentageOrAuto> { - LengthPercentageOrAuto(LengthPercentageOrAuto), +pub enum MozLength<LengthPercentage> { + LengthPercentage(LengthPercentage), + Auto, #[animation(error)] 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. #[allow(missing_docs)] #[cfg_attr(feature = "servo", derive(MallocSizeOf))] @@ -43,12 +121,23 @@ pub enum MozLength<LengthPercentageOrAuto> { Debug, PartialEq, SpecifiedValueInfo, + ToAnimatedValue, ToAnimatedZero, ToComputedValue, ToCss, )] -pub enum MaxLength<LengthPercentageOrNone> { - LengthPercentageOrNone(LengthPercentageOrNone), +pub enum MaxLength<LengthPercentage> { + LengthPercentage(LengthPercentage), + None, + #[cfg(feature = "gecko")] #[animation(error)] ExtremumLength(ExtremumLength), } + +impl<LengthPercentage> MaxLength<LengthPercentage> { + /// `none` value. + #[inline] + pub fn none() -> Self { + MaxLength::None + } +} diff --git a/components/style/values/generics/mod.rs b/components/style/values/generics/mod.rs index c18eb0e7a88..a5c8c957073 100644 --- a/components/style/values/generics/mod.rs +++ b/components/style/values/generics/mod.rs @@ -174,6 +174,7 @@ impl SpecifiedValueInfo for CounterStyleOrNone { ToComputedValue, ToCss, )] +#[repr(transparent)] pub struct NonNegative<T>(pub T); /// A wrapper of greater-than-or-equal-to-one values. diff --git a/components/style/values/generics/rect.rs b/components/style/values/generics/rect.rs index 985a9c4a320..de7237e694d 100644 --- a/components/style/values/generics/rect.rs +++ b/components/style/values/generics/rect.rs @@ -23,6 +23,7 @@ use style_traits::{CssWriter, ParseError, ToCss}; ToAnimatedValue, ToComputedValue, )] +#[repr(C)] pub struct Rect<T>(pub T, pub T, pub T, pub T); impl<T> Rect<T> { diff --git a/components/style/values/specified/background.rs b/components/style/values/specified/background.rs index 47c66feaef6..b53669abfa8 100644 --- a/components/style/values/specified/background.rs +++ b/components/style/values/specified/background.rs @@ -6,14 +6,16 @@ use crate::parser::{Parse, ParserContext}; 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 selectors::parser::SelectorParseErrorKind; use std::fmt::{self, Write}; use style_traits::{CssWriter, ParseError, ToCss}; /// A specified value for the `background-size` property. -pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentageOrAuto>; +pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentage>; impl Parse for BackgroundSize { fn parse<'i, 't>( diff --git a/components/style/values/specified/gecko.rs b/components/style/values/specified/gecko.rs index 02bd5505123..42ca5e3e2bf 100644 --- a/components/style/values/specified/gecko.rs +++ b/components/style/values/specified/gecko.rs @@ -4,21 +4,19 @@ //! 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::values::computed; use crate::values::computed::length::CSSPixelLength; +use crate::values::computed::{self, LengthPercentage}; use crate::values::generics::gecko::ScrollSnapPoint as GenericScrollSnapPoint; 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 std::fmt; use style_traits::values::SequenceWriter; use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; /// A specified type for scroll snap points. -pub type ScrollSnapPoint = GenericScrollSnapPoint<LengthPercentage>; +pub type ScrollSnapPoint = GenericScrollSnapPoint<SpecifiedLengthPercentage>; impl Parse for ScrollSnapPoint { fn parse<'i, 't>( @@ -29,62 +27,34 @@ impl Parse for ScrollSnapPoint { return Ok(GenericScrollSnapPoint::None); } input.expect_function_matching("repeat")?; - let length = - input.parse_nested_block(|i| LengthPercentage::parse_non_negative(context, i))?; + // FIXME(emilio): This won't clamp properly when animating. + let length = input + .parse_nested_block(|i| SpecifiedLengthPercentage::parse_non_negative(context, i))?; Ok(GenericScrollSnapPoint::Repeat(length)) } } -/// A component of an IntersectionObserverRootMargin. -#[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, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - let location = input.current_source_location(); - let token = input.next()?; - let value = match *token { - Token::Dimension { - value, ref unit, .. - } => { - match_ignore_ascii_case! { unit, - "px" => Ok(PixelOrPercentage::Pixel(CSSPixelLength::new(value))), - _ => Err(()), - } - }, - Token::Percentage { unit_value, .. } => Ok(PixelOrPercentage::Percentage( - computed::Percentage(unit_value), - )), - _ => Err(()), - }; - 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) - }) - } +fn parse_pixel_or_percent<'i, 't>( + _context: &ParserContext, + input: &mut Parser<'i, 't>, +) -> Result<LengthPercentage, ParseError<'i>> { + let location = input.current_source_location(); + let token = input.next()?; + let value = match *token { + Token::Dimension { + value, ref unit, .. + } => { + match_ignore_ascii_case! { unit, + "px" => Ok(LengthPercentage::new(CSSPixelLength::new(value), None)), + _ => Err(()), + } + }, + Token::Percentage { unit_value, .. } => Ok(LengthPercentage::new_percent( + computed::Percentage(unit_value), + )), + _ => Err(()), + }; + value.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } /// The value of an IntersectionObserver's rootMargin property. @@ -93,14 +63,15 @@ impl GeckoStyleCoordConvertible for PixelOrPercentage { /// calc() values are not allowed. /// /// <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 { fn parse<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, ) -> 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)) } } diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index e83abebc37c..9da17990078 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -10,12 +10,14 @@ use super::{AllowQuirks, Number, Percentage, ToComputedValue}; use crate::font_metrics::FontMetricsQueryResult; use crate::parser::{Parse, ParserContext}; use crate::values::computed::{self, CSSPixelLength, Context, ExtremumLength}; -use crate::values::generics::length::MaxLength as GenericMaxLength; -use crate::values::generics::length::MozLength as GenericMozLength; +use crate::values::generics::length as generics; +use crate::values::generics::length::{ + MaxLength as GenericMaxLength, MozLength as GenericMozLength, +}; use crate::values::generics::transform::IsZeroLength; use crate::values::generics::NonNegative; 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 cssparser::{Parser, Token}; 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 { #[inline] /// Returns a `zero` length. @@ -844,12 +856,26 @@ impl LengthPercentage { 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. + /// + /// FIXME(emilio): This should be not public and we should use + /// NonNegativeLengthPercentage instead. #[inline] pub fn parse_non_negative<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, - ) -> Result<LengthPercentage, ParseError<'i>> { + ) -> Result<Self, ParseError<'i>> { Self::parse_non_negative_quirky(context, input, AllowQuirks::No) } @@ -859,7 +885,7 @@ impl LengthPercentage { context: &ParserContext, input: &mut Parser<'i, 't>, allow_quirks: AllowQuirks, - ) -> Result<LengthPercentage, ParseError<'i>> { + ) -> Result<Self, ParseError<'i>> { Self::parse_internal( context, 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 { #[inline] fn is_zero_length(&self) -> bool { @@ -903,189 +906,64 @@ impl IsZeroLength for LengthPercentage { } } -/// Either a `<length>`, a `<percentage>`, or the `auto` keyword. -#[allow(missing_docs)] -#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] -pub enum LengthPercentageOrAuto { - LengthPercentage(LengthPercentage), - Auto, -} +/// A specified type for `<length-percentage> | auto`. +pub type LengthPercentageOrAuto = generics::LengthPercentageOrAuto<LengthPercentage>; 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. pub fn zero() -> Self { - LengthPercentageOrAuto::LengthPercentage(LengthPercentage::zero()) + generics::LengthPercentageOrAuto::LengthPercentage(LengthPercentage::zero()) } /// Returns a value representing `0%`. #[inline] 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] 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 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) + Self::parse_with(context, input, |context, input| { + LengthPercentage::parse_quirky(context, input, allow_quirks) + }) } } /// A wrapper of LengthPercentageOrAuto, whose value must be >= 0. -pub type NonNegativeLengthPercentageOrAuto = NonNegative<LengthPercentageOrAuto>; - -impl IsAuto for NonNegativeLengthPercentageOrAuto { - #[inline] - fn is_auto(&self) -> bool { - *self == Self::auto() - } -} +pub type NonNegativeLengthPercentageOrAuto = + generics::LengthPercentageOrAuto<NonNegativeLengthPercentage>; impl NonNegativeLengthPercentageOrAuto { - /// 0 - #[inline] + /// Returns a value representing a `0` length. pub fn zero() -> Self { - NonNegative(LengthPercentageOrAuto::zero()) + generics::LengthPercentageOrAuto::LengthPercentage(NonNegativeLengthPercentage::zero()) } - /// 0% + /// Returns a value representing `0%`. #[inline] pub fn zero_percent() -> Self { - NonNegative(LengthPercentageOrAuto::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, + generics::LengthPercentageOrAuto::LengthPercentage( + NonNegativeLengthPercentage::zero_percent(), ) } -} -impl Parse for LengthPercentageOrNone { + /// Parses a non-negative length-percentage, allowing the unitless length + /// quirk. #[inline] - fn parse<'i, 't>( + 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, 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 { #[inline] fn from(len: NoCalcLength) -> Self { - NonNegative::<LengthPercentage>(LengthPercentage::from(len)) + NonNegative(LengthPercentage::from(len)) } } @@ -1111,7 +989,7 @@ impl Parse for NonNegativeLengthPercentage { context: &ParserContext, input: &mut Parser<'i, 't>, ) -> 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] /// Returns a `zero` length. 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. @@ -1130,8 +1014,7 @@ impl NonNegativeLengthPercentage { input: &mut Parser<'i, 't>, allow_quirks: AllowQuirks, ) -> Result<Self, ParseError<'i>> { - LengthPercentage::parse_non_negative_quirky(context, input, allow_quirks) - .map(NonNegative::<LengthPercentage>) + LengthPercentage::parse_non_negative_quirky(context, input, allow_quirks).map(NonNegative) } } @@ -1168,7 +1051,7 @@ impl LengthOrNumber { } /// 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 { fn parse<'i, 't>( @@ -1190,26 +1073,23 @@ impl MozLength { return Ok(GenericMozLength::ExtremumLength(l)); } - let length = - LengthPercentageOrAuto::parse_non_negative_quirky(context, input, allow_quirks)?; - Ok(GenericMozLength::LengthPercentageOrAuto(length)) - } + if input.try(|i| i.expect_ident_matching("auto")).is_ok() { + return Ok(GenericMozLength::Auto); + } - /// Returns `auto`. - #[inline] - pub fn auto() -> Self { - GenericMozLength::LengthPercentageOrAuto(LengthPercentageOrAuto::auto()) + let length = NonNegativeLengthPercentage::parse_quirky(context, input, allow_quirks)?; + Ok(GenericMozLength::LengthPercentage(length)) } /// Returns `0%`. #[inline] 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. -pub type MaxLength = GenericMaxLength<LengthPercentageOrNone>; +pub type MaxLength = GenericMaxLength<NonNegativeLengthPercentage>; impl Parse for MaxLength { fn parse<'i, 't>( @@ -1227,12 +1107,18 @@ impl MaxLength { input: &mut Parser<'i, 't>, allow_quirks: AllowQuirks, ) -> Result<Self, ParseError<'i>> { - if let Ok(l) = input.try(ExtremumLength::parse) { - return Ok(GenericMaxLength::ExtremumLength(l)); + #[cfg(feature = "gecko")] + { + if let Ok(l) = input.try(ExtremumLength::parse) { + return Ok(GenericMaxLength::ExtremumLength(l)); + } + } + + if input.try(|i| i.expect_ident_matching("none")).is_ok() { + return Ok(GenericMaxLength::None); } - let length = - LengthPercentageOrNone::parse_non_negative_quirky(context, input, allow_quirks)?; - Ok(GenericMaxLength::LengthPercentageOrNone(length)) + let length = NonNegativeLengthPercentage::parse_quirky(context, input, allow_quirks)?; + Ok(GenericMaxLength::LengthPercentage(length)) } } diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 2cb267045ac..b37d2554c34 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -59,7 +59,7 @@ pub use self::image::{GradientItem, GradientKind, Image, ImageLayer, MozImageRec pub use self::length::{AbsoluteLength, CalcLengthPercentage, CharacterWidth}; pub use self::length::{FontRelativeLength, Length, LengthOrNumber}; 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::{NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto}; #[cfg(feature = "gecko")] diff --git a/resources/user-agent.css b/resources/user-agent.css index fbbc7bef3ea..06410f74b81 100644 --- a/resources/user-agent.css +++ b/resources/user-agent.css @@ -303,7 +303,7 @@ textarea { white-space: pre-wrap; } /* intentionally not !important */ 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 */ -servo-top-layer: top; } diff --git a/tests/unit/style/viewport.rs b/tests/unit/style/viewport.rs index 89f708643b9..b4043038b83 100644 --- a/tests/unit/style/viewport.rs +++ b/tests/unit/style/viewport.rs @@ -14,8 +14,9 @@ use style::parser::ParserContext; use style::shared_lock::{SharedRwLock, StylesheetGuards}; use style::stylesheets::viewport_rule::*; 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::LengthPercentageOrAuto::{self, Auto}; use style::values::specified::NoCalcLength::{self, ViewportPercentage}; use style::values::specified::ViewportPercentageLength::Vw; use style_traits::viewport::*; @@ -97,14 +98,14 @@ macro_rules! assert_decl_len { macro_rules! viewport_length { ($value:expr, px) => { - ViewportLength::Specified(LengthPercentageOrAuto::LengthPercentage( + ViewportLength::Specified(LengthPercentageOrAuto::LengthPercentage(NonNegative( LengthPercentage::Length(NoCalcLength::from_px($value)), - )) + ))) }; ($value:expr, vw) => { - ViewportLength::Specified(LengthPercentageOrAuto::LengthPercentage( + ViewportLength::Specified(LengthPercentageOrAuto::LengthPercentage(NonNegative( LengthPercentage::Length(ViewportPercentage(Vw($value))), - )) + ))) }; } |