Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the `box-sizing` property #26079

Merged
merged 6 commits into from Apr 1, 2020

Less cloning

  • Loading branch information
SimonSapin committed Mar 31, 2020
commit 08801d94cd0416ef1bb50bb4657929d38c02dbec
@@ -206,7 +206,7 @@ impl InlineFormattingContext {
}
}

fn add_lengthpercentage(&mut self, lp: LengthPercentage) {
fn add_lengthpercentage(&mut self, lp: &LengthPercentage) {
if let Some(l) = lp.to_length() {
self.add_length(l);
}
@@ -7,15 +7,17 @@ use std::fmt;
use std::ops::{Add, AddAssign, Sub};
use style::logical_geometry::{BlockFlowDirection, InlineBaseDirection};
use style::logical_geometry::{PhysicalCorner, WritingMode};
use style::values::computed::{Length, LengthOrAuto, LengthPercentage, LengthPercentageOrAuto};
use style::values::generics::length::MaxSize;
use style::values::computed::{Length, LengthPercentage};
use style::values::generics::length::GenericLengthPercentageOrAuto as AutoOr;
use style::Zero;
use style_traits::CSSPixel;

pub type PhysicalPoint<U> = euclid::Point2D<U, CSSPixel>;
pub type PhysicalSize<U> = euclid::Size2D<U, CSSPixel>;
pub type PhysicalRect<U> = euclid::Rect<U, CSSPixel>;
pub type PhysicalSides<U> = euclid::SideOffsets2D<U, CSSPixel>;
pub type LengthOrAuto = AutoOr<Length>;
pub type LengthPercentageOrAuto<'a> = AutoOr<&'a LengthPercentage>;

pub(crate) mod flow_relative {
#[derive(Clone, Serialize)]
@@ -107,7 +109,7 @@ impl flow_relative::Vec2<LengthOrAuto> {
}
}

impl flow_relative::Vec2<LengthPercentageOrAuto> {
impl flow_relative::Vec2<LengthPercentageOrAuto<'_>> {
pub fn percentages_relative_to(
&self,
containing_block: &ContainingBlock,
@@ -123,24 +125,18 @@ impl flow_relative::Vec2<LengthPercentageOrAuto> {
}
}

impl flow_relative::Vec2<MaxSize<LengthPercentage>> {
impl flow_relative::Vec2<Option<&'_ LengthPercentage>> {
pub fn percentages_relative_to(
&self,
containing_block: &ContainingBlock,
) -> flow_relative::Vec2<Option<Length>> {
flow_relative::Vec2 {
inline: match self.inline {
MaxSize::None => None,
MaxSize::LengthPercentage(ref lp) => {
Some(lp.percentage_relative_to(containing_block.inline_size))
},
},
block: match self.block {
MaxSize::None => None,
MaxSize::LengthPercentage(ref lp) => {
lp.maybe_percentage_relative_to(containing_block.block_size.non_auto())
},
},
inline: self
.inline
.map(|lp| lp.percentage_relative_to(containing_block.inline_size)),
block: self.block.and_then(|lp| {
lp.maybe_percentage_relative_to(containing_block.block_size.non_auto())
}),
}
}
}
@@ -280,13 +276,13 @@ impl<T> flow_relative::Sides<T> {
}
}

impl flow_relative::Sides<LengthPercentage> {
impl flow_relative::Sides<&'_ LengthPercentage> {
pub fn percentages_relative_to(&self, basis: Length) -> flow_relative::Sides<Length> {
self.map(|s| s.percentage_relative_to(basis))
}
}

impl flow_relative::Sides<LengthPercentageOrAuto> {
impl flow_relative::Sides<LengthPercentageOrAuto<'_>> {
pub fn percentages_relative_to(&self, basis: Length) -> flow_relative::Sides<LengthOrAuto> {
self.map(|s| s.percentage_relative_to(basis))
}
@@ -8,6 +8,7 @@ use crate::dom_traversal::{Contents, NodeExt};
use crate::formatting_contexts::IndependentFormattingContext;
use crate::fragments::{BoxFragment, CollapsedBlockMargins, Fragment};
use crate::geom::flow_relative::{Rect, Sides, Vec2};
use crate::geom::{LengthOrAuto, LengthPercentageOrAuto};
use crate::sizing::ContentSizesRequest;
use crate::style_ext::{ComputedValuesExt, DisplayInside};
use crate::{ContainingBlock, DefiniteContainingBlock};
@@ -16,7 +17,7 @@ use rayon_croissant::ParallelIteratorExt;
use servo_arc::Arc;
use style::computed_values::position::T as Position;
use style::properties::ComputedValues;
use style::values::computed::{Length, LengthOrAuto, LengthPercentage, LengthPercentageOrAuto};
use style::values::computed::{Length, LengthPercentage};
use style::values::specified::text::TextDecorationLine;
use style::Zero;

@@ -112,29 +113,34 @@ impl AbsolutelyPositionedBox {
(None, None) => AbsoluteBoxOffsets::StaticStart {
start: initial_static_start,
},
(Some(start), Some(end)) => AbsoluteBoxOffsets::Both { start, end },
(None, Some(end)) => AbsoluteBoxOffsets::End { end },
(Some(start), None) => AbsoluteBoxOffsets::Start { start },
(Some(start), Some(end)) => AbsoluteBoxOffsets::Both {
start: start.clone(),
end: end.clone(),
},
(None, Some(end)) => AbsoluteBoxOffsets::End { end: end.clone() },
(Some(start), None) => AbsoluteBoxOffsets::Start {
start: start.clone(),
},
}
}

let box_offsets = self.contents.style.box_offsets();
HoistedAbsolutelyPositionedBox {
absolutely_positioned_box: self,
tree_rank,
box_offsets: Vec2 {
inline: absolute_box_offsets(
initial_start_corner.inline,
box_offsets.inline_start.clone(),
box_offsets.inline_end.clone(),
box_offsets.inline_start,
box_offsets.inline_end,
),
block: absolute_box_offsets(
initial_start_corner.block,
box_offsets.block_start.clone(),
box_offsets.block_end.clone(),
box_offsets.block_start,
box_offsets.block_end,
),
},
fragment: ArcRefCell::new(None),
absolutely_positioned_box: self,
}
}
}
@@ -436,7 +442,7 @@ impl HoistedAbsolutelyPositionedBox {
pbm.margin.inline_start,
pbm.margin.inline_end,
/* avoid_negative_margin_start */ true,
self.box_offsets.inline.clone(),
&self.box_offsets.inline,
size.inline,
);

@@ -446,7 +452,7 @@ impl HoistedAbsolutelyPositionedBox {
pbm.margin.block_start,
pbm.margin.block_end,
/* avoid_negative_margin_start */ false,
self.box_offsets.block.clone(),
&self.box_offsets.block,
size.block,
);

@@ -583,12 +589,12 @@ fn solve_axis(
computed_margin_start: LengthOrAuto,
computed_margin_end: LengthOrAuto,
avoid_negative_margin_start: bool,
box_offsets: AbsoluteBoxOffsets,
box_offsets: &AbsoluteBoxOffsets,
size: LengthOrAuto,
) -> AxisResult {
match box_offsets {
AbsoluteBoxOffsets::StaticStart { start } => AxisResult {
anchor: Anchor::Start(start),
anchor: Anchor::Start(*start),
size,
margin_start: computed_margin_start.auto_is(Length::zero),
margin_end: computed_margin_end.auto_is(Length::zero),
@@ -8,7 +8,6 @@ use crate::style_ext::ComputedValuesExt;
use style::properties::longhands::box_sizing::computed_value::T as BoxSizing;
use style::properties::ComputedValues;
use style::values::computed::{Length, LengthPercentage, Percentage};
use style::values::generics::length::MaxSize;
use style::Zero;

/// Which min/max-content values should be computed during box construction
@@ -121,7 +120,7 @@ impl BoxContentSizes {
let margin = style.margin();

let mut pbm_percentages = Percentage::zero();
let mut decompose = |x: LengthPercentage| {
let mut decompose = |x: &LengthPercentage| {
pbm_percentages += x.to_percentage().unwrap_or_else(Zero::zero);
x.to_length().unwrap_or_else(Zero::zero)
};
@@ -149,11 +148,11 @@ impl BoxContentSizes {
.percentage_relative_to(Length::zero())
// FIXME: 'auto' is not zero in Flexbox
.auto_is(Length::zero);
let max_inline_size = match style.max_box_size().inline {
MaxSize::None => None,
let max_inline_size = style
.max_box_size()
.inline
// Percentages for 'max-width' are treated as 'none'
MaxSize::LengthPercentage(ref lp) => lp.to_length(),
};
.and_then(|lp| lp.to_length());
let clamp = |l: Length| l.clamp_between_extremums(min_inline_size, max_inline_size);

let border_box_sizes = match inline_size {
@@ -2,14 +2,15 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use crate::geom::{flow_relative, PhysicalSides, PhysicalSize};
use crate::geom::flow_relative;
use crate::geom::{LengthOrAuto, LengthPercentageOrAuto, PhysicalSides, PhysicalSize};
use crate::ContainingBlock;
use style::computed_values::mix_blend_mode::T as ComputedMixBlendMode;
use style::computed_values::position::T as ComputedPosition;
use style::computed_values::transform_style::T as ComputedTransformStyle;
use style::properties::longhands::box_sizing::computed_value::T as BoxSizing;
use style::properties::ComputedValues;
use style::values::computed::{Length, LengthOrAuto, LengthPercentage, LengthPercentageOrAuto};
use style::values::computed::{Length, LengthPercentage};
use style::values::computed::{NonNegativeLengthPercentage, Size};
use style::values::generics::box_::Perspective;
use style::values::generics::length::MaxSize;
@@ -62,7 +63,7 @@ pub(crate) trait ComputedValuesExt {
fn box_offsets(&self) -> flow_relative::Sides<LengthPercentageOrAuto>;
fn box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto>;
fn min_box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto>;
fn max_box_size(&self) -> flow_relative::Vec2<MaxSize<LengthPercentage>>;
fn max_box_size(&self) -> flow_relative::Vec2<Option<&LengthPercentage>>;
fn content_box_size(
&self,
containing_block: &ContainingBlock,
@@ -79,7 +80,7 @@ pub(crate) trait ComputedValuesExt {
pbm: &PaddingBorderMargin,
) -> flow_relative::Vec2<Option<Length>>;
fn padding_border_margin(&self, containing_block: &ContainingBlock) -> PaddingBorderMargin;
fn padding(&self) -> flow_relative::Sides<LengthPercentage>;
fn padding(&self) -> flow_relative::Sides<&LengthPercentage>;
fn border_width(&self) -> flow_relative::Sides<Length>;
fn margin(&self) -> flow_relative::Sides<LengthPercentageOrAuto>;
fn has_transform_or_perspective(&self) -> bool;
@@ -114,10 +115,10 @@ impl ComputedValuesExt for ComputedValues {
let position = self.get_position();
flow_relative::Sides::from_physical(
&PhysicalSides::new(
position.top.clone(),
position.right.clone(),
position.bottom.clone(),
position.left.clone(),
position.top.as_ref(),
position.right.as_ref(),
position.bottom.as_ref(),
position.left.as_ref(),
),
self.writing_mode,
)
@@ -127,8 +128,8 @@ impl ComputedValuesExt for ComputedValues {
let position = self.get_position();
flow_relative::Vec2::from_physical_size(
&PhysicalSize::new(
size_to_length(position.width.clone()),
size_to_length(position.height.clone()),
size_to_length(&position.width),
size_to_length(&position.height),
),
self.writing_mode,
)
@@ -138,24 +139,23 @@ impl ComputedValuesExt for ComputedValues {
let position = self.get_position();
flow_relative::Vec2::from_physical_size(
&PhysicalSize::new(
size_to_length(position.min_width.clone()),
size_to_length(position.min_height.clone()),
size_to_length(&position.min_width),
size_to_length(&position.min_height),
),
self.writing_mode,
)
}

fn max_box_size(&self) -> flow_relative::Vec2<MaxSize<LengthPercentage>> {
let unwrap = |max_size: MaxSize<NonNegativeLengthPercentage>| match max_size {
MaxSize::LengthPercentage(length) => MaxSize::LengthPercentage(length.0),
MaxSize::None => MaxSize::None,
};
fn max_box_size(&self) -> flow_relative::Vec2<Option<&LengthPercentage>> {
fn unwrap(max_size: &MaxSize<NonNegativeLengthPercentage>) -> Option<&LengthPercentage> {
match max_size {
MaxSize::LengthPercentage(length) => Some(&length.0),
MaxSize::None => None,
}
}
let position = self.get_position();
flow_relative::Vec2::from_physical_size(
&PhysicalSize::new(
unwrap(position.max_width.clone()),
unwrap(position.max_height.clone()),
),
&PhysicalSize::new(unwrap(&position.max_width), unwrap(&position.max_height)),
self.writing_mode,
)
}
@@ -239,14 +239,14 @@ impl ComputedValuesExt for ComputedValues {
}
}

fn padding(&self) -> flow_relative::Sides<LengthPercentage> {
fn padding(&self) -> flow_relative::Sides<&LengthPercentage> {
let padding = self.get_padding();
flow_relative::Sides::from_physical(
&PhysicalSides::new(
padding.padding_top.0.clone(),
padding.padding_right.0.clone(),
padding.padding_bottom.0.clone(),
padding.padding_left.0.clone(),
&padding.padding_top.0,
&padding.padding_right.0,
&padding.padding_bottom.0,
&padding.padding_left.0,
),
self.writing_mode,
)
@@ -269,10 +269,10 @@ impl ComputedValuesExt for ComputedValues {
let margin = self.get_margin();
flow_relative::Sides::from_physical(
&PhysicalSides::new(
margin.margin_top.clone(),
margin.margin_right.clone(),
margin.margin_bottom.clone(),
margin.margin_left.clone(),
margin.margin_top.as_ref(),
margin.margin_right.as_ref(),
margin.margin_bottom.as_ref(),
margin.margin_left.as_ref(),
),
self.writing_mode,
)
@@ -388,9 +388,9 @@ impl From<stylo::Display> for Display {
}
}

fn size_to_length(size: Size) -> LengthPercentageOrAuto {
fn size_to_length(size: &Size) -> LengthPercentageOrAuto {
match size {
Size::LengthPercentage(length) => LengthPercentageOrAuto::LengthPercentage(length.0),
Size::LengthPercentage(length) => LengthPercentageOrAuto::LengthPercentage(&length.0),
Size::Auto => LengthPercentageOrAuto::Auto,
}
}
@@ -109,8 +109,19 @@ impl LengthPercentageOrAuto {
}
}

/// Convert to have a borrow inside the enum
pub fn as_ref(&self) -> generics::GenericLengthPercentageOrAuto<&LengthPercentage> {
use values::generics::length::LengthPercentageOrAuto::*;
match *self {
LengthPercentage(ref lp) => LengthPercentage(lp),
Auto => Auto,
}
}

computed_length_percentage_or_auto!(LengthPercentage);
}

impl generics::GenericLengthPercentageOrAuto<&LengthPercentage> {
/// Resolves the percentage.
#[inline]
pub fn percentage_relative_to(&self, basis: Length) -> LengthOrAuto {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.