From 5c93ac4baecddbe4b54d050eb7a5b72d55f4dc40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 12 Sep 2019 21:09:39 +0000 Subject: [PATCH] Bug 1580963 - Cherry-pick style changes from servo's victor import. https://github.com/servo/servo/pull/24165 Differential Revision: https://phabricator.services.mozilla.com/D45740 --HG-- extra : moz-landing-system : lando --- servo/components/style/style_adjuster.rs | 3 + .../style/values/computed/length.rs | 107 +++++++++++++++--- .../style/values/generics/length.rs | 33 ++++++ .../components/style/values/specified/box.rs | 69 ++++++++++- 4 files changed, 195 insertions(+), 17 deletions(-) diff --git a/servo/components/style/style_adjuster.rs b/servo/components/style/style_adjuster.rs index 4f8794bc7e63..9f274917b08c 100644 --- a/servo/components/style/style_adjuster.rs +++ b/servo/components/style/style_adjuster.rs @@ -12,6 +12,7 @@ use crate::properties::longhands::float::computed_value::T as Float; use crate::properties::longhands::overflow_x::computed_value::T as Overflow; use crate::properties::longhands::position::computed_value::T as Position; use crate::properties::{self, ComputedValues, StyleBuilder}; +#[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] use crate::values::specified::box_::DisplayInside; use app_units::Au; @@ -183,6 +184,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { where E: TElement, { + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] use crate::computed_values::list_style_position::T as ListStylePosition; let mut blockify = false; @@ -205,6 +207,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { blockify_if!(self.style.floated()); blockify_if!(self.style.out_of_flow_positioned()); + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] blockify_if!( self.style.pseudo.map_or(false, |p| p.is_marker()) && self.style.get_parent_list().clone_list_style_position() == diff --git a/servo/components/style/values/computed/length.rs b/servo/components/style/values/computed/length.rs index f9575061d7da..2643cd141504 100644 --- a/servo/components/style/values/computed/length.rs +++ b/servo/components/style/values/computed/length.rs @@ -20,9 +20,9 @@ use crate::Zero; use app_units::Au; use ordered_float::NotNan; use std::fmt::{self, Write}; -use std::ops::{Add, Mul, Neg}; +use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub}; use style_traits::values::specified::AllowedNumericType; -use style_traits::{CssWriter, ToCss}; +use style_traits::{CSSPixel, CssWriter, ToCss}; pub use super::image::Image; pub use crate::values::specified::url::UrlOrNone; @@ -198,20 +198,26 @@ impl LengthPercentage { Some(Percentage(self.clamping_mode.clamp(self.percentage.0))) } + /// Resolves the percentage. + #[inline] + pub fn percentage_relative_to(&self, basis: Length) -> Length { + let length = self.unclamped_length().0 + basis.0 * self.percentage.0; + Length::new(self.clamping_mode.clamp(length)) + } + /// Convert the computed value into used value. #[inline] - pub fn maybe_to_used_value(&self, container_len: Option) -> Option { - self.maybe_to_pixel_length(container_len).map(Au::from) + pub fn maybe_to_used_value(&self, container_len: Option) -> Option { + self.maybe_percentage_relative_to(container_len) + .map(Au::from) } /// If there are special rules for computing percentages in a value (e.g. /// the height property), they apply whenever a calc() expression contains /// percentages. - pub fn maybe_to_pixel_length(&self, container_len: Option) -> Option { + pub fn maybe_percentage_relative_to(&self, container_len: Option) -> Option { if self.has_percentage { - let length = self.unclamped_length().px() + - container_len?.scale_by(self.percentage.0).to_f32_px(); - return Some(Length::new(self.clamping_mode.clamp(length))); + return Some(self.percentage_relative_to(container_len?)); } Some(self.length()) } @@ -362,7 +368,7 @@ impl LengthPercentage { /// Returns the used value as CSSPixelLength. pub fn to_pixel_length(&self, containing_length: Au) -> Length { - self.maybe_to_pixel_length(Some(containing_length)).unwrap() + self.percentage_relative_to(containing_length.into()) } /// Returns the clamped non-negative values. @@ -473,6 +479,30 @@ impl LengthPercentageOrAuto { } computed_length_percentage_or_auto!(LengthPercentage); + + /// Resolves the percentage. + #[inline] + pub fn percentage_relative_to(&self, basis: Length) -> LengthOrAuto { + use values::generics::length::LengthPercentageOrAuto::*; + match self { + LengthPercentage(length_percentage) => { + LengthPercentage(length_percentage.percentage_relative_to(basis)) + }, + Auto => Auto, + } + } + + /// Maybe resolves the percentage. + #[inline] + pub fn maybe_percentage_relative_to(&self, basis: Option) -> LengthOrAuto { + use values::generics::length::LengthPercentageOrAuto::*; + match self { + LengthPercentage(length_percentage) => length_percentage + .maybe_percentage_relative_to(basis) + .map_or(Auto, LengthPercentage), + Auto => Auto, + } + } } /// A wrapper of LengthPercentageOrAuto, whose value must be >= 0. @@ -540,7 +570,9 @@ impl NonNegativeLengthPercentage { /// Convert the computed value into used value. #[inline] pub fn maybe_to_used_value(&self, containing_length: Option) -> Option { - let resolved = self.0.maybe_to_used_value(containing_length)?; + let resolved = self + .0 + .maybe_to_used_value(containing_length.map(|v| v.into()))?; Some(::std::cmp::max(resolved, Au(0))) } } @@ -629,6 +661,23 @@ impl CSSPixelLength { pub fn clamp_to_non_negative(self) -> Self { CSSPixelLength::new(self.0.max(0.)) } + + /// Returns the minimum between `self` and `other`. + #[inline] + pub fn min(self, other: Self) -> Self { + CSSPixelLength::new(self.0.min(other.0)) + } + + /// Returns the maximum between `self` and `other`. + #[inline] + pub fn max(self, other: Self) -> Self { + CSSPixelLength::new(self.0.max(other.0)) + } + + /// Sets `self` to the maximum between `self` and `other`. + pub fn max_assign(&mut self, other: Self) { + *self = self.max(other); + } } impl Zero for CSSPixelLength { @@ -661,12 +710,19 @@ impl Add for CSSPixelLength { } } -impl Neg for CSSPixelLength { +impl AddAssign for CSSPixelLength { + #[inline] + fn add_assign(&mut self, other: Self) { + self.0 += other.0; + } +} + +impl Div for CSSPixelLength { type Output = Self; #[inline] - fn neg(self) -> Self { - CSSPixelLength::new(-self.0) + fn div(self, other: CSSFloat) -> Self { + Self::new(self.px() / other) } } @@ -679,6 +735,24 @@ impl Mul for CSSPixelLength { } } +impl Neg for CSSPixelLength { + type Output = Self; + + #[inline] + fn neg(self) -> Self { + CSSPixelLength::new(-self.0) + } +} + +impl Sub for CSSPixelLength { + type Output = Self; + + #[inline] + fn sub(self, other: Self) -> Self { + Self::new(self.px() - other.px()) + } +} + impl From for Au { #[inline] fn from(len: CSSPixelLength) -> Self { @@ -693,6 +767,13 @@ impl From for CSSPixelLength { } } +impl From for euclid::Length { + #[inline] + fn from(length: CSSPixelLength) -> Self { + Self::new(length.0) + } +} + /// An alias of computed `` value. pub type Length = CSSPixelLength; diff --git a/servo/components/style/values/generics/length.rs b/servo/components/style/values/generics/length.rs index 1665f144778b..d9cc2396f38d 100644 --- a/servo/components/style/values/generics/length.rs +++ b/servo/components/style/values/generics/length.rs @@ -69,6 +69,39 @@ impl LengthPercentageOrAuto { } } +impl LengthPercentageOrAuto +where + LengthPercentage: Clone, +{ + /// Resolves `auto` values by calling `f`. + #[inline] + pub fn auto_is(&self, f: impl Fn() -> LengthPercentage) -> LengthPercentage { + match self { + LengthPercentageOrAuto::LengthPercentage(length) => length.clone(), + LengthPercentageOrAuto::Auto => f(), + } + } + + /// Returns the non-`auto` value, if any. + #[inline] + pub fn non_auto(&self) -> Option { + match self { + LengthPercentageOrAuto::LengthPercentage(length) => Some(length.clone()), + LengthPercentageOrAuto::Auto => None, + } + } + + /// Maps the length of this value. + pub fn map(&self, f: impl FnOnce(LengthPercentage) -> LengthPercentage) -> Self { + match self { + LengthPercentageOrAuto::LengthPercentage(l) => { + LengthPercentageOrAuto::LengthPercentage(f(l.clone())) + }, + LengthPercentageOrAuto::Auto => LengthPercentageOrAuto::Auto, + } + } +} + impl Zero for LengthPercentageOrAuto { fn zero() -> Self { LengthPercentageOrAuto::LengthPercentage(Zero::zero()) diff --git a/servo/components/style/values/specified/box.rs b/servo/components/style/values/specified/box.rs index ad703fa65ed4..3e18a23d9649 100644 --- a/servo/components/style/values/specified/box.rs +++ b/servo/components/style/values/specified/box.rs @@ -44,7 +44,9 @@ pub enum DisplayOutside { None = 0, Inline, Block, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] TableCaption, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] InternalTable, #[cfg(feature = "gecko")] InternalRuby, @@ -57,21 +59,32 @@ pub enum DisplayOutside { #[repr(u8)] pub enum DisplayInside { None = 0, - #[cfg(feature = "gecko")] + #[cfg(any(feature = "servo-layout-2020", feature = "gecko"))] Contents, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] Block, FlowRoot, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] Inline, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] Flex, #[cfg(feature = "gecko")] Grid, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] Table, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] TableRowGroup, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] TableColumn, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] TableColumnGroup, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] TableHeaderGroup, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] TableFooterGroup, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] TableRow, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] TableCell, #[cfg(feature = "gecko")] Ruby, @@ -134,21 +147,32 @@ impl Display { /// https://drafts.csswg.org/css-display/#the-display-properties pub const None: Self = Self::new(DisplayOutside::None, DisplayInside::None); - #[cfg(feature = "gecko")] + #[cfg(any(feature = "servo-layout-2020", feature = "gecko"))] pub const Contents: Self = Self::new(DisplayOutside::None, DisplayInside::Contents); + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] pub const Inline: Self = Self::new(DisplayOutside::Inline, DisplayInside::Inline); + #[cfg(any(feature = "servo-layout-2020"))] + pub const Inline: Self = Self::new(DisplayOutside::Inline, DisplayInside::Flow); pub const InlineBlock: Self = Self::new(DisplayOutside::Inline, DisplayInside::FlowRoot); + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] pub const Block: Self = Self::new(DisplayOutside::Block, DisplayInside::Block); + #[cfg(any(feature = "servo-layout-2020"))] + pub const Block: Self = Self::new(DisplayOutside::Block, DisplayInside::Flow); #[cfg(feature = "gecko")] pub const FlowRoot: Self = Self::new(DisplayOutside::Block, DisplayInside::FlowRoot); + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] pub const Flex: Self = Self::new(DisplayOutside::Block, DisplayInside::Flex); + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] pub const InlineFlex: Self = Self::new(DisplayOutside::Inline, DisplayInside::Flex); #[cfg(feature = "gecko")] pub const Grid: Self = Self::new(DisplayOutside::Block, DisplayInside::Grid); #[cfg(feature = "gecko")] pub const InlineGrid: Self = Self::new(DisplayOutside::Inline, DisplayInside::Grid); + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] pub const Table: Self = Self::new(DisplayOutside::Block, DisplayInside::Table); + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] pub const InlineTable: Self = Self::new(DisplayOutside::Inline, DisplayInside::Table); + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] pub const TableCaption: Self = Self::new(DisplayOutside::TableCaption, DisplayInside::Block); #[cfg(feature = "gecko")] pub const Ruby: Self = Self::new(DisplayOutside::Inline, DisplayInside::Ruby); @@ -156,25 +180,39 @@ impl Display { pub const WebkitBox: Self = Self::new(DisplayOutside::Block, DisplayInside::WebkitBox); #[cfg(feature = "gecko")] pub const WebkitInlineBox: Self = Self::new(DisplayOutside::Inline, DisplayInside::WebkitBox); - /// Internal table boxes. + + // Internal table boxes. + + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] pub const TableRowGroup: Self = Self::new(DisplayOutside::InternalTable, DisplayInside::TableRowGroup); + + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] pub const TableHeaderGroup: Self = Self::new( DisplayOutside::InternalTable, DisplayInside::TableHeaderGroup, ); + + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] pub const TableFooterGroup: Self = Self::new( DisplayOutside::InternalTable, DisplayInside::TableFooterGroup, ); + + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] pub const TableColumn: Self = Self::new(DisplayOutside::InternalTable, DisplayInside::TableColumn); + + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] pub const TableColumnGroup: Self = Self::new( DisplayOutside::InternalTable, DisplayInside::TableColumnGroup, ); + + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] pub const TableRow: Self = Self::new(DisplayOutside::InternalTable, DisplayInside::TableRow); + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] pub const TableCell: Self = Self::new(DisplayOutside::InternalTable, DisplayInside::TableCell); /// Internal ruby boxes. @@ -227,6 +265,7 @@ impl Display { #[inline] fn from3(outside: DisplayOutside, inside: DisplayInside, list_item: bool) -> Self { let inside = match inside { + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] DisplayInside::Flow => match outside { DisplayOutside::Inline => DisplayInside::Inline, _ => DisplayInside::Block, @@ -299,6 +338,7 @@ impl Display { pub fn is_atomic_inline_level(&self) -> bool { match *self { Display::InlineBlock => true, + #[cfg(any(feature = "servo-layout-2013"))] Display::InlineFlex | Display::InlineTable => true, _ => false, } @@ -310,6 +350,7 @@ impl Display { /// This is used to implement various style fixups. pub fn is_item_container(&self) -> bool { match self.inside() { + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] DisplayInside::Flex => true, #[cfg(feature = "gecko")] DisplayInside::Grid => true, @@ -344,12 +385,16 @@ impl Display { match self.outside() { DisplayOutside::Inline => { let inside = match self.inside() { + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] DisplayInside::Inline | DisplayInside::FlowRoot => DisplayInside::Block, + #[cfg(feature = "servo-layout-2020")] + DisplayInside::FlowRoot => DisplayInside::Flow, inside => inside, }; Display::from3(DisplayOutside::Block, inside, self.is_list_item()) }, DisplayOutside::Block | DisplayOutside::None => *self, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] _ => Display::Block, } } @@ -404,6 +449,7 @@ impl ToCss for Display { ); let outside = self.outside(); let inside = match self.inside() { + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] DisplayInside::Block | DisplayInside::Inline => DisplayInside::Flow, inside => inside, }; @@ -414,10 +460,12 @@ impl ToCss for Display { Display::WebkitInlineBox => dest.write_str("-webkit-inline-box"), #[cfg(feature = "gecko")] Display::MozInlineBox => dest.write_str("-moz-inline-box"), + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] Display::TableCaption => dest.write_str("table-caption"), _ => match (outside, inside) { #[cfg(feature = "gecko")] (DisplayOutside::Inline, DisplayInside::Grid) => dest.write_str("inline-grid"), + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] (DisplayOutside::Inline, DisplayInside::Flex) | (DisplayOutside::Inline, DisplayInside::Table) => { dest.write_str("inline-")?; @@ -452,9 +500,11 @@ fn parse_display_inside<'i, 't>( ) -> Result> { Ok(try_match_ident_ignore_ascii_case! { input, "flow" => DisplayInside::Flow, - #[cfg(feature = "gecko")] + #[cfg(any(feature = "servo-layout-2020", feature = "gecko"))] "flow-root" => DisplayInside::FlowRoot, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] "table" => DisplayInside::Table, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] "flex" => DisplayInside::Flex, #[cfg(feature = "gecko")] "grid" => DisplayInside::Grid, @@ -556,18 +606,29 @@ impl Parse for Display { #[cfg(feature = "gecko")] "contents" => Display::Contents, "inline-block" => Display::InlineBlock, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] "inline-table" => Display::InlineTable, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] "-webkit-flex" => Display::Flex, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] "inline-flex" | "-webkit-inline-flex" => Display::InlineFlex, #[cfg(feature = "gecko")] "inline-grid" => Display::InlineGrid, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] "table-caption" => Display::TableCaption, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] "table-row-group" => Display::TableRowGroup, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] "table-header-group" => Display::TableHeaderGroup, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] "table-footer-group" => Display::TableFooterGroup, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] "table-column" => Display::TableColumn, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] "table-column-group" => Display::TableColumnGroup, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] "table-row" => Display::TableRow, + #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] "table-cell" => Display::TableCell, #[cfg(feature = "gecko")] "ruby-base" => Display::RubyBase,