mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Implement the box-sizing
property
This commit is contained in:
parent
0e35d70ca8
commit
c377d9c48e
7 changed files with 168 additions and 94 deletions
|
@ -529,10 +529,8 @@ fn layout_atomic(
|
||||||
atomic: &IndependentFormattingContext,
|
atomic: &IndependentFormattingContext,
|
||||||
) {
|
) {
|
||||||
let pbm = atomic.style.padding_border_margin(&ifc.containing_block);
|
let pbm = atomic.style.padding_border_margin(&ifc.containing_block);
|
||||||
let padding = pbm.padding;
|
|
||||||
let border = pbm.border;
|
|
||||||
let margin = pbm.margin.auto_is(Length::zero);
|
let margin = pbm.margin.auto_is(Length::zero);
|
||||||
let pbm_sums = &(&padding + &border) + &margin;
|
let pbm_sums = &(&pbm.padding + &pbm.border) + &margin;
|
||||||
ifc.inline_position += pbm_sums.inline_start;
|
ifc.inline_position += pbm_sums.inline_start;
|
||||||
let mut start_corner = Vec2 {
|
let mut start_corner = Vec2 {
|
||||||
block: pbm_sums.block_start,
|
block: pbm_sums.block_start,
|
||||||
|
@ -544,7 +542,8 @@ fn layout_atomic(
|
||||||
|
|
||||||
let fragment = match atomic.as_replaced() {
|
let fragment = match atomic.as_replaced() {
|
||||||
Ok(replaced) => {
|
Ok(replaced) => {
|
||||||
let size = replaced.used_size_as_if_inline_element(ifc.containing_block, &atomic.style);
|
let size =
|
||||||
|
replaced.used_size_as_if_inline_element(ifc.containing_block, &atomic.style, &pbm);
|
||||||
let fragments = replaced.make_fragments(&atomic.style, size.clone());
|
let fragments = replaced.make_fragments(&atomic.style, size.clone());
|
||||||
let content_rect = Rect { start_corner, size };
|
let content_rect = Rect { start_corner, size };
|
||||||
BoxFragment::new(
|
BoxFragment::new(
|
||||||
|
@ -552,29 +551,25 @@ fn layout_atomic(
|
||||||
atomic.style.clone(),
|
atomic.style.clone(),
|
||||||
fragments,
|
fragments,
|
||||||
content_rect,
|
content_rect,
|
||||||
padding,
|
pbm.padding,
|
||||||
border,
|
pbm.border,
|
||||||
margin,
|
margin,
|
||||||
CollapsedBlockMargins::zero(),
|
CollapsedBlockMargins::zero(),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
Err(non_replaced) => {
|
Err(non_replaced) => {
|
||||||
let box_size = atomic.style.box_size();
|
let box_size = atomic.style.content_box_size(&ifc.containing_block, &pbm);
|
||||||
let max_box_size = atomic
|
let max_box_size = atomic
|
||||||
.style
|
.style
|
||||||
.max_box_size()
|
.content_max_box_size(&ifc.containing_block, &pbm);
|
||||||
.percentages_relative_to(ifc.containing_block);
|
|
||||||
let min_box_size = atomic
|
let min_box_size = atomic
|
||||||
.style
|
.style
|
||||||
.min_box_size()
|
.content_min_box_size(&ifc.containing_block, &pbm)
|
||||||
.percentages_relative_to(ifc.containing_block)
|
|
||||||
.auto_is(Length::zero);
|
.auto_is(Length::zero);
|
||||||
|
|
||||||
// https://drafts.csswg.org/css2/visudet.html#inlineblock-width
|
// https://drafts.csswg.org/css2/visudet.html#inlineblock-width
|
||||||
let cbis = ifc.containing_block.inline_size;
|
let tentative_inline_size = box_size.inline.auto_is(|| {
|
||||||
let tentative_inline_size =
|
let available_size = ifc.containing_block.inline_size - pbm_sums.inline_sum();
|
||||||
box_size.inline.percentage_relative_to(cbis).auto_is(|| {
|
|
||||||
let available_size = cbis - pbm_sums.inline_sum();
|
|
||||||
atomic.content_sizes.shrink_to_fit(available_size)
|
atomic.content_sizes.shrink_to_fit(available_size)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -584,12 +579,9 @@ fn layout_atomic(
|
||||||
let inline_size = tentative_inline_size
|
let inline_size = tentative_inline_size
|
||||||
.clamp_between_extremums(min_box_size.inline, max_box_size.inline);
|
.clamp_between_extremums(min_box_size.inline, max_box_size.inline);
|
||||||
|
|
||||||
let block_size = box_size
|
|
||||||
.block
|
|
||||||
.maybe_percentage_relative_to(ifc.containing_block.block_size.non_auto());
|
|
||||||
let containing_block_for_children = ContainingBlock {
|
let containing_block_for_children = ContainingBlock {
|
||||||
inline_size,
|
inline_size,
|
||||||
block_size,
|
block_size: box_size.block,
|
||||||
style: &atomic.style,
|
style: &atomic.style,
|
||||||
};
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -608,7 +600,9 @@ fn layout_atomic(
|
||||||
);
|
);
|
||||||
|
|
||||||
// https://drafts.csswg.org/css2/visudet.html#block-root-margin
|
// https://drafts.csswg.org/css2/visudet.html#block-root-margin
|
||||||
let tentative_block_size = block_size.auto_is(|| independent_layout.content_block_size);
|
let tentative_block_size = box_size
|
||||||
|
.block
|
||||||
|
.auto_is(|| independent_layout.content_block_size);
|
||||||
|
|
||||||
// https://drafts.csswg.org/css2/visudet.html#min-max-heights
|
// https://drafts.csswg.org/css2/visudet.html#min-max-heights
|
||||||
// In this case “applying the rules above again” with a non-auto block-size
|
// In this case “applying the rules above again” with a non-auto block-size
|
||||||
|
@ -628,8 +622,8 @@ fn layout_atomic(
|
||||||
atomic.style.clone(),
|
atomic.style.clone(),
|
||||||
independent_layout.fragments,
|
independent_layout.fragments,
|
||||||
content_rect,
|
content_rect,
|
||||||
padding,
|
pbm.padding,
|
||||||
border,
|
pbm.border,
|
||||||
margin,
|
margin,
|
||||||
CollapsedBlockMargins::zero(),
|
CollapsedBlockMargins::zero(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -351,14 +351,10 @@ fn layout_in_flow_non_replaced_block_level(
|
||||||
float_context: Option<&mut FloatContext>,
|
float_context: Option<&mut FloatContext>,
|
||||||
) -> BoxFragment {
|
) -> BoxFragment {
|
||||||
let pbm = style.padding_border_margin(containing_block);
|
let pbm = style.padding_border_margin(containing_block);
|
||||||
|
let box_size = style.content_box_size(containing_block, &pbm);
|
||||||
let box_size = style.box_size().percentages_relative_to(containing_block);
|
let max_box_size = style.content_max_box_size(containing_block, &pbm);
|
||||||
let max_box_size = style
|
|
||||||
.max_box_size()
|
|
||||||
.percentages_relative_to(containing_block);
|
|
||||||
let min_box_size = style
|
let min_box_size = style
|
||||||
.min_box_size()
|
.content_min_box_size(containing_block, &pbm)
|
||||||
.percentages_relative_to(containing_block)
|
|
||||||
.auto_is(Length::zero);
|
.auto_is(Length::zero);
|
||||||
|
|
||||||
// https://drafts.csswg.org/css2/visudet.html#min-max-widths
|
// https://drafts.csswg.org/css2/visudet.html#min-max-widths
|
||||||
|
@ -508,7 +504,7 @@ fn layout_in_flow_replaced_block_level<'a>(
|
||||||
replaced: &ReplacedContent,
|
replaced: &ReplacedContent,
|
||||||
) -> BoxFragment {
|
) -> BoxFragment {
|
||||||
let pbm = style.padding_border_margin(containing_block);
|
let pbm = style.padding_border_margin(containing_block);
|
||||||
let size = replaced.used_size_as_if_inline_element(containing_block, style);
|
let size = replaced.used_size_as_if_inline_element(containing_block, style, &pbm);
|
||||||
|
|
||||||
let (margin_inline_start, margin_inline_end) =
|
let (margin_inline_start, margin_inline_end) =
|
||||||
solve_inline_margins_for_in_flow_block_level(containing_block, &pbm, size.inline);
|
solve_inline_margins_for_in_flow_block_level(containing_block, &pbm, size.inline);
|
||||||
|
|
|
@ -416,19 +416,16 @@ impl HoistedAbsolutelyPositionedBox {
|
||||||
Ok(replaced) => {
|
Ok(replaced) => {
|
||||||
// https://drafts.csswg.org/css2/visudet.html#abs-replaced-width
|
// https://drafts.csswg.org/css2/visudet.html#abs-replaced-width
|
||||||
// https://drafts.csswg.org/css2/visudet.html#abs-replaced-height
|
// https://drafts.csswg.org/css2/visudet.html#abs-replaced-height
|
||||||
let u = replaced.used_size_as_if_inline_element(&containing_block.into(), style);
|
let used_size =
|
||||||
|
replaced.used_size_as_if_inline_element(&containing_block.into(), style, &pbm);
|
||||||
size = Vec2 {
|
size = Vec2 {
|
||||||
inline: LengthOrAuto::LengthPercentage(u.inline),
|
inline: LengthOrAuto::LengthPercentage(used_size.inline),
|
||||||
block: LengthOrAuto::LengthPercentage(u.block),
|
block: LengthOrAuto::LengthPercentage(used_size.block),
|
||||||
};
|
};
|
||||||
replaced_used_size = Some(u);
|
replaced_used_size = Some(used_size);
|
||||||
},
|
},
|
||||||
Err(_non_replaced) => {
|
Err(_non_replaced) => {
|
||||||
let box_size = style.box_size();
|
size = style.content_box_size(&containing_block.into(), &pbm);
|
||||||
size = Vec2 {
|
|
||||||
inline: box_size.inline.percentage_relative_to(cbis),
|
|
||||||
block: box_size.block.percentage_relative_to(cbbs),
|
|
||||||
};
|
|
||||||
replaced_used_size = None;
|
replaced_used_size = None;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use crate::fragments::{DebugId, Fragment, ImageFragment};
|
||||||
use crate::geom::flow_relative::{Rect, Vec2};
|
use crate::geom::flow_relative::{Rect, Vec2};
|
||||||
use crate::geom::PhysicalSize;
|
use crate::geom::PhysicalSize;
|
||||||
use crate::sizing::ContentSizes;
|
use crate::sizing::ContentSizes;
|
||||||
use crate::style_ext::ComputedValuesExt;
|
use crate::style_ext::{ComputedValuesExt, PaddingBorderMargin};
|
||||||
use crate::ContainingBlock;
|
use crate::ContainingBlock;
|
||||||
use canvas_traits::canvas::{CanvasId, CanvasMsg, FromLayoutMsg};
|
use canvas_traits::canvas::{CanvasId, CanvasMsg, FromLayoutMsg};
|
||||||
use ipc_channel::ipc::{self, IpcSender};
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
|
@ -240,19 +240,17 @@ impl ReplacedContent {
|
||||||
&self,
|
&self,
|
||||||
containing_block: &ContainingBlock,
|
containing_block: &ContainingBlock,
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
|
pbm: &PaddingBorderMargin,
|
||||||
) -> Vec2<Length> {
|
) -> Vec2<Length> {
|
||||||
let mode = style.writing_mode;
|
let mode = style.writing_mode;
|
||||||
let intrinsic_size = self.flow_relative_intrinsic_size(style);
|
let intrinsic_size = self.flow_relative_intrinsic_size(style);
|
||||||
let intrinsic_ratio = self.inline_size_over_block_size_intrinsic_ratio(style);
|
let intrinsic_ratio = self.inline_size_over_block_size_intrinsic_ratio(style);
|
||||||
|
|
||||||
let box_size = style.box_size().percentages_relative_to(containing_block);
|
let box_size = style.content_box_size(containing_block, &pbm);
|
||||||
|
let max_box_size = style.content_max_box_size(containing_block, &pbm);
|
||||||
let min_box_size = style
|
let min_box_size = style
|
||||||
.min_box_size()
|
.content_min_box_size(containing_block, &pbm)
|
||||||
.percentages_relative_to(containing_block)
|
|
||||||
.auto_is(Length::zero);
|
.auto_is(Length::zero);
|
||||||
let max_box_size = style
|
|
||||||
.max_box_size()
|
|
||||||
.percentages_relative_to(containing_block);
|
|
||||||
|
|
||||||
let default_object_size = || {
|
let default_object_size = || {
|
||||||
// FIXME:
|
// FIXME:
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
//! https://drafts.csswg.org/css-sizing/
|
//! https://drafts.csswg.org/css-sizing/
|
||||||
|
|
||||||
use crate::style_ext::ComputedValuesExt;
|
use crate::style_ext::ComputedValuesExt;
|
||||||
|
use style::properties::longhands::box_sizing::computed_value::T as BoxSizing;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::values::computed::{Length, LengthPercentage, Percentage};
|
use style::values::computed::{Length, LengthPercentage, Percentage};
|
||||||
use style::values::generics::length::MaxSize;
|
use style::values::generics::length::MaxSize;
|
||||||
|
@ -63,6 +64,13 @@ impl ContentSizes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn map(&self, f: impl Fn(Length) -> Length) -> Self {
|
||||||
|
Self {
|
||||||
|
min_content: f(self.min_content),
|
||||||
|
max_content: f(self.max_content),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn max_assign(&mut self, other: &Self) {
|
pub fn max_assign(&mut self, other: &Self) {
|
||||||
self.min_content.max_assign(other.min_content);
|
self.min_content.max_assign(other.min_content);
|
||||||
self.max_content.max_assign(other.max_content);
|
self.max_content.max_assign(other.max_content);
|
||||||
|
@ -108,61 +116,68 @@ impl BoxContentSizes {
|
||||||
&self,
|
&self,
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
) -> (ContentSizes, Percentage) {
|
) -> (ContentSizes, Percentage) {
|
||||||
// FIXME: account for 'box-sizing'
|
let padding = style.padding();
|
||||||
let inline_size = style.box_size().inline;
|
let border = style.border_width();
|
||||||
|
let margin = style.margin();
|
||||||
|
|
||||||
|
let mut pbm_percentages = Percentage::zero();
|
||||||
|
let mut decompose = |x: LengthPercentage| {
|
||||||
|
pbm_percentages += x.to_percentage().unwrap_or_else(Zero::zero);
|
||||||
|
x.to_length().unwrap_or_else(Zero::zero)
|
||||||
|
};
|
||||||
|
let pb_lengths =
|
||||||
|
border.inline_sum() + decompose(padding.inline_start) + decompose(padding.inline_end);
|
||||||
|
let mut m_lengths = Length::zero();
|
||||||
|
if let Some(m) = margin.inline_start.non_auto() {
|
||||||
|
m_lengths += decompose(m)
|
||||||
|
}
|
||||||
|
if let Some(m) = margin.inline_end.non_auto() {
|
||||||
|
m_lengths += decompose(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
let box_sizing = style.get_position().box_sizing;
|
||||||
|
let inline_size = style
|
||||||
|
.box_size()
|
||||||
|
.inline
|
||||||
|
.non_auto()
|
||||||
|
// Percentages for 'width' are treated as 'auto'
|
||||||
|
.and_then(|lp| lp.to_length());
|
||||||
let min_inline_size = style
|
let min_inline_size = style
|
||||||
.min_box_size()
|
.min_box_size()
|
||||||
.inline
|
.inline
|
||||||
|
// Percentages for 'min-width' are treated as zero
|
||||||
.percentage_relative_to(Length::zero())
|
.percentage_relative_to(Length::zero())
|
||||||
|
// FIXME: 'auto' is not zero in Flexbox
|
||||||
.auto_is(Length::zero);
|
.auto_is(Length::zero);
|
||||||
let max_inline_size = match style.max_box_size().inline {
|
let max_inline_size = match style.max_box_size().inline {
|
||||||
MaxSize::None => None,
|
MaxSize::None => None,
|
||||||
|
// Percentages for 'max-width' are treated as 'none'
|
||||||
MaxSize::LengthPercentage(ref lp) => lp.to_length(),
|
MaxSize::LengthPercentage(ref lp) => lp.to_length(),
|
||||||
};
|
};
|
||||||
let clamp = |l: Length| l.clamp_between_extremums(min_inline_size, max_inline_size);
|
let clamp = |l: Length| l.clamp_between_extremums(min_inline_size, max_inline_size);
|
||||||
|
|
||||||
// Percentages for 'width' are treated as 'auto'
|
let border_box_sizes = match inline_size {
|
||||||
let inline_size = inline_size.map(|lp| lp.to_length());
|
Some(non_auto) => {
|
||||||
// The (inner) min/max-content are only used for 'auto'
|
let clamped = clamp(non_auto);
|
||||||
let mut outer = match inline_size.non_auto().flatten() {
|
let border_box_size = match box_sizing {
|
||||||
None => {
|
BoxSizing::ContentBox => clamped + pb_lengths,
|
||||||
let inner = self.expect_inline().clone();
|
BoxSizing::BorderBox => clamped,
|
||||||
|
};
|
||||||
ContentSizes {
|
ContentSizes {
|
||||||
min_content: clamp(inner.min_content),
|
min_content: border_box_size,
|
||||||
max_content: clamp(inner.max_content),
|
max_content: border_box_size,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Some(length) => {
|
None => self.expect_inline().map(|content_box_size| {
|
||||||
let length = clamp(length);
|
match box_sizing {
|
||||||
ContentSizes {
|
// Clamp to 'min-width' and 'max-width', which are sizing the…
|
||||||
min_content: length,
|
BoxSizing::ContentBox => clamp(content_box_size) + pb_lengths,
|
||||||
max_content: length,
|
BoxSizing::BorderBox => clamp(content_box_size + pb_lengths),
|
||||||
}
|
}
|
||||||
},
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut pbm_lengths = Length::zero();
|
let outer = border_box_sizes.map(|s| s + m_lengths);
|
||||||
let mut pbm_percentages = Percentage::zero();
|
|
||||||
let padding = style.padding();
|
|
||||||
let border = style.border_width();
|
|
||||||
let margin = style.margin();
|
|
||||||
pbm_lengths += border.inline_sum();
|
|
||||||
let mut add = |x: LengthPercentage| {
|
|
||||||
if let Some(l) = x.to_length() {
|
|
||||||
pbm_lengths += l;
|
|
||||||
}
|
|
||||||
if let Some(p) = x.to_percentage() {
|
|
||||||
pbm_percentages += p;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
add(padding.inline_start);
|
|
||||||
add(padding.inline_end);
|
|
||||||
margin.inline_start.non_auto().map(&mut add);
|
|
||||||
margin.inline_end.non_auto().map(&mut add);
|
|
||||||
|
|
||||||
outer.min_content += pbm_lengths;
|
|
||||||
outer.max_content += pbm_lengths;
|
|
||||||
|
|
||||||
(outer, pbm_percentages)
|
(outer, pbm_percentages)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,14 @@ use crate::ContainingBlock;
|
||||||
use style::computed_values::mix_blend_mode::T as ComputedMixBlendMode;
|
use style::computed_values::mix_blend_mode::T as ComputedMixBlendMode;
|
||||||
use style::computed_values::position::T as ComputedPosition;
|
use style::computed_values::position::T as ComputedPosition;
|
||||||
use style::computed_values::transform_style::T as ComputedTransformStyle;
|
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::properties::ComputedValues;
|
||||||
use style::values::computed::{Length, LengthOrAuto, LengthPercentage, LengthPercentageOrAuto};
|
use style::values::computed::{Length, LengthOrAuto, LengthPercentage, LengthPercentageOrAuto};
|
||||||
use style::values::computed::{NonNegativeLengthPercentage, Size};
|
use style::values::computed::{NonNegativeLengthPercentage, Size};
|
||||||
use style::values::generics::box_::Perspective;
|
use style::values::generics::box_::Perspective;
|
||||||
use style::values::generics::length::MaxSize;
|
use style::values::generics::length::MaxSize;
|
||||||
use style::values::specified::box_ as stylo;
|
use style::values::specified::box_ as stylo;
|
||||||
|
use style::Zero;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||||
pub(crate) enum Display {
|
pub(crate) enum Display {
|
||||||
|
@ -61,6 +63,21 @@ pub(crate) trait ComputedValuesExt {
|
||||||
fn box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto>;
|
fn box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto>;
|
||||||
fn min_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<MaxSize<LengthPercentage>>;
|
||||||
|
fn content_box_size(
|
||||||
|
&self,
|
||||||
|
containing_block: &ContainingBlock,
|
||||||
|
pbm: &PaddingBorderMargin,
|
||||||
|
) -> flow_relative::Vec2<LengthOrAuto>;
|
||||||
|
fn content_min_box_size(
|
||||||
|
&self,
|
||||||
|
containing_block: &ContainingBlock,
|
||||||
|
pbm: &PaddingBorderMargin,
|
||||||
|
) -> flow_relative::Vec2<LengthOrAuto>;
|
||||||
|
fn content_max_box_size(
|
||||||
|
&self,
|
||||||
|
containing_block: &ContainingBlock,
|
||||||
|
pbm: &PaddingBorderMargin,
|
||||||
|
) -> flow_relative::Vec2<Option<Length>>;
|
||||||
fn padding_border_margin(&self, containing_block: &ContainingBlock) -> PaddingBorderMargin;
|
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 border_width(&self) -> flow_relative::Sides<Length>;
|
||||||
|
@ -93,7 +110,6 @@ impl ComputedValuesExt for ComputedValues {
|
||||||
!a.is_auto() && !b.is_auto()
|
!a.is_auto() && !b.is_auto()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn box_offsets(&self) -> flow_relative::Sides<LengthPercentageOrAuto> {
|
fn box_offsets(&self) -> flow_relative::Sides<LengthPercentageOrAuto> {
|
||||||
let position = self.get_position();
|
let position = self.get_position();
|
||||||
flow_relative::Sides::from_physical(
|
flow_relative::Sides::from_physical(
|
||||||
|
@ -107,7 +123,6 @@ impl ComputedValuesExt for ComputedValues {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto> {
|
fn box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto> {
|
||||||
let position = self.get_position();
|
let position = self.get_position();
|
||||||
flow_relative::Vec2::from_physical_size(
|
flow_relative::Vec2::from_physical_size(
|
||||||
|
@ -119,7 +134,6 @@ impl ComputedValuesExt for ComputedValues {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn min_box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto> {
|
fn min_box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto> {
|
||||||
let position = self.get_position();
|
let position = self.get_position();
|
||||||
flow_relative::Vec2::from_physical_size(
|
flow_relative::Vec2::from_physical_size(
|
||||||
|
@ -131,7 +145,6 @@ impl ComputedValuesExt for ComputedValues {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn max_box_size(&self) -> flow_relative::Vec2<MaxSize<LengthPercentage>> {
|
fn max_box_size(&self) -> flow_relative::Vec2<MaxSize<LengthPercentage>> {
|
||||||
let unwrap = |max_size: MaxSize<NonNegativeLengthPercentage>| match max_size {
|
let unwrap = |max_size: MaxSize<NonNegativeLengthPercentage>| match max_size {
|
||||||
MaxSize::LengthPercentage(length) => MaxSize::LengthPercentage(length.0),
|
MaxSize::LengthPercentage(length) => MaxSize::LengthPercentage(length.0),
|
||||||
|
@ -147,6 +160,70 @@ impl ComputedValuesExt for ComputedValues {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn content_box_size(
|
||||||
|
&self,
|
||||||
|
containing_block: &ContainingBlock,
|
||||||
|
pbm: &PaddingBorderMargin,
|
||||||
|
) -> flow_relative::Vec2<LengthOrAuto> {
|
||||||
|
let box_size = self.box_size().percentages_relative_to(containing_block);
|
||||||
|
match self.get_position().box_sizing {
|
||||||
|
BoxSizing::ContentBox => box_size,
|
||||||
|
BoxSizing::BorderBox => flow_relative::Vec2 {
|
||||||
|
// These may be negative, but will later be clamped by `min-width`/`min-height`
|
||||||
|
// which is clamped to zero.
|
||||||
|
inline: box_size.inline.map(|i| i - pbm.padding_border_sums.inline),
|
||||||
|
block: box_size.block.map(|b| b - pbm.padding_border_sums.block),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn content_min_box_size(
|
||||||
|
&self,
|
||||||
|
containing_block: &ContainingBlock,
|
||||||
|
pbm: &PaddingBorderMargin,
|
||||||
|
) -> flow_relative::Vec2<LengthOrAuto> {
|
||||||
|
let min_box_size = self
|
||||||
|
.min_box_size()
|
||||||
|
.percentages_relative_to(containing_block);
|
||||||
|
match self.get_position().box_sizing {
|
||||||
|
BoxSizing::ContentBox => min_box_size,
|
||||||
|
BoxSizing::BorderBox => flow_relative::Vec2 {
|
||||||
|
// Clamp to zero to make sure the used size components are non-negative
|
||||||
|
inline: min_box_size
|
||||||
|
.inline
|
||||||
|
.map(|i| (i - pbm.padding_border_sums.inline).max(Length::zero())),
|
||||||
|
block: min_box_size
|
||||||
|
.block
|
||||||
|
.map(|b| (b - pbm.padding_border_sums.block).max(Length::zero())),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn content_max_box_size(
|
||||||
|
&self,
|
||||||
|
containing_block: &ContainingBlock,
|
||||||
|
pbm: &PaddingBorderMargin,
|
||||||
|
) -> flow_relative::Vec2<Option<Length>> {
|
||||||
|
let max_box_size = self
|
||||||
|
.max_box_size()
|
||||||
|
.percentages_relative_to(containing_block);
|
||||||
|
match self.get_position().box_sizing {
|
||||||
|
BoxSizing::ContentBox => max_box_size,
|
||||||
|
BoxSizing::BorderBox => {
|
||||||
|
// This may be negative, but will later be clamped by `min-width`
|
||||||
|
// which itself is clamped to zero.
|
||||||
|
flow_relative::Vec2 {
|
||||||
|
inline: max_box_size
|
||||||
|
.inline
|
||||||
|
.map(|i| i - pbm.padding_border_sums.inline),
|
||||||
|
block: max_box_size
|
||||||
|
.block
|
||||||
|
.map(|b| b - pbm.padding_border_sums.block),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn padding_border_margin(&self, containing_block: &ContainingBlock) -> PaddingBorderMargin {
|
fn padding_border_margin(&self, containing_block: &ContainingBlock) -> PaddingBorderMargin {
|
||||||
let cbis = containing_block.inline_size;
|
let cbis = containing_block.inline_size;
|
||||||
let padding = self.padding().percentages_relative_to(cbis);
|
let padding = self.padding().percentages_relative_to(cbis);
|
||||||
|
@ -313,9 +390,7 @@ impl From<stylo::Display> for Display {
|
||||||
|
|
||||||
fn size_to_length(size: Size) -> LengthPercentageOrAuto {
|
fn size_to_length(size: Size) -> LengthPercentageOrAuto {
|
||||||
match size {
|
match size {
|
||||||
Size::LengthPercentage(length) => {
|
Size::LengthPercentage(length) => LengthPercentageOrAuto::LengthPercentage(length.0),
|
||||||
LengthPercentageOrAuto::LengthPercentage(length.0.clone())
|
|
||||||
},
|
|
||||||
Size::Auto => LengthPercentageOrAuto::Auto,
|
Size::Auto => LengthPercentageOrAuto::Auto,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -313,7 +313,6 @@ ${helpers.single_keyword(
|
||||||
"box-sizing",
|
"box-sizing",
|
||||||
"content-box border-box",
|
"content-box border-box",
|
||||||
engines="gecko servo-2013 servo-2020",
|
engines="gecko servo-2013 servo-2020",
|
||||||
servo_2020_pref="layout.2020.unimplemented",
|
|
||||||
extra_prefixes="moz:layout.css.prefixes.box-sizing webkit",
|
extra_prefixes="moz:layout.css.prefixes.box-sizing webkit",
|
||||||
spec="https://drafts.csswg.org/css-ui/#propdef-box-sizing",
|
spec="https://drafts.csswg.org/css-ui/#propdef-box-sizing",
|
||||||
gecko_enum_prefix="StyleBoxSizing",
|
gecko_enum_prefix="StyleBoxSizing",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue