mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
layout: Implement support for line-height
and vertical-align
(#30902)
* layout: Implement support for `line-height` and `vertical-align` This is an initial implementation of proper `line-height` and `vertical-align` support. While this change includes the bulk of the work there are still many missing pieces for full support. In particular some big missing things are: - Flex containers do not properly compute their baselines. The idea is to tackle this in a followup change. This causes various flex tests to start failing because everything used to be top aligned. - The implementation of the line-height quirks (only active in quirks mode) are incomplete. While the quirk works in many cases, there are still some cases where it is handled incorrectly. This requires more redesign and refinement, better suited for a followup. - Most of the features are CSS 3 such as precision control of the baseline and first and last baselines are not implemented. This change gets us close to CSS 2.x support. While there are many new test passes with this change some tests are starting to fail. An accounting of new failures: Tests failing also in Layout 2013: - /css/css2/positioning/toogle-abspos-on-relpos-inline-child.html (only passes in Chrome) - /css/CSS2/fonts/font-applies-to-001.xht (potentially an issue with font size) Invalid tests: - /css/CSS2/visudet/inline-block-baseline-003.xht - /css/CSS2/visudet/inline-block-baseline-004.xht - These are are failing in all browsers. See https://bugs.chromium.org/p/chromium/issues/detail?id=1222151. Missing table support: - /_mozilla/mozilla/table_valign_middle.html Missing `font-size-adjust` support : - /css/css-fonts/font-size-adjust-zero-2.html (also failing in 2013) Incomplete form field support : - /html/rendering/widgets/the-select-element/option-add-label-quirks.html (label isn't rendered so button isn't the right size in quirks mode due to line height quirk) Need support for calculating flexbox baseline: - /css/css-flexbox/fieldset-baseline-alignment.html - /css/css-flexbox/flex-inline.html - /css/css-flexbox/flexbox-baseline-multi-line-horiz-001.html - /css/css-flexbox/flexbox-baseline-single-item-001a.html - /css/css-flexbox/flexbox-baseline-single-item-001b.html Failing because we don't create anonymous inline boxes for text children of blocks: - /css/CSS2/linebox/anonymous-inline-inherit-001.html Passes locally (potentially related to fonts): - /css/CSS2/css1/c414-flt-fit-004.xht - /css/css-transforms/transform-input-017.html - /html/obsolete/requirements-for-implementations/the-marquee-element-0/marquee-min-intrinsic-size.html - /css/css-fonts/first-available-font-005.html - /css/css-fonts/first-available-font-006.html * Some cleanups after live review with @mukilan Also update results.
This commit is contained in:
parent
527119aebb
commit
aa073c3dca
148 changed files with 965 additions and 944 deletions
|
@ -121,6 +121,27 @@ pub struct FontMetrics {
|
||||||
pub line_gap: Au,
|
pub line_gap: Au,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FontMetrics {
|
||||||
|
/// Create an empty [`FontMetrics`] mainly to be used in situations where
|
||||||
|
/// no font can be found.
|
||||||
|
pub fn empty() -> Self {
|
||||||
|
Self {
|
||||||
|
underline_size: Au(0),
|
||||||
|
underline_offset: Au(0),
|
||||||
|
strikeout_size: Au(0),
|
||||||
|
strikeout_offset: Au(0),
|
||||||
|
leading: Au(0),
|
||||||
|
x_height: Au(0),
|
||||||
|
em_size: Au(0),
|
||||||
|
ascent: Au(0),
|
||||||
|
descent: Au(0),
|
||||||
|
max_advance: Au(0),
|
||||||
|
average_advance: Au(0),
|
||||||
|
line_gap: Au(0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// `FontDescriptor` describes the parameters of a `Font`. It represents rendering a given font
|
/// `FontDescriptor` describes the parameters of a `Font`. It represents rendering a given font
|
||||||
/// template at a particular size, with a particular font-variant-caps applied, etc. This contrasts
|
/// template at a particular size, with a particular font-variant-caps applied, etc. This contrasts
|
||||||
/// with `FontTemplateDescriptor` in that the latter represents only the parameters inherent in the
|
/// with `FontTemplateDescriptor` in that the latter represents only the parameters inherent in the
|
||||||
|
|
|
@ -763,7 +763,7 @@ fn rgba(color: AbsoluteColor) -> wr::ColorF {
|
||||||
|
|
||||||
fn glyphs(
|
fn glyphs(
|
||||||
glyph_runs: &[Arc<GlyphStore>],
|
glyph_runs: &[Arc<GlyphStore>],
|
||||||
mut origin: PhysicalPoint<Length>,
|
mut baseline_origin: PhysicalPoint<Length>,
|
||||||
justification_adjustment: Length,
|
justification_adjustment: Length,
|
||||||
) -> Vec<wr::GlyphInstance> {
|
) -> Vec<wr::GlyphInstance> {
|
||||||
use gfx_traits::ByteIndex;
|
use gfx_traits::ByteIndex;
|
||||||
|
@ -775,8 +775,8 @@ fn glyphs(
|
||||||
if !run.is_whitespace() {
|
if !run.is_whitespace() {
|
||||||
let glyph_offset = glyph.offset().unwrap_or(Point2D::zero());
|
let glyph_offset = glyph.offset().unwrap_or(Point2D::zero());
|
||||||
let point = units::LayoutPoint::new(
|
let point = units::LayoutPoint::new(
|
||||||
origin.x.px() + glyph_offset.x.to_f32_px(),
|
baseline_origin.x.px() + glyph_offset.x.to_f32_px(),
|
||||||
origin.y.px() + glyph_offset.y.to_f32_px(),
|
baseline_origin.y.px() + glyph_offset.y.to_f32_px(),
|
||||||
);
|
);
|
||||||
let glyph = wr::GlyphInstance {
|
let glyph = wr::GlyphInstance {
|
||||||
index: glyph.id(),
|
index: glyph.id(),
|
||||||
|
@ -786,9 +786,9 @@ fn glyphs(
|
||||||
}
|
}
|
||||||
|
|
||||||
if glyph.char_is_word_separator() {
|
if glyph.char_is_word_separator() {
|
||||||
origin.x += justification_adjustment;
|
baseline_origin.x += justification_adjustment;
|
||||||
}
|
}
|
||||||
origin.x += Length::from(glyph.advance());
|
baseline_origin.x += Length::from(glyph.advance());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glyphs
|
glyphs
|
||||||
|
|
|
@ -1242,7 +1242,7 @@ impl BoxFragment {
|
||||||
) -> Option<(ScrollTreeNodeId, wr::ClipChainId, LayoutSize)> {
|
) -> Option<(ScrollTreeNodeId, wr::ClipChainId, LayoutSize)> {
|
||||||
let overflow_x = self.style.get_box().overflow_x;
|
let overflow_x = self.style.get_box().overflow_x;
|
||||||
let overflow_y = self.style.get_box().overflow_y;
|
let overflow_y = self.style.get_box().overflow_y;
|
||||||
if overflow_x == ComputedOverflow::Visible && overflow_y == ComputedOverflow::Visible {
|
if !self.style.establishes_scroll_container() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -411,6 +411,7 @@ impl FlexContainer {
|
||||||
IndependentLayout {
|
IndependentLayout {
|
||||||
fragments,
|
fragments,
|
||||||
content_block_size,
|
content_block_size,
|
||||||
|
last_inflow_baseline_offset: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -855,7 +856,9 @@ impl FlexLine<'_> {
|
||||||
logical_slides(flex_context, item.padding),
|
logical_slides(flex_context, item.padding),
|
||||||
logical_slides(flex_context, item.border),
|
logical_slides(flex_context, item.border),
|
||||||
margin,
|
margin,
|
||||||
None,
|
None, /* clearance */
|
||||||
|
// TODO: We should likely propagate baselines from `display: flex`.
|
||||||
|
None, /* last_inflow_baseline_offset */
|
||||||
collapsed_margin,
|
collapsed_margin,
|
||||||
),
|
),
|
||||||
item_result.positioning_context,
|
item_result.positioning_context,
|
||||||
|
@ -1098,6 +1101,7 @@ impl<'a> FlexItem<'a> {
|
||||||
let IndependentLayout {
|
let IndependentLayout {
|
||||||
fragments,
|
fragments,
|
||||||
content_block_size,
|
content_block_size,
|
||||||
|
..
|
||||||
} = non_replaced.layout(
|
} = non_replaced.layout(
|
||||||
flex_context.layout_context,
|
flex_context.layout_context,
|
||||||
&mut positioning_context,
|
&mut positioning_context,
|
||||||
|
|
|
@ -965,6 +965,7 @@ impl FloatBox {
|
||||||
// Clearance is handled internally by the float placement logic, so there's no need
|
// Clearance is handled internally by the float placement logic, so there's no need
|
||||||
// to store it explicitly in the fragment.
|
// to store it explicitly in the fragment.
|
||||||
None, // clearance
|
None, // clearance
|
||||||
|
None, // last_inflow_baseline_offset
|
||||||
CollapsedBlockMargins::zero(),
|
CollapsedBlockMargins::zero(),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -195,6 +195,10 @@ struct FlowLayout {
|
||||||
pub fragments: Vec<Fragment>,
|
pub fragments: Vec<Fragment>,
|
||||||
pub content_block_size: Length,
|
pub content_block_size: Length,
|
||||||
pub collapsible_margins_in_children: CollapsedBlockMargins,
|
pub collapsible_margins_in_children: CollapsedBlockMargins,
|
||||||
|
/// The offset of the last inflow baseline in this layout in the content area, if
|
||||||
|
/// there was one. This is used to propagate inflow baselines to the ancestors
|
||||||
|
/// of `display: inline-block` elements.
|
||||||
|
pub last_inflow_baseline_offset: Option<Length>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
@ -238,6 +242,7 @@ impl BlockFormattingContext {
|
||||||
content_block_size: flow_layout.content_block_size +
|
content_block_size: flow_layout.content_block_size +
|
||||||
flow_layout.collapsible_margins_in_children.end.solve() +
|
flow_layout.collapsible_margins_in_children.end.solve() +
|
||||||
clearance.unwrap_or_else(Length::zero),
|
clearance.unwrap_or_else(Length::zero),
|
||||||
|
last_inflow_baseline_offset: flow_layout.last_inflow_baseline_offset,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -454,7 +459,7 @@ fn layout_block_level_children_in_parallel(
|
||||||
let fragments = layout_results
|
let fragments = layout_results
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(mut fragment, mut child_positioning_context)| {
|
.map(|(mut fragment, mut child_positioning_context)| {
|
||||||
placement_state.place_fragment(&mut fragment, None);
|
placement_state.place_fragment_and_update_baseline(&mut fragment, None);
|
||||||
child_positioning_context.adjust_static_position_of_hoisted_fragments(
|
child_positioning_context.adjust_static_position_of_hoisted_fragments(
|
||||||
&fragment,
|
&fragment,
|
||||||
PositioningContextLength::zero(),
|
PositioningContextLength::zero(),
|
||||||
|
@ -464,11 +469,13 @@ fn layout_block_level_children_in_parallel(
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let (content_block_size, collapsible_margins_in_children) = placement_state.finish();
|
let (content_block_size, collapsible_margins_in_children, baseline_offset) =
|
||||||
|
placement_state.finish();
|
||||||
FlowLayout {
|
FlowLayout {
|
||||||
fragments,
|
fragments,
|
||||||
content_block_size,
|
content_block_size,
|
||||||
collapsible_margins_in_children,
|
collapsible_margins_in_children,
|
||||||
|
last_inflow_baseline_offset: baseline_offset,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,7 +506,8 @@ fn layout_block_level_children_sequentially(
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
|
|
||||||
placement_state.place_fragment(&mut fragment, Some(sequential_layout_state));
|
placement_state
|
||||||
|
.place_fragment_and_update_baseline(&mut fragment, Some(sequential_layout_state));
|
||||||
positioning_context.adjust_static_position_of_hoisted_fragments(
|
positioning_context.adjust_static_position_of_hoisted_fragments(
|
||||||
&fragment,
|
&fragment,
|
||||||
positioning_context_length_before_layout,
|
positioning_context_length_before_layout,
|
||||||
|
@ -509,11 +517,13 @@ fn layout_block_level_children_sequentially(
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let (content_block_size, collapsible_margins_in_children) = placement_state.finish();
|
let (content_block_size, collapsible_margins_in_children, baseline_offset) =
|
||||||
|
placement_state.finish();
|
||||||
FlowLayout {
|
FlowLayout {
|
||||||
fragments,
|
fragments,
|
||||||
content_block_size,
|
content_block_size,
|
||||||
collapsible_margins_in_children,
|
collapsible_margins_in_children,
|
||||||
|
last_inflow_baseline_offset: baseline_offset,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -800,6 +810,7 @@ fn layout_in_flow_non_replaced_block_level_same_formatting_context(
|
||||||
pbm.border,
|
pbm.border,
|
||||||
margin,
|
margin,
|
||||||
clearance,
|
clearance,
|
||||||
|
flow_layout.last_inflow_baseline_offset,
|
||||||
block_margins_collapsed_with_children,
|
block_margins_collapsed_with_children,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -870,6 +881,7 @@ impl NonReplacedFormattingContext {
|
||||||
pbm.border,
|
pbm.border,
|
||||||
margin,
|
margin,
|
||||||
None, /* clearance */
|
None, /* clearance */
|
||||||
|
layout.last_inflow_baseline_offset,
|
||||||
block_margins_collapsed_with_children,
|
block_margins_collapsed_with_children,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1079,6 +1091,7 @@ impl NonReplacedFormattingContext {
|
||||||
pbm.border,
|
pbm.border,
|
||||||
margin,
|
margin,
|
||||||
clearance,
|
clearance,
|
||||||
|
layout.last_inflow_baseline_offset,
|
||||||
block_margins_collapsed_with_children,
|
block_margins_collapsed_with_children,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1175,6 +1188,7 @@ fn layout_in_flow_replaced_block_level<'a>(
|
||||||
pbm.border,
|
pbm.border,
|
||||||
margin,
|
margin,
|
||||||
clearance,
|
clearance,
|
||||||
|
None, /* last_inflow_base_offset */
|
||||||
block_margins_collapsed_with_children,
|
block_margins_collapsed_with_children,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1351,6 +1365,7 @@ struct PlacementState {
|
||||||
start_margin: CollapsedMargin,
|
start_margin: CollapsedMargin,
|
||||||
current_margin: CollapsedMargin,
|
current_margin: CollapsedMargin,
|
||||||
current_block_direction_position: Length,
|
current_block_direction_position: Length,
|
||||||
|
last_inflow_baseline_offset: Option<Length>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PlacementState {
|
impl PlacementState {
|
||||||
|
@ -1364,6 +1379,25 @@ impl PlacementState {
|
||||||
start_margin: CollapsedMargin::zero(),
|
start_margin: CollapsedMargin::zero(),
|
||||||
current_margin: CollapsedMargin::zero(),
|
current_margin: CollapsedMargin::zero(),
|
||||||
current_block_direction_position: Length::zero(),
|
current_block_direction_position: Length::zero(),
|
||||||
|
last_inflow_baseline_offset: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn place_fragment_and_update_baseline(
|
||||||
|
&mut self,
|
||||||
|
fragment: &mut Fragment,
|
||||||
|
sequential_layout_state: Option<&mut SequentialLayoutState>,
|
||||||
|
) {
|
||||||
|
self.place_fragment(fragment, sequential_layout_state);
|
||||||
|
|
||||||
|
match fragment {
|
||||||
|
Fragment::Box(box_fragment) => {
|
||||||
|
if let Some(baseline) = box_fragment.last_baseline_offset {
|
||||||
|
self.last_inflow_baseline_offset =
|
||||||
|
Some(baseline + box_fragment.content_rect.start_corner.block);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1453,7 +1487,7 @@ impl PlacementState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish(mut self) -> (Length, CollapsedBlockMargins) {
|
fn finish(mut self) -> (Length, CollapsedBlockMargins, Option<Length>) {
|
||||||
if !self.last_in_flow_margin_collapses_with_parent_end_margin {
|
if !self.last_in_flow_margin_collapses_with_parent_end_margin {
|
||||||
self.current_block_direction_position += self.current_margin.solve();
|
self.current_block_direction_position += self.current_margin.solve();
|
||||||
self.current_margin = CollapsedMargin::zero();
|
self.current_margin = CollapsedMargin::zero();
|
||||||
|
@ -1465,6 +1499,7 @@ impl PlacementState {
|
||||||
start: self.start_margin,
|
start: self.start_margin,
|
||||||
end: self.current_margin,
|
end: self.current_margin,
|
||||||
},
|
},
|
||||||
|
self.last_inflow_baseline_offset,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,11 @@ pub(crate) struct IndependentLayout {
|
||||||
|
|
||||||
/// https://drafts.csswg.org/css2/visudet.html#root-height
|
/// https://drafts.csswg.org/css2/visudet.html#root-height
|
||||||
pub content_block_size: Length,
|
pub content_block_size: Length,
|
||||||
|
|
||||||
|
/// The offset of the last inflow baseline of this layout in the content area, if
|
||||||
|
/// there was one. This is used to propagate baselines to the ancestors of `display:
|
||||||
|
/// inline-block`.
|
||||||
|
pub last_inflow_baseline_offset: Option<Length>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IndependentFormattingContext {
|
impl IndependentFormattingContext {
|
||||||
|
|
|
@ -17,6 +17,7 @@ use crate::geom::{
|
||||||
LengthOrAuto, LogicalRect, LogicalSides, PhysicalPoint, PhysicalRect, PhysicalSides,
|
LengthOrAuto, LogicalRect, LogicalSides, PhysicalPoint, PhysicalRect, PhysicalSides,
|
||||||
PhysicalSize,
|
PhysicalSize,
|
||||||
};
|
};
|
||||||
|
use crate::style_ext::ComputedValuesExt;
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub(crate) struct BoxFragment {
|
pub(crate) struct BoxFragment {
|
||||||
|
@ -43,6 +44,11 @@ pub(crate) struct BoxFragment {
|
||||||
/// https://drafts.csswg.org/css2/#clearance
|
/// https://drafts.csswg.org/css2/#clearance
|
||||||
pub clearance: Option<Length>,
|
pub clearance: Option<Length>,
|
||||||
|
|
||||||
|
/// When this box contains an inline formatting context, this tracks the baseline
|
||||||
|
/// offset of the last inflow line. This offset is used to propagate baselines to
|
||||||
|
/// ancestors of `display: inline-block` ancestors.
|
||||||
|
pub last_baseline_offset: Option<Length>,
|
||||||
|
|
||||||
pub block_margins_collapsed_with_children: CollapsedBlockMargins,
|
pub block_margins_collapsed_with_children: CollapsedBlockMargins,
|
||||||
|
|
||||||
/// The scrollable overflow of this box fragment.
|
/// The scrollable overflow of this box fragment.
|
||||||
|
@ -67,6 +73,7 @@ impl BoxFragment {
|
||||||
border: LogicalSides<Length>,
|
border: LogicalSides<Length>,
|
||||||
margin: LogicalSides<Length>,
|
margin: LogicalSides<Length>,
|
||||||
clearance: Option<Length>,
|
clearance: Option<Length>,
|
||||||
|
last_inflow_baseline_offset: Option<Length>,
|
||||||
block_margins_collapsed_with_children: CollapsedBlockMargins,
|
block_margins_collapsed_with_children: CollapsedBlockMargins,
|
||||||
) -> BoxFragment {
|
) -> BoxFragment {
|
||||||
let position = style.get_box().position;
|
let position = style.get_box().position;
|
||||||
|
@ -87,6 +94,7 @@ impl BoxFragment {
|
||||||
border,
|
border,
|
||||||
margin,
|
margin,
|
||||||
clearance,
|
clearance,
|
||||||
|
last_inflow_baseline_offset,
|
||||||
block_margins_collapsed_with_children,
|
block_margins_collapsed_with_children,
|
||||||
PhysicalSize::new(width_overconstrained, height_overconstrained),
|
PhysicalSize::new(width_overconstrained, height_overconstrained),
|
||||||
)
|
)
|
||||||
|
@ -101,6 +109,7 @@ impl BoxFragment {
|
||||||
border: LogicalSides<Length>,
|
border: LogicalSides<Length>,
|
||||||
margin: LogicalSides<Length>,
|
margin: LogicalSides<Length>,
|
||||||
clearance: Option<Length>,
|
clearance: Option<Length>,
|
||||||
|
mut last_inflow_baseline_offset: Option<Length>,
|
||||||
block_margins_collapsed_with_children: CollapsedBlockMargins,
|
block_margins_collapsed_with_children: CollapsedBlockMargins,
|
||||||
overconstrained: PhysicalSize<bool>,
|
overconstrained: PhysicalSize<bool>,
|
||||||
) -> BoxFragment {
|
) -> BoxFragment {
|
||||||
|
@ -112,6 +121,17 @@ impl BoxFragment {
|
||||||
acc.union(&child.scrollable_overflow(&containing_block))
|
acc.union(&child.scrollable_overflow(&containing_block))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// From the https://drafts.csswg.org/css-align-3/#baseline-export section on "block containers":
|
||||||
|
// > However, for legacy reasons if its baseline-source is auto (the initial
|
||||||
|
// > value) a block-level or inline-level block container that is a scroll container
|
||||||
|
// > always has a last baseline set, whose baselines all correspond to its block-end
|
||||||
|
// > margin edge.
|
||||||
|
if style.establishes_scroll_container() {
|
||||||
|
last_inflow_baseline_offset = Some(
|
||||||
|
content_rect.size.block + padding.block_end + border.block_end + margin.block_end,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
BoxFragment {
|
BoxFragment {
|
||||||
base: base_fragment_info.into(),
|
base: base_fragment_info.into(),
|
||||||
style,
|
style,
|
||||||
|
@ -124,6 +144,7 @@ impl BoxFragment {
|
||||||
border,
|
border,
|
||||||
margin,
|
margin,
|
||||||
clearance,
|
clearance,
|
||||||
|
last_baseline_offset: last_inflow_baseline_offset,
|
||||||
block_margins_collapsed_with_children,
|
block_margins_collapsed_with_children,
|
||||||
scrollable_overflow_from_children,
|
scrollable_overflow_from_children,
|
||||||
overconstrained,
|
overconstrained,
|
||||||
|
@ -194,9 +215,7 @@ impl BoxFragment {
|
||||||
.border_rect()
|
.border_rect()
|
||||||
.to_physical(self.style.writing_mode, containing_block);
|
.to_physical(self.style.writing_mode, containing_block);
|
||||||
|
|
||||||
if self.style.get_box().overflow_y != ComputedOverflow::Visible &&
|
if self.style.establishes_scroll_container() {
|
||||||
self.style.get_box().overflow_x != ComputedOverflow::Visible
|
|
||||||
{
|
|
||||||
return overflow;
|
return overflow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -703,7 +703,10 @@ impl HoistedAbsolutelyPositionedBox {
|
||||||
pbm.padding,
|
pbm.padding,
|
||||||
pbm.border,
|
pbm.border,
|
||||||
margin,
|
margin,
|
||||||
None,
|
None, /* clearance */
|
||||||
|
// We do not set the baseline offset, because absolutely positioned
|
||||||
|
// elements are not inflow.
|
||||||
|
None, /* last_inflow_baseline_offset */
|
||||||
CollapsedBlockMargins::zero(),
|
CollapsedBlockMargins::zero(),
|
||||||
physical_overconstrained,
|
physical_overconstrained,
|
||||||
)
|
)
|
||||||
|
|
|
@ -15,7 +15,7 @@ use style::values::computed::image::Image as ComputedImageLayer;
|
||||||
use style::values::computed::{Length, LengthPercentage, NonNegativeLengthPercentage, Size};
|
use style::values::computed::{Length, LengthPercentage, 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, Overflow};
|
||||||
use style::Zero;
|
use style::Zero;
|
||||||
use webrender_api as wr;
|
use webrender_api as wr;
|
||||||
|
|
||||||
|
@ -163,6 +163,7 @@ pub(crate) trait ComputedValuesExt {
|
||||||
fn effective_z_index(&self) -> i32;
|
fn effective_z_index(&self) -> i32;
|
||||||
fn establishes_block_formatting_context(&self) -> bool;
|
fn establishes_block_formatting_context(&self) -> bool;
|
||||||
fn establishes_stacking_context(&self) -> bool;
|
fn establishes_stacking_context(&self) -> bool;
|
||||||
|
fn establishes_scroll_container(&self) -> bool;
|
||||||
fn establishes_containing_block_for_absolute_descendants(&self) -> bool;
|
fn establishes_containing_block_for_absolute_descendants(&self) -> bool;
|
||||||
fn establishes_containing_block_for_all_descendants(&self) -> bool;
|
fn establishes_containing_block_for_all_descendants(&self) -> bool;
|
||||||
fn background_is_transparent(&self) -> bool;
|
fn background_is_transparent(&self) -> bool;
|
||||||
|
@ -431,6 +432,12 @@ impl ComputedValuesExt for ComputedValues {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether or not the `overflow` value of this style establishes a scroll container.
|
||||||
|
fn establishes_scroll_container(&self) -> bool {
|
||||||
|
self.get_box().overflow_x != Overflow::Visible ||
|
||||||
|
self.get_box().overflow_y != Overflow::Visible
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if this fragment establishes a new stacking context and false otherwise.
|
/// Returns true if this fragment establishes a new stacking context and false otherwise.
|
||||||
fn establishes_stacking_context(&self) -> bool {
|
fn establishes_stacking_context(&self) -> bool {
|
||||||
let effects = self.get_effects();
|
let effects = self.get_effects();
|
||||||
|
|
|
@ -40,6 +40,7 @@ impl Table {
|
||||||
IndependentLayout {
|
IndependentLayout {
|
||||||
fragments: Vec::new(),
|
fragments: Vec::new(),
|
||||||
content_block_size: Length::new(0.),
|
content_block_size: Length::new(0.),
|
||||||
|
last_inflow_baseline_offset: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,6 @@ ${helpers.predefined_type(
|
||||||
"VerticalAlign",
|
"VerticalAlign",
|
||||||
"computed::VerticalAlign::baseline()",
|
"computed::VerticalAlign::baseline()",
|
||||||
engines="gecko servo",
|
engines="gecko servo",
|
||||||
servo_pref="layout.legacy_layout",
|
|
||||||
animation_value_type="ComputedValue",
|
animation_value_type="ComputedValue",
|
||||||
spec="https://www.w3.org/TR/CSS2/visudet.html#propdef-vertical-align",
|
spec="https://www.w3.org/TR/CSS2/visudet.html#propdef-vertical-align",
|
||||||
servo_restyle_damage = "reflow",
|
servo_restyle_damage = "reflow",
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[background-position-applies-to-009.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[background-position-applies-to-012.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[background-position-applies-to-015.xht]
|
|
||||||
expected: FAIL
|
|
2
tests/wpt/meta/css/CSS2/css1/c414-flt-fit-004.xht.ini
Normal file
2
tests/wpt/meta/css/CSS2/css1/c414-flt-fit-004.xht.ini
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[c414-flt-fit-004.xht]
|
||||||
|
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
||||||
[c44-ln-box-000.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[c44-ln-box-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[c44-ln-box-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[c44-ln-box-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[c544-valgn-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[c548-leadin-000.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[c548-ln-ht-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[c548-ln-ht-004.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[c5502-imrgn-r-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[c5504-imrgn-l-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[c5507-ipadn-r-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[c5509-ipadn-l-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[float-non-replaced-width-007.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[float-non-replaced-width-008.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[float-non-replaced-width-009.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[float-non-replaced-width-010.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[float-non-replaced-width-011.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[float-non-replaced-width-012.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[margin-collapse-clear-014.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
[font-applies-to-001.xht]
|
||||||
|
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
||||||
|
[anonymous-inline-inherit-001.html]
|
||||||
|
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-004.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-005.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-013.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-015.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-016.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-024.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-025.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-026.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-027.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-035.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-037.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-038.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-046.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-048.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-049.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-057.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-059.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-060.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-068.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-070.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-071.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-079.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-081.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-082.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-090.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-092.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-093.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-101.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-103.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-104.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-125.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-bleed-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[line-height-bleed-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-007.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-008.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-019.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-020.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-031.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-032.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-043.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-044.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-055.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-056.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-067.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-068.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-079.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-080.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-103.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-104.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-applies-to-008.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-baseline-004a.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[vertical-align-baseline-005a.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[margin-percentage-inherit-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[inline-block-non-replaced-width-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[inline-block-non-replaced-width-004.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[inline-block-valign-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[inline-non-replaced-height-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[inline-non-replaced-height-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[absolute-non-replaced-width-017.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[absolute-non-replaced-width-018.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[absolute-non-replaced-width-019.xht]
|
|
||||||
expected: FAIL
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue