mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Auto merge of #6903 - glennw:fix-height-again, r=pcwalton
Fix percentage height calculation, absolute containing block height calculations. It's not possible to correctly determine during the css cascade whether the container height is explicitly specified. Additionally, the spec https://drafts.csswg.org/css2/visudet.html#the-height-property says this should affect the *used* height, rather than the computed height. This significantly improves the layout in #6643. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/6903) <!-- Reviewable:end -->
This commit is contained in:
commit
028707f5cd
10 changed files with 151 additions and 119 deletions
|
@ -699,7 +699,7 @@ impl BlockFlow {
|
||||||
/// Right now, this only gets the containing block size for absolutely positioned elements.
|
/// Right now, this only gets the containing block size for absolutely positioned elements.
|
||||||
/// Note: We assume this is called in a top-down traversal, so it is ok to reference the CB.
|
/// Note: We assume this is called in a top-down traversal, so it is ok to reference the CB.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn containing_block_size(&mut self, viewport_size: &Size2D<Au>, descendant: OpaqueFlow)
|
pub fn containing_block_size(&self, viewport_size: &Size2D<Au>, descendant: OpaqueFlow)
|
||||||
-> LogicalSize<Au> {
|
-> LogicalSize<Au> {
|
||||||
debug_assert!(self.base.flags.contains(IS_ABSOLUTELY_POSITIONED));
|
debug_assert!(self.base.flags.contains(IS_ABSOLUTELY_POSITIONED));
|
||||||
if self.is_fixed() {
|
if self.is_fixed() {
|
||||||
|
@ -929,6 +929,7 @@ impl BlockFlow {
|
||||||
let (collapsible_margins, delta) =
|
let (collapsible_margins, delta) =
|
||||||
margin_collapse_info.finish_and_compute_collapsible_margins(
|
margin_collapse_info.finish_and_compute_collapsible_margins(
|
||||||
&self.fragment,
|
&self.fragment,
|
||||||
|
self.base.block_container_explicit_block_size,
|
||||||
can_collapse_block_end_margin_with_kids);
|
can_collapse_block_end_margin_with_kids);
|
||||||
self.base.collapsible_margins = collapsible_margins;
|
self.base.collapsible_margins = collapsible_margins;
|
||||||
translate_including_floats(&mut cur_b, delta, &mut floats);
|
translate_including_floats(&mut cur_b, delta, &mut floats);
|
||||||
|
@ -1095,14 +1096,69 @@ impl BlockFlow {
|
||||||
self.base.position.size);
|
self.base.position.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn explicit_block_containing_size(&self, layout_context: &LayoutContext) -> Option<Au> {
|
||||||
|
if self.is_root() || self.is_fixed() {
|
||||||
|
let screen_size = LogicalSize::from_physical(self.fragment.style.writing_mode,
|
||||||
|
layout_context.shared.screen_size);
|
||||||
|
Some(screen_size.block)
|
||||||
|
} else if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||||
|
self.base.absolute_cb.explicit_block_containing_size(layout_context)
|
||||||
|
} else {
|
||||||
|
self.base.block_container_explicit_block_size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn explicit_block_size(&self, containing_block_size: Option<Au>) -> Option<Au> {
|
||||||
|
let content_block_size = self.fragment.style().content_block_size();
|
||||||
|
|
||||||
|
match (content_block_size, containing_block_size) {
|
||||||
|
(LengthOrPercentageOrAuto::Length(length), _) => Some(length),
|
||||||
|
(LengthOrPercentageOrAuto::Percentage(percent), Some(container_size)) => {
|
||||||
|
Some(container_size.scale_by(percent))
|
||||||
|
}
|
||||||
|
(LengthOrPercentageOrAuto::Percentage(_), None) => {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
(LengthOrPercentageOrAuto::Auto, None) => {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
(LengthOrPercentageOrAuto::Auto, Some(container_size)) => {
|
||||||
|
let (block_start, block_end) = {
|
||||||
|
let position = self.fragment.style().logical_position();
|
||||||
|
(MaybeAuto::from_style(position.block_start, container_size),
|
||||||
|
MaybeAuto::from_style(position.block_end, container_size))
|
||||||
|
};
|
||||||
|
|
||||||
|
match (block_start, block_end) {
|
||||||
|
(MaybeAuto::Specified(block_start), MaybeAuto::Specified(block_end)) => {
|
||||||
|
let available_block_size = container_size - self.fragment.border_padding.block_start_end();
|
||||||
|
|
||||||
|
// Non-auto margin-block-start and margin-block-end values have already been
|
||||||
|
// calculated during assign-inline-size.
|
||||||
|
let margin = self.fragment.style().logical_margin();
|
||||||
|
let margin_block_start = match margin.block_start {
|
||||||
|
LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto,
|
||||||
|
_ => MaybeAuto::Specified(self.fragment.margin.block_start)
|
||||||
|
};
|
||||||
|
let margin_block_end = match margin.block_end {
|
||||||
|
LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto,
|
||||||
|
_ => MaybeAuto::Specified(self.fragment.margin.block_end)
|
||||||
|
};
|
||||||
|
|
||||||
|
let margin_block_start = margin_block_start.specified_or_zero();
|
||||||
|
let margin_block_end = margin_block_end.specified_or_zero();
|
||||||
|
let sum = block_start + block_end + margin_block_start + margin_block_end;
|
||||||
|
Some(available_block_size - sum)
|
||||||
|
}
|
||||||
|
|
||||||
|
(_, _) => {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Calculate and set the block-size, offsets, etc. for absolutely positioned flow.
|
|
||||||
///
|
|
||||||
/// The layout for its in-flow children has been done during normal layout.
|
|
||||||
/// This is just the calculation of:
|
|
||||||
/// + block-size for the flow
|
|
||||||
/// + position in the block direction of the flow with respect to its Containing Block.
|
|
||||||
/// + block-size, vertical margins, and y-coordinate for the flow's box.
|
|
||||||
fn calculate_absolute_block_size_and_margins(&mut self, layout_context: &LayoutContext) {
|
fn calculate_absolute_block_size_and_margins(&mut self, layout_context: &LayoutContext) {
|
||||||
let opaque_self = OpaqueFlow::from_flow(self);
|
let opaque_self = OpaqueFlow::from_flow(self);
|
||||||
let containing_block_block_size =
|
let containing_block_block_size =
|
||||||
|
@ -1140,7 +1196,7 @@ impl BlockFlow {
|
||||||
// Calculate used value of block-size just like we do for inline replaced elements.
|
// Calculate used value of block-size just like we do for inline replaced elements.
|
||||||
// TODO: Pass in the containing block block-size when Fragment's
|
// TODO: Pass in the containing block block-size when Fragment's
|
||||||
// assign-block-size can handle it correctly.
|
// assign-block-size can handle it correctly.
|
||||||
self.fragment.assign_replaced_block_size_if_necessary(containing_block_block_size);
|
self.fragment.assign_replaced_block_size_if_necessary(Some(containing_block_block_size));
|
||||||
// TODO: Right now, this content block-size value includes the
|
// TODO: Right now, this content block-size value includes the
|
||||||
// margin because of erroneous block-size calculation in fragment.
|
// margin because of erroneous block-size calculation in fragment.
|
||||||
// Check this when that has been fixed.
|
// Check this when that has been fixed.
|
||||||
|
@ -1248,28 +1304,13 @@ impl BlockFlow {
|
||||||
inline_size_of_preceding_right_floats = self.inline_size_of_preceding_right_floats;
|
inline_size_of_preceding_right_floats = self.inline_size_of_preceding_right_floats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let opaque_self = OpaqueFlow::from_flow(self);
|
||||||
|
|
||||||
// Calculate non-auto block size to pass to children.
|
// Calculate non-auto block size to pass to children.
|
||||||
let content_block_size = self.fragment.style().content_block_size();
|
let parent_container_size = self.explicit_block_containing_size(layout_context);
|
||||||
|
let explicit_content_size = self.explicit_block_size(parent_container_size);
|
||||||
let parent_container_size = if self.is_root() {
|
|
||||||
let screen_size = LogicalSize::from_physical(self.fragment.style.writing_mode,
|
|
||||||
layout_context.shared.screen_size);
|
|
||||||
Some(screen_size.block)
|
|
||||||
} else {
|
|
||||||
self.base.block_container_explicit_block_size
|
|
||||||
};
|
|
||||||
|
|
||||||
let explicit_content_size = match (content_block_size, parent_container_size) {
|
|
||||||
(LengthOrPercentageOrAuto::Percentage(percent), Some(container_size)) => {
|
|
||||||
Some(container_size.scale_by(percent))
|
|
||||||
}
|
|
||||||
(LengthOrPercentageOrAuto::Percentage(_), None) |
|
|
||||||
(LengthOrPercentageOrAuto::Auto, _) => None,
|
|
||||||
(LengthOrPercentageOrAuto::Length(length), _) => Some(length),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Calculate containing block inline size.
|
// Calculate containing block inline size.
|
||||||
let opaque_self = OpaqueFlow::from_flow(self);
|
|
||||||
let containing_block_size = if flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
let containing_block_size = if flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||||
self.containing_block_size(&layout_context.shared.screen_size, opaque_self).inline
|
self.containing_block_size(&layout_context.shared.screen_size, opaque_self).inline
|
||||||
} else {
|
} else {
|
||||||
|
@ -1286,8 +1327,10 @@ impl BlockFlow {
|
||||||
while let Some((i, kid)) = iterator.next() {
|
while let Some((i, kid)) = iterator.next() {
|
||||||
{
|
{
|
||||||
let kid_base = flow::mut_base(kid);
|
let kid_base = flow::mut_base(kid);
|
||||||
|
if !kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||||
kid_base.block_container_explicit_block_size = explicit_content_size;
|
kid_base.block_container_explicit_block_size = explicit_content_size;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Determine float impaction, and update the inline size speculations if necessary.
|
// Determine float impaction, and update the inline size speculations if necessary.
|
||||||
if flow::base(kid).flags.contains(CLEARS_LEFT) {
|
if flow::base(kid).flags.contains(CLEARS_LEFT) {
|
||||||
|
@ -1675,7 +1718,7 @@ impl Flow for BlockFlow {
|
||||||
|
|
||||||
// Assign block-size for fragment if it is an image fragment.
|
// Assign block-size for fragment if it is an image fragment.
|
||||||
let containing_block_block_size =
|
let containing_block_block_size =
|
||||||
self.base.block_container_explicit_block_size.unwrap_or(Au(0));
|
self.base.block_container_explicit_block_size;
|
||||||
self.fragment.assign_replaced_block_size_if_necessary(containing_block_block_size);
|
self.fragment.assign_replaced_block_size_if_necessary(containing_block_block_size);
|
||||||
if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||||
self.base.position.size.block = self.fragment.border_box.size.block;
|
self.base.position.size.block = self.fragment.border_box.size.block;
|
||||||
|
|
|
@ -1389,7 +1389,7 @@ impl ContainingBlockLink {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn generated_containing_block_size(&mut self, for_flow: OpaqueFlow) -> LogicalSize<Au> {
|
pub fn generated_containing_block_size(&self, for_flow: OpaqueFlow) -> LogicalSize<Au> {
|
||||||
match self.link {
|
match self.link {
|
||||||
None => {
|
None => {
|
||||||
panic!("Link to containing block not established; perhaps you forgot to call \
|
panic!("Link to containing block not established; perhaps you forgot to call \
|
||||||
|
@ -1398,6 +1398,24 @@ impl ContainingBlockLink {
|
||||||
Some(ref link) => link.upgrade().unwrap().generated_containing_block_size(for_flow),
|
Some(ref link) => link.upgrade().unwrap().generated_containing_block_size(for_flow),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn explicit_block_containing_size(&self, layout_context: &LayoutContext) -> Option<Au> {
|
||||||
|
match self.link {
|
||||||
|
None => {
|
||||||
|
panic!("Link to containing block not established; perhaps you forgot to call \
|
||||||
|
`set_absolute_descendants`?")
|
||||||
|
}
|
||||||
|
Some(ref link) => {
|
||||||
|
let flow = link.upgrade().unwrap();
|
||||||
|
if flow.is_block_like() {
|
||||||
|
flow.as_immutable_block().explicit_block_containing_size(layout_context)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wrapper for the pointer address of a flow. These pointer addresses may only be compared for
|
/// A wrapper for the pointer address of a flow. These pointer addresses may only be compared for
|
||||||
|
|
|
@ -216,10 +216,10 @@ impl fmt::Debug for SpecificFragmentInfo {
|
||||||
fn clamp_size(size: Au,
|
fn clamp_size(size: Au,
|
||||||
min_size: LengthOrPercentage,
|
min_size: LengthOrPercentage,
|
||||||
max_size: LengthOrPercentageOrNone,
|
max_size: LengthOrPercentageOrNone,
|
||||||
container_inline_size: Au)
|
container_size: Au)
|
||||||
-> Au {
|
-> Au {
|
||||||
let min_size = model::specified(min_size, container_inline_size);
|
let min_size = model::specified(min_size, container_size);
|
||||||
let max_size = model::specified_or_none(max_size, container_inline_size);
|
let max_size = model::specified_or_none(max_size, container_size);
|
||||||
|
|
||||||
max(min_size, match max_size {
|
max(min_size, match max_size {
|
||||||
None => size,
|
None => size,
|
||||||
|
@ -442,11 +442,15 @@ impl ReplacedImageFragmentInfo {
|
||||||
// `style_length`: inline-size as given in the CSS
|
// `style_length`: inline-size as given in the CSS
|
||||||
pub fn style_length(style_length: LengthOrPercentageOrAuto,
|
pub fn style_length(style_length: LengthOrPercentageOrAuto,
|
||||||
dom_length: Option<Au>,
|
dom_length: Option<Au>,
|
||||||
container_inline_size: Au) -> MaybeAuto {
|
container_size: Option<Au>) -> MaybeAuto {
|
||||||
match (MaybeAuto::from_style(style_length,container_inline_size), dom_length) {
|
match (style_length, dom_length, container_size) {
|
||||||
(MaybeAuto::Specified(length), _) => MaybeAuto::Specified(length),
|
(LengthOrPercentageOrAuto::Length(length), _, _) => MaybeAuto::Specified(length),
|
||||||
(MaybeAuto::Auto, Some(length)) => MaybeAuto::Specified(length),
|
(LengthOrPercentageOrAuto::Percentage(pc), _, Some(container_size)) => {
|
||||||
(MaybeAuto::Auto, None) => MaybeAuto::Auto,
|
MaybeAuto::Specified(container_size.scale_by(pc))
|
||||||
|
}
|
||||||
|
(LengthOrPercentageOrAuto::Percentage(_), _, None) => MaybeAuto::Auto,
|
||||||
|
(LengthOrPercentageOrAuto::Auto, Some(dom_length), _) => MaybeAuto::Specified(dom_length),
|
||||||
|
(LengthOrPercentageOrAuto::Auto, None, _) => MaybeAuto::Auto,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,7 +472,7 @@ impl ReplacedImageFragmentInfo {
|
||||||
let inline_size = ReplacedImageFragmentInfo::style_length(
|
let inline_size = ReplacedImageFragmentInfo::style_length(
|
||||||
style_inline_size,
|
style_inline_size,
|
||||||
self.dom_inline_size,
|
self.dom_inline_size,
|
||||||
container_inline_size);
|
Some(container_inline_size));
|
||||||
|
|
||||||
let inline_size = match inline_size {
|
let inline_size = match inline_size {
|
||||||
MaybeAuto::Auto => {
|
MaybeAuto::Auto => {
|
||||||
|
@ -483,7 +487,7 @@ impl ReplacedImageFragmentInfo {
|
||||||
let specified_height = ReplacedImageFragmentInfo::style_length(
|
let specified_height = ReplacedImageFragmentInfo::style_length(
|
||||||
style_block_size,
|
style_block_size,
|
||||||
self.dom_block_size,
|
self.dom_block_size,
|
||||||
Au(0));
|
None);
|
||||||
let specified_height = match specified_height {
|
let specified_height = match specified_height {
|
||||||
MaybeAuto::Auto => intrinsic_height,
|
MaybeAuto::Auto => intrinsic_height,
|
||||||
MaybeAuto::Specified(h) => h,
|
MaybeAuto::Specified(h) => h,
|
||||||
|
@ -510,7 +514,7 @@ impl ReplacedImageFragmentInfo {
|
||||||
pub fn calculate_replaced_block_size(&mut self,
|
pub fn calculate_replaced_block_size(&mut self,
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
noncontent_block_size: Au,
|
noncontent_block_size: Au,
|
||||||
containing_block_block_size: Au,
|
containing_block_block_size: Option<Au>,
|
||||||
fragment_inline_size: Au,
|
fragment_inline_size: Au,
|
||||||
fragment_block_size: Au)
|
fragment_block_size: Au)
|
||||||
-> Au {
|
-> Au {
|
||||||
|
@ -574,12 +578,12 @@ impl IframeFragmentInfo {
|
||||||
IframeFragmentInfo::calculate_replaced_size(style.content_inline_size(),
|
IframeFragmentInfo::calculate_replaced_size(style.content_inline_size(),
|
||||||
style.min_inline_size(),
|
style.min_inline_size(),
|
||||||
style.max_inline_size(),
|
style.max_inline_size(),
|
||||||
containing_size,
|
Some(containing_size),
|
||||||
Au::from_px(300))
|
Au::from_px(300))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn calculate_replaced_block_size(&self, style: &ComputedValues, containing_size: Au)
|
pub fn calculate_replaced_block_size(&self, style: &ComputedValues, containing_size: Option<Au>)
|
||||||
-> Au {
|
-> Au {
|
||||||
// Calculate the replaced block size (or default) as per CSS 2.1 § 10.3.2
|
// Calculate the replaced block size (or default) as per CSS 2.1 § 10.3.2
|
||||||
IframeFragmentInfo::calculate_replaced_size(style.content_block_size(),
|
IframeFragmentInfo::calculate_replaced_size(style.content_block_size(),
|
||||||
|
@ -593,13 +597,16 @@ impl IframeFragmentInfo {
|
||||||
fn calculate_replaced_size(content_size: LengthOrPercentageOrAuto,
|
fn calculate_replaced_size(content_size: LengthOrPercentageOrAuto,
|
||||||
style_min_size: LengthOrPercentage,
|
style_min_size: LengthOrPercentage,
|
||||||
style_max_size: LengthOrPercentageOrNone,
|
style_max_size: LengthOrPercentageOrNone,
|
||||||
containing_size: Au,
|
containing_size: Option<Au>,
|
||||||
default_size: Au) -> Au {
|
default_size: Au) -> Au {
|
||||||
let computed_size = match MaybeAuto::from_style(content_size, containing_size) {
|
let computed_size = match (content_size, containing_size) {
|
||||||
MaybeAuto::Specified(length) => length,
|
(LengthOrPercentageOrAuto::Length(length), _) => length,
|
||||||
MaybeAuto::Auto => default_size,
|
(LengthOrPercentageOrAuto::Percentage(pc), Some(container_size)) => container_size.scale_by(pc),
|
||||||
|
(LengthOrPercentageOrAuto::Percentage(_), None) => default_size,
|
||||||
|
(LengthOrPercentageOrAuto::Auto, _) => default_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let containing_size = containing_size.unwrap_or(Au(0));
|
||||||
let size = clamp_size(computed_size,
|
let size = clamp_size(computed_size,
|
||||||
style_min_size,
|
style_min_size,
|
||||||
style_max_size,
|
style_max_size,
|
||||||
|
@ -1714,7 +1721,7 @@ impl Fragment {
|
||||||
/// been assigned first.
|
/// been assigned first.
|
||||||
///
|
///
|
||||||
/// Ideally, this should follow CSS 2.1 § 10.6.2.
|
/// Ideally, this should follow CSS 2.1 § 10.6.2.
|
||||||
pub fn assign_replaced_block_size_if_necessary(&mut self, containing_block_block_size: Au) {
|
pub fn assign_replaced_block_size_if_necessary(&mut self, containing_block_block_size: Option<Au>) {
|
||||||
match self.specific {
|
match self.specific {
|
||||||
SpecificFragmentInfo::Generic |
|
SpecificFragmentInfo::Generic |
|
||||||
SpecificFragmentInfo::GeneratedContent(_) |
|
SpecificFragmentInfo::GeneratedContent(_) |
|
||||||
|
|
|
@ -1346,7 +1346,7 @@ impl Flow for InlineFlow {
|
||||||
|
|
||||||
// Assign the block-size and late-computed inline-sizes for the inline fragments.
|
// Assign the block-size and late-computed inline-sizes for the inline fragments.
|
||||||
let containing_block_block_size =
|
let containing_block_block_size =
|
||||||
self.base.block_container_explicit_block_size.unwrap_or(Au(0));
|
self.base.block_container_explicit_block_size;
|
||||||
for fragment in self.fragments.fragments.iter_mut() {
|
for fragment in self.fragments.fragments.iter_mut() {
|
||||||
fragment.update_late_computed_replaced_inline_size_if_necessary();
|
fragment.update_late_computed_replaced_inline_size_if_necessary();
|
||||||
fragment.assign_replaced_block_size_if_necessary(
|
fragment.assign_replaced_block_size_if_necessary(
|
||||||
|
|
|
@ -106,7 +106,7 @@ impl Flow for ListItemFlow {
|
||||||
|
|
||||||
if let Some(ref mut marker) = self.marker {
|
if let Some(ref mut marker) = self.marker {
|
||||||
let containing_block_block_size =
|
let containing_block_block_size =
|
||||||
self.block_flow.base.block_container_explicit_block_size.unwrap_or(Au(0));
|
self.block_flow.base.block_container_explicit_block_size;
|
||||||
marker.assign_replaced_block_size_if_necessary(containing_block_block_size);
|
marker.assign_replaced_block_size_if_necessary(containing_block_block_size);
|
||||||
|
|
||||||
let font_metrics =
|
let font_metrics =
|
||||||
|
|
|
@ -126,13 +126,20 @@ impl MarginCollapseInfo {
|
||||||
|
|
||||||
pub fn finish_and_compute_collapsible_margins(mut self,
|
pub fn finish_and_compute_collapsible_margins(mut self,
|
||||||
fragment: &Fragment,
|
fragment: &Fragment,
|
||||||
|
containing_block_size: Option<Au>,
|
||||||
can_collapse_block_end_margin_with_kids: bool)
|
can_collapse_block_end_margin_with_kids: bool)
|
||||||
-> (CollapsibleMargins, Au) {
|
-> (CollapsibleMargins, Au) {
|
||||||
let state = match self.state {
|
let state = match self.state {
|
||||||
MarginCollapseState::AccumulatingCollapsibleTopMargin => {
|
MarginCollapseState::AccumulatingCollapsibleTopMargin => {
|
||||||
match fragment.style().content_block_size() {
|
let may_collapse_through = match fragment.style().content_block_size() {
|
||||||
LengthOrPercentageOrAuto::Auto | LengthOrPercentageOrAuto::Length(Au(0)) |
|
LengthOrPercentageOrAuto::Auto => true,
|
||||||
LengthOrPercentageOrAuto::Percentage(0.) => {
|
LengthOrPercentageOrAuto::Length(Au(0)) => true,
|
||||||
|
LengthOrPercentageOrAuto::Percentage(0.) => true,
|
||||||
|
LengthOrPercentageOrAuto::Percentage(_) if containing_block_size.is_none() => true,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if may_collapse_through {
|
||||||
match fragment.style().min_block_size() {
|
match fragment.style().min_block_size() {
|
||||||
LengthOrPercentage::Length(Au(0)) | LengthOrPercentage::Percentage(0.) => {
|
LengthOrPercentage::Length(Au(0)) | LengthOrPercentage::Percentage(0.) => {
|
||||||
FinalMarginState::MarginsCollapseThrough
|
FinalMarginState::MarginsCollapseThrough
|
||||||
|
@ -143,14 +150,12 @@ impl MarginCollapseInfo {
|
||||||
FinalMarginState::BottomMarginCollapses
|
FinalMarginState::BottomMarginCollapses
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
} else {
|
||||||
_ => {
|
|
||||||
// If the fragment has an explicitly specified block-size, margins may not
|
// If the fragment has an explicitly specified block-size, margins may not
|
||||||
// collapse through it.
|
// collapse through it.
|
||||||
FinalMarginState::BottomMarginCollapses
|
FinalMarginState::BottomMarginCollapses
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
MarginCollapseState::AccumulatingMarginIn => FinalMarginState::BottomMarginCollapses,
|
MarginCollapseState::AccumulatingMarginIn => FinalMarginState::BottomMarginCollapses,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -390,15 +390,15 @@ impl RawLayoutElementHelpers for Element {
|
||||||
match height {
|
match height {
|
||||||
LengthOrPercentageOrAuto::Auto => {}
|
LengthOrPercentageOrAuto::Auto => {}
|
||||||
LengthOrPercentageOrAuto::Percentage(percentage) => {
|
LengthOrPercentageOrAuto::Percentage(percentage) => {
|
||||||
let width_value = specified::LengthOrPercentageOrAuto::Percentage(percentage);
|
let height_value = specified::LengthOrPercentageOrAuto::Percentage(percentage);
|
||||||
hints.push(from_declaration(PropertyDeclaration::Height(SpecifiedValue(
|
hints.push(from_declaration(
|
||||||
height::SpecifiedValue(width_value)))));
|
PropertyDeclaration::Height(SpecifiedValue(height_value))));
|
||||||
}
|
}
|
||||||
LengthOrPercentageOrAuto::Length(length) => {
|
LengthOrPercentageOrAuto::Length(length) => {
|
||||||
let width_value = specified::LengthOrPercentageOrAuto::Length(
|
let height_value = specified::LengthOrPercentageOrAuto::Length(
|
||||||
specified::Length::Absolute(length));
|
specified::Length::Absolute(length));
|
||||||
hints.push(from_declaration(PropertyDeclaration::Height(SpecifiedValue(
|
hints.push(from_declaration(
|
||||||
height::SpecifiedValue(width_value)))));
|
PropertyDeclaration::Height(SpecifiedValue(height_value))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,8 +443,7 @@ impl RawLayoutElementHelpers for Element {
|
||||||
let value = specified::Length::FontRelative(specified::FontRelativeLength::Em(rows as CSSFloat));
|
let value = specified::Length::FontRelative(specified::FontRelativeLength::Em(rows as CSSFloat));
|
||||||
hints.push(from_declaration(
|
hints.push(from_declaration(
|
||||||
PropertyDeclaration::Height(SpecifiedValue(
|
PropertyDeclaration::Height(SpecifiedValue(
|
||||||
longhands::height::SpecifiedValue(
|
specified::LengthOrPercentageOrAuto::Length(value)))));
|
||||||
specified::LengthOrPercentageOrAuto::Length(value))))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -534,45 +534,10 @@ pub mod longhands {
|
||||||
${predefined_type("width", "LengthOrPercentageOrAuto",
|
${predefined_type("width", "LengthOrPercentageOrAuto",
|
||||||
"computed::LengthOrPercentageOrAuto::Auto",
|
"computed::LengthOrPercentageOrAuto::Auto",
|
||||||
"parse_non_negative")}
|
"parse_non_negative")}
|
||||||
<%self:longhand name="height">
|
|
||||||
use values::computed::Context;
|
|
||||||
use cssparser::ToCss;
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
impl ToCss for SpecifiedValue {
|
${predefined_type("height", "LengthOrPercentageOrAuto",
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
"computed::LengthOrPercentageOrAuto::Auto",
|
||||||
self.0.to_css(dest)
|
"parse_non_negative")}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
|
||||||
pub struct SpecifiedValue(pub specified::LengthOrPercentageOrAuto);
|
|
||||||
pub mod computed_value {
|
|
||||||
pub use values::computed::LengthOrPercentageOrAuto as T;
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn get_initial_value() -> computed_value::T { computed::LengthOrPercentageOrAuto::Auto }
|
|
||||||
#[inline]
|
|
||||||
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
|
||||||
specified::LengthOrPercentageOrAuto::parse_non_negative(input).map(SpecifiedValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToComputedValue for SpecifiedValue {
|
|
||||||
type ComputedValue = computed_value::T;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn to_computed_value(&self, context: &Context) -> computed_value::T {
|
|
||||||
match (self.0, context.inherited_height) {
|
|
||||||
(specified::LengthOrPercentageOrAuto::Percentage(_),
|
|
||||||
computed::LengthOrPercentageOrAuto::Auto)
|
|
||||||
if !context.is_root_element && !context.positioned => {
|
|
||||||
computed::LengthOrPercentageOrAuto::Auto
|
|
||||||
},
|
|
||||||
_ => self.0.to_computed_value(context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</%self:longhand>
|
|
||||||
|
|
||||||
${predefined_type("min-width", "LengthOrPercentage",
|
${predefined_type("min-width", "LengthOrPercentage",
|
||||||
"computed::LengthOrPercentage::Length(Au(0))",
|
"computed::LengthOrPercentage::Length(Au(0))",
|
||||||
|
@ -6217,7 +6182,6 @@ pub fn cascade(viewport_size: Size2D<Au>,
|
||||||
viewport_size: viewport_size,
|
viewport_size: viewport_size,
|
||||||
inherited_font_weight: inherited_font_style.font_weight,
|
inherited_font_weight: inherited_font_style.font_weight,
|
||||||
inherited_font_size: inherited_font_style.font_size,
|
inherited_font_size: inherited_font_style.font_size,
|
||||||
inherited_height: inherited_style.get_box().height,
|
|
||||||
inherited_text_decorations_in_effect:
|
inherited_text_decorations_in_effect:
|
||||||
inherited_style.get_inheritedtext()._servo_text_decorations_in_effect,
|
inherited_style.get_inheritedtext()._servo_text_decorations_in_effect,
|
||||||
// To be overridden by applicable declarations:
|
// To be overridden by applicable declarations:
|
||||||
|
|
|
@ -873,7 +873,6 @@ pub mod computed {
|
||||||
pub inherited_font_size: longhands::font_size::computed_value::T,
|
pub inherited_font_size: longhands::font_size::computed_value::T,
|
||||||
pub inherited_text_decorations_in_effect:
|
pub inherited_text_decorations_in_effect:
|
||||||
longhands::_servo_text_decorations_in_effect::computed_value::T,
|
longhands::_servo_text_decorations_in_effect::computed_value::T,
|
||||||
pub inherited_height: longhands::height::computed_value::T,
|
|
||||||
pub color: longhands::color::computed_value::T,
|
pub color: longhands::color::computed_value::T,
|
||||||
pub text_decoration: longhands::text_decoration::computed_value::T,
|
pub text_decoration: longhands::text_decoration::computed_value::T,
|
||||||
pub font_size: longhands::font_size::computed_value::T,
|
pub font_size: longhands::font_size::computed_value::T,
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
[block-in-inline-percents-001.htm]
|
|
||||||
type: reftest
|
|
||||||
expected: FAIL
|
|
Loading…
Add table
Add a link
Reference in a new issue