mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
layout: Implement proper absolute child position for flexbox (#33346)
This implements the requirements outlined in the [flexbox specification] about how to position absolute children of flex containers. We must establish a static position rectangle (to use if all insets are auto) and also align the child into that rectangle. [flebox specification]: https://drafts.csswg.org/css-flexbox/#abspos-items Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
a3a86d5913
commit
d169a82d2e
20 changed files with 678 additions and 724 deletions
|
@ -11,7 +11,6 @@ use itertools::izip;
|
|||
use style::computed_values::position::T as Position;
|
||||
use style::logical_geometry::Direction;
|
||||
use style::properties::longhands::align_items::computed_value::T as AlignItems;
|
||||
use style::properties::longhands::align_self::computed_value::T as AlignSelf;
|
||||
use style::properties::longhands::box_sizing::computed_value::T as BoxSizing;
|
||||
use style::properties::longhands::flex_wrap::computed_value::T as FlexWrap;
|
||||
use style::properties::ComputedValues;
|
||||
|
@ -136,7 +135,7 @@ impl FlexItemLayoutResult {
|
|||
final_line_cross_size,
|
||||
self.baseline_relative_to_margin_box.unwrap_or_default(),
|
||||
shared_alignment_baseline.unwrap_or_default(),
|
||||
flex_context.config.flex_wrap_reverse,
|
||||
flex_context.config.flex_wrap_is_reversed,
|
||||
);
|
||||
|
||||
let start_corner = FlexRelativeVec2 {
|
||||
|
@ -244,16 +243,6 @@ struct FinalFlexLineLayout {
|
|||
}
|
||||
|
||||
impl FlexContainerConfig {
|
||||
fn align_for(&self, align_self: AlignSelf) -> AlignItems {
|
||||
let value = align_self.0 .0.value();
|
||||
let mapped_value = match value {
|
||||
AlignFlags::AUTO => self.align_items.0,
|
||||
AlignFlags::NORMAL => AlignFlags::STRETCH,
|
||||
_ => value,
|
||||
};
|
||||
AlignItems(mapped_value)
|
||||
}
|
||||
|
||||
/// Whether an item with an `auto` preferred cross size needs to be stretched
|
||||
/// to fill the flex container.
|
||||
/// <https://drafts.csswg.org/css-flexbox/#stretched>
|
||||
|
@ -264,10 +253,40 @@ impl FlexContainerConfig {
|
|||
) -> bool {
|
||||
self.container_is_single_line &&
|
||||
item_with_auto_cross_size_stretches_to_line_size(
|
||||
self.align_for(item_style.clone_align_self()),
|
||||
AlignItems(self.resolve_align_self_for_child(item_style)),
|
||||
item_margin,
|
||||
)
|
||||
}
|
||||
|
||||
fn resolve_reversable_flex_alignment(
|
||||
&self,
|
||||
align_flags: AlignFlags,
|
||||
reversed: bool,
|
||||
) -> AlignFlags {
|
||||
match (align_flags.value(), reversed) {
|
||||
(AlignFlags::FLEX_START, false) => AlignFlags::START | align_flags.flags(),
|
||||
(AlignFlags::FLEX_START, true) => AlignFlags::END | align_flags.flags(),
|
||||
(AlignFlags::FLEX_END, false) => AlignFlags::END | align_flags.flags(),
|
||||
(AlignFlags::FLEX_END, true) => AlignFlags::START | align_flags.flags(),
|
||||
(_, _) => align_flags,
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_align_self_for_child(&self, child_style: &ComputedValues) -> AlignFlags {
|
||||
self.resolve_reversable_flex_alignment(
|
||||
child_style
|
||||
.resolve_align_self(self.align_items, AlignItems(AlignFlags::STRETCH))
|
||||
.0,
|
||||
self.flex_wrap_is_reversed,
|
||||
)
|
||||
}
|
||||
|
||||
fn resolve_justify_content_for_child(&self) -> AlignFlags {
|
||||
self.resolve_reversable_flex_alignment(
|
||||
self.justify_content.0.primary(),
|
||||
self.flex_direction_is_reversed,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl FlexContext<'_> {
|
||||
|
@ -299,10 +318,6 @@ impl FlexContext<'_> {
|
|||
rect,
|
||||
)
|
||||
}
|
||||
|
||||
fn align_for(&self, align_self: AlignSelf) -> AlignItems {
|
||||
self.config.align_for(align_self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
|
@ -632,24 +647,15 @@ impl FlexContainer {
|
|||
flex_context.container_max_cross_size,
|
||||
);
|
||||
|
||||
let content_block_size = match flex_context.config.flex_axis {
|
||||
FlexAxis::Row => {
|
||||
// `container_main_size` ends up unused here but in this case that’s fine
|
||||
// since it was already exactly the one decided by the outer formatting context.
|
||||
container_cross_size
|
||||
},
|
||||
FlexAxis::Column => {
|
||||
// FIXME: `container_cross_size` ends up unused here, which is a bug.
|
||||
// It is meant to be the used inline-size, but the parent formatting context
|
||||
// has already decided a possibly-different used inline-size.
|
||||
// The spec is missing something to resolve this conflict:
|
||||
// https://github.com/w3c/csswg-drafts/issues/5190
|
||||
// And we’ll need to change the signature of `IndependentFormattingContext::layout`
|
||||
// to allow the inner formatting context to “negotiate” a used inline-size
|
||||
// with the outer one somehow.
|
||||
container_main_size
|
||||
},
|
||||
let container_size = FlexRelativeVec2 {
|
||||
main: container_main_size,
|
||||
cross: container_cross_size,
|
||||
};
|
||||
let content_block_size = flex_context
|
||||
.config
|
||||
.flex_axis
|
||||
.vec2_to_flow_relative(container_size)
|
||||
.block;
|
||||
|
||||
let mut remaining_free_cross_space = flex_context
|
||||
.container_definite_inner_size
|
||||
|
@ -704,23 +710,13 @@ impl FlexContainer {
|
|||
};
|
||||
|
||||
// Implement "unsafe" alignment. "safe" alignment is handled by the fallback process above.
|
||||
let resolved_align_content = self.config.resolve_reversable_flex_alignment(
|
||||
resolved_align_content,
|
||||
flex_context.config.flex_wrap_is_reversed,
|
||||
);
|
||||
let mut cross_start_position_cursor = match resolved_align_content {
|
||||
AlignFlags::START => Au::zero(),
|
||||
AlignFlags::FLEX_START => {
|
||||
if flex_context.config.flex_wrap_reverse {
|
||||
remaining_free_cross_space
|
||||
} else {
|
||||
Au::zero()
|
||||
}
|
||||
},
|
||||
AlignFlags::END => remaining_free_cross_space,
|
||||
AlignFlags::FLEX_END => {
|
||||
if flex_context.config.flex_wrap_reverse {
|
||||
Au::zero()
|
||||
} else {
|
||||
remaining_free_cross_space
|
||||
}
|
||||
},
|
||||
AlignFlags::CENTER => remaining_free_cross_space / 2,
|
||||
AlignFlags::STRETCH => Au::zero(),
|
||||
AlignFlags::SPACE_BETWEEN => Au::zero(),
|
||||
|
@ -764,7 +760,7 @@ impl FlexContainer {
|
|||
cross_gap;
|
||||
|
||||
let flow_relative_line_position =
|
||||
match (self.config.flex_axis, self.config.flex_wrap_reverse) {
|
||||
match (self.config.flex_axis, self.config.flex_wrap_is_reversed) {
|
||||
(FlexAxis::Row, false) => LogicalVec2 {
|
||||
block: line_cross_start_position,
|
||||
inline: Au::zero(),
|
||||
|
@ -824,16 +820,13 @@ impl FlexContainer {
|
|||
let fragments = absolutely_positioned_items_with_original_order
|
||||
.into_iter()
|
||||
.map(|child_as_abspos| match child_as_abspos {
|
||||
FlexContent::AbsolutelyPositionedBox(absolutely_positioned) => {
|
||||
let hoisted_box = AbsolutelyPositionedBox::to_hoisted(
|
||||
absolutely_positioned,
|
||||
LogicalVec2::zero(),
|
||||
FlexContent::AbsolutelyPositionedBox(absolutely_positioned_box) => self
|
||||
.create_absolutely_positioned_flex_child_fragment(
|
||||
absolutely_positioned_box,
|
||||
containing_block,
|
||||
);
|
||||
let hoisted_fragment = hoisted_box.fragment.clone();
|
||||
positioning_context.push(hoisted_box);
|
||||
Fragment::AbsoluteOrFixedPositioned(hoisted_fragment)
|
||||
},
|
||||
container_size,
|
||||
positioning_context,
|
||||
),
|
||||
FlexContent::FlexItemPlaceholder => {
|
||||
// The `flex_item_fragments` iterator yields one fragment
|
||||
// per flex item, in the original order.
|
||||
|
@ -842,7 +835,6 @@ impl FlexContainer {
|
|||
let fragment = Fragment::Box(fragment);
|
||||
child_positioning_context.adjust_static_position_of_hoisted_fragments(
|
||||
&fragment,
|
||||
self.style.effective_writing_mode(),
|
||||
PositioningContextLength::zero(),
|
||||
);
|
||||
positioning_context.append(child_positioning_context);
|
||||
|
@ -871,6 +863,68 @@ impl FlexContainer {
|
|||
}
|
||||
}
|
||||
|
||||
/// Create a absolutely positioned flex child fragment, using the rules the
|
||||
/// specification dictates. This should take into account the alignment and
|
||||
/// justification values of the container and the child to position it within a
|
||||
/// "inset-modified containing block," which may be either the "static-position
|
||||
/// rectangle" that's calculated below or a modified version of the absolute's
|
||||
/// containing block adjusted by the insets specified in the item's style.
|
||||
///
|
||||
/// From <https://drafts.csswg.org/css-flexbox/#abspos-items>:
|
||||
/// > The cross-axis edges of the static-position rectangle of an
|
||||
/// > absolutely-positioned child of a flex container are the content edges of the
|
||||
/// > flex container The main-axis edges of the static-position rectangle are where
|
||||
/// > the margin edges of the child would be positioned if it were the sole flex item
|
||||
/// > in the flex container, assuming both the child and the flex container were
|
||||
/// > fixed-size boxes of their used size. (For this purpose, auto margins are
|
||||
/// > treated as zero.)
|
||||
fn create_absolutely_positioned_flex_child_fragment(
|
||||
&self,
|
||||
absolutely_positioned_box: ArcRefCell<AbsolutelyPositionedBox>,
|
||||
containing_block: &ContainingBlock,
|
||||
container_size: FlexRelativeVec2<Au>,
|
||||
positioning_context: &mut PositioningContext,
|
||||
) -> Fragment {
|
||||
let alignment = {
|
||||
let fragment = absolutely_positioned_box.borrow();
|
||||
let make_flex_only_values_directional_for_absolutes =
|
||||
|value: AlignFlags, reversed: bool| match (value.value(), reversed) {
|
||||
(AlignFlags::NORMAL | AlignFlags::AUTO | AlignFlags::STRETCH, true) => {
|
||||
AlignFlags::END | AlignFlags::SAFE
|
||||
},
|
||||
(AlignFlags::STRETCH, false) => AlignFlags::START | AlignFlags::SAFE,
|
||||
_ => value,
|
||||
};
|
||||
let cross = make_flex_only_values_directional_for_absolutes(
|
||||
self.config
|
||||
.resolve_align_self_for_child(fragment.context.style()),
|
||||
self.config.flex_wrap_is_reversed,
|
||||
);
|
||||
let main = make_flex_only_values_directional_for_absolutes(
|
||||
self.config.resolve_justify_content_for_child(),
|
||||
self.config.flex_direction_is_reversed,
|
||||
);
|
||||
|
||||
FlexRelativeVec2 { cross, main }
|
||||
};
|
||||
let logical_alignment = self.config.flex_axis.vec2_to_flow_relative(alignment);
|
||||
|
||||
let static_position_rect = LogicalRect {
|
||||
start_corner: LogicalVec2::zero(),
|
||||
size: self.config.flex_axis.vec2_to_flow_relative(container_size),
|
||||
}
|
||||
.to_physical(containing_block.effective_writing_mode());
|
||||
|
||||
let hoisted_box = AbsolutelyPositionedBox::to_hoisted(
|
||||
absolutely_positioned_box,
|
||||
static_position_rect,
|
||||
logical_alignment,
|
||||
);
|
||||
let hoisted_fragment = hoisted_box.fragment.clone();
|
||||
positioning_context.push(hoisted_box);
|
||||
Fragment::AbsoluteOrFixedPositioned(hoisted_fragment)
|
||||
}
|
||||
|
||||
fn available_cross_space_for_flex_items(
|
||||
&self,
|
||||
containing_block_for_container: &ContainingBlock,
|
||||
|
@ -1022,8 +1076,11 @@ impl<'a> FlexItem<'a> {
|
|||
cross: flex_relative_content_min_size.cross.auto_is(Au::zero),
|
||||
};
|
||||
|
||||
let align_self = flex_context.align_for(box_.style().clone_align_self());
|
||||
|
||||
let align_self = AlignItems(
|
||||
flex_context
|
||||
.config
|
||||
.resolve_align_self_for_child(box_.style()),
|
||||
);
|
||||
let (flex_base_size, flex_base_size_is_definite) = box_.flex_base_size(
|
||||
flex_context.layout_context,
|
||||
&containing_block.into(),
|
||||
|
@ -1922,8 +1979,7 @@ impl FlexItem<'_> {
|
|||
Au::zero()
|
||||
} else {
|
||||
match self.align_self.0.value() {
|
||||
AlignFlags::FLEX_START | AlignFlags::STRETCH => Au::zero(),
|
||||
AlignFlags::FLEX_END => ending_alignment,
|
||||
AlignFlags::STRETCH => Au::zero(),
|
||||
AlignFlags::CENTER => ending_alignment / 2,
|
||||
AlignFlags::BASELINE | AlignFlags::LAST_BASELINE => {
|
||||
max_propagated_baseline - propagated_baseline
|
||||
|
|
|
@ -33,7 +33,7 @@ pub(crate) struct FlexContainerConfig {
|
|||
flex_direction: FlexDirection,
|
||||
flex_direction_is_reversed: bool,
|
||||
flex_wrap: FlexWrap,
|
||||
flex_wrap_reverse: bool,
|
||||
flex_wrap_is_reversed: bool,
|
||||
main_start_cross_start_sides_are: MainStartCrossStart,
|
||||
align_content: AlignContent,
|
||||
align_items: AlignItems,
|
||||
|
@ -74,7 +74,7 @@ impl FlexContainerConfig {
|
|||
flex_direction,
|
||||
flex_direction_is_reversed,
|
||||
flex_wrap,
|
||||
flex_wrap_reverse,
|
||||
flex_wrap_is_reversed: flex_wrap_reverse,
|
||||
main_start_cross_start_sides_are,
|
||||
align_content,
|
||||
align_items,
|
||||
|
|
|
@ -11,6 +11,7 @@ use style::properties::ComputedValues;
|
|||
use style::values::computed::Length;
|
||||
use style::values::generics::box_::{GenericVerticalAlign, VerticalAlignKeyword};
|
||||
use style::values::generics::font::LineHeight;
|
||||
use style::values::specified::align::AlignFlags;
|
||||
use style::values::specified::box_::DisplayOutside;
|
||||
use style::values::specified::text::TextDecorationLine;
|
||||
use style::values::Either;
|
||||
|
@ -24,7 +25,7 @@ use crate::cell::ArcRefCell;
|
|||
use crate::fragment_tree::{
|
||||
BaseFragmentInfo, BoxFragment, CollapsedBlockMargins, Fragment, TextFragment,
|
||||
};
|
||||
use crate::geom::{LogicalRect, LogicalVec2, ToLogical};
|
||||
use crate::geom::{LogicalRect, LogicalVec2};
|
||||
use crate::positioned::{
|
||||
relative_adjustement, AbsolutelyPositionedBox, PositioningContext, PositioningContextLength,
|
||||
};
|
||||
|
@ -368,15 +369,13 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> {
|
|||
};
|
||||
|
||||
let ifc_writing_mode = self.layout.containing_block.effective_writing_mode();
|
||||
if inner_state
|
||||
.flags
|
||||
.contains(LineLayoutInlineContainerFlags::HAD_ANY_FLOATS)
|
||||
{
|
||||
for fragment in inner_state.fragments.iter_mut() {
|
||||
if let Fragment::Float(box_fragment) = fragment {
|
||||
match fragment {
|
||||
Fragment::Float(box_fragment) => {
|
||||
box_fragment.content_rect.origin -=
|
||||
pbm_sums.start_offset().to_physical_size(ifc_writing_mode);
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -404,7 +403,7 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> {
|
|||
positioning_context
|
||||
.layout_collected_children(self.layout.layout_context, &mut fragment);
|
||||
positioning_context.adjust_static_position_of_hoisted_fragments_with_offset(
|
||||
&fragment.content_rect.origin.to_logical(ifc_writing_mode),
|
||||
&fragment.content_rect.origin.to_vector(),
|
||||
PositioningContextLength::zero(),
|
||||
);
|
||||
self.current_positioning_context_mut()
|
||||
|
@ -413,7 +412,7 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> {
|
|||
Either::Second(start_offset) => {
|
||||
self.current_positioning_context_mut()
|
||||
.adjust_static_position_of_hoisted_fragments_with_offset(
|
||||
&fragment.content_rect.origin.to_logical(ifc_writing_mode),
|
||||
&fragment.content_rect.origin.to_vector(),
|
||||
start_offset,
|
||||
);
|
||||
},
|
||||
|
@ -526,11 +525,7 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> {
|
|||
|
||||
if let Some(mut positioning_context) = atomic.positioning_context {
|
||||
positioning_context.adjust_static_position_of_hoisted_fragments_with_offset(
|
||||
&atomic
|
||||
.fragment
|
||||
.content_rect
|
||||
.origin
|
||||
.to_logical(ifc_writing_mode),
|
||||
&atomic.fragment.content_rect.origin.to_vector(),
|
||||
PositioningContextLength::zero(),
|
||||
);
|
||||
self.current_positioning_context_mut()
|
||||
|
@ -574,10 +569,21 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> {
|
|||
}
|
||||
};
|
||||
|
||||
// Since alignment of absolutes in inlines is currently always `start`, the size of
|
||||
// of the static position rectangle does not matter.
|
||||
let static_position_rect = LogicalRect {
|
||||
start_corner: initial_start_corner,
|
||||
size: LogicalVec2::zero(),
|
||||
}
|
||||
.to_physical(self.layout.containing_block.effective_writing_mode());
|
||||
|
||||
let hoisted_box = AbsolutelyPositionedBox::to_hoisted(
|
||||
absolute.absolutely_positioned_box.clone(),
|
||||
initial_start_corner.into(),
|
||||
self.layout.containing_block,
|
||||
static_position_rect,
|
||||
LogicalVec2 {
|
||||
inline: AlignFlags::START,
|
||||
block: AlignFlags::START,
|
||||
},
|
||||
);
|
||||
let hoisted_fragment = hoisted_box.fragment.clone();
|
||||
self.current_positioning_context_mut().push(hoisted_box);
|
||||
|
|
|
@ -886,13 +886,13 @@ impl<'layout_dta> InlineFormattingContextLayout<'layout_dta> {
|
|||
},
|
||||
};
|
||||
|
||||
let line_rect = line_rect.to_physical(self.containing_block.effective_writing_mode());
|
||||
self.positioning_context
|
||||
.adjust_static_position_of_hoisted_fragments_with_offset(
|
||||
&line_rect.start_corner,
|
||||
&line_rect.origin.to_vector(),
|
||||
start_positioning_context_length,
|
||||
);
|
||||
|
||||
let line_rect = line_rect.to_physical(self.containing_block.effective_writing_mode());
|
||||
self.fragments
|
||||
.push(Fragment::Positioning(PositioningFragment::new_anonymous(
|
||||
line_rect, fragments,
|
||||
|
|
|
@ -15,6 +15,7 @@ use style::computed_values::float::T as Float;
|
|||
use style::logical_geometry::WritingMode;
|
||||
use style::properties::ComputedValues;
|
||||
use style::values::computed::{Length, LengthOrAuto, Size};
|
||||
use style::values::specified::align::AlignFlags;
|
||||
use style::values::specified::{Display, TextAlignKeyword};
|
||||
use style::Zero;
|
||||
|
||||
|
@ -594,7 +595,6 @@ fn layout_block_level_children_in_parallel(
|
|||
placement_state.place_fragment_and_update_baseline(&mut fragment, None);
|
||||
child_positioning_context.adjust_static_position_of_hoisted_fragments(
|
||||
&fragment,
|
||||
containing_block.effective_writing_mode(),
|
||||
PositioningContextLength::zero(),
|
||||
);
|
||||
positioning_context.append(child_positioning_context);
|
||||
|
@ -632,7 +632,6 @@ fn layout_block_level_children_sequentially(
|
|||
.place_fragment_and_update_baseline(&mut fragment, Some(sequential_layout_state));
|
||||
positioning_context.adjust_static_position_of_hoisted_fragments(
|
||||
&fragment,
|
||||
containing_block.effective_writing_mode(),
|
||||
positioning_context_length_before_layout,
|
||||
);
|
||||
|
||||
|
@ -709,11 +708,14 @@ impl BlockLevelBox {
|
|||
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(box_) => {
|
||||
let hoisted_box = AbsolutelyPositionedBox::to_hoisted(
|
||||
box_.clone(),
|
||||
// This is incorrect, however we do not know the
|
||||
// correct positioning until later, in place_block_level_fragment,
|
||||
// and this value will be adjusted there
|
||||
LogicalVec2::zero(),
|
||||
containing_block,
|
||||
// This is incorrect, however we do not know the correct positioning
|
||||
// until later, in PlacementState::place_fragment, and this value will be
|
||||
// adjusted there
|
||||
PhysicalRect::zero(),
|
||||
LogicalVec2 {
|
||||
inline: AlignFlags::START,
|
||||
block: AlignFlags::START,
|
||||
},
|
||||
);
|
||||
let hoisted_fragment = hoisted_box.fragment.clone();
|
||||
positioning_context.push(hoisted_box);
|
||||
|
@ -1817,11 +1819,17 @@ impl PlacementState {
|
|||
}
|
||||
},
|
||||
Fragment::AbsoluteOrFixedPositioned(fragment) => {
|
||||
let offset = LogicalVec2 {
|
||||
block: (self.current_margin.solve() + self.current_block_direction_position),
|
||||
// The alignment of absolutes in block flow layout is always "start", so the size of
|
||||
// the static position rectangle does not matter.
|
||||
fragment.borrow_mut().static_position_rect = LogicalRect {
|
||||
start_corner: LogicalVec2 {
|
||||
block: (self.current_margin.solve() +
|
||||
self.current_block_direction_position),
|
||||
inline: Au::zero(),
|
||||
};
|
||||
fragment.borrow_mut().adjust_offsets(offset);
|
||||
},
|
||||
size: LogicalVec2::zero(),
|
||||
}
|
||||
.to_physical(self.writing_mode);
|
||||
},
|
||||
Fragment::Float(box_fragment) => {
|
||||
let sequential_layout_state = sequential_layout_state
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
|
||||
use app_units::Au;
|
||||
use serde::Serialize;
|
||||
use style::values::computed::LengthPercentage;
|
||||
use style::values::specified::align::AlignFlags;
|
||||
|
||||
use super::Fragment;
|
||||
use crate::cell::ArcRefCell;
|
||||
use crate::geom::LogicalVec2;
|
||||
use crate::geom::{LogicalVec2, PhysicalRect, PhysicalVec};
|
||||
|
||||
/// A reference to a Fragment which is shared between `HoistedAbsolutelyPositionedBox`
|
||||
/// and its placeholder `AbsoluteOrFixedPositionedFragment` in the original tree position.
|
||||
|
@ -16,53 +16,35 @@ use crate::geom::LogicalVec2;
|
|||
#[derive(Serialize)]
|
||||
pub(crate) struct HoistedSharedFragment {
|
||||
pub fragment: Option<ArcRefCell<Fragment>>,
|
||||
pub box_offsets: LogicalVec2<AbsoluteBoxOffsets>,
|
||||
/// The "static-position rect" of this absolutely positioned box. This is defined by the
|
||||
/// layout mode from which the box originates.
|
||||
///
|
||||
/// See <https://drafts.csswg.org/css-position-3/#staticpos-rect>
|
||||
pub static_position_rect: PhysicalRect<Au>,
|
||||
/// The resolved alignment values used for aligning this absolutely positioned element
|
||||
/// if the "static-position rect" ends up being the "inset-modified containing block".
|
||||
/// These values are dependent on the layout mode (currently only interesting for
|
||||
/// flexbox).
|
||||
pub resolved_alignment: LogicalVec2<AlignFlags>,
|
||||
}
|
||||
|
||||
impl HoistedSharedFragment {
|
||||
pub(crate) fn new(box_offsets: LogicalVec2<AbsoluteBoxOffsets>) -> Self {
|
||||
pub(crate) fn new(
|
||||
static_position_rect: PhysicalRect<Au>,
|
||||
resolved_alignment: LogicalVec2<AlignFlags>,
|
||||
) -> Self {
|
||||
HoistedSharedFragment {
|
||||
fragment: None,
|
||||
box_offsets,
|
||||
static_position_rect,
|
||||
resolved_alignment,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HoistedSharedFragment {
|
||||
/// In some cases `inset: auto`-positioned elements do not know their precise
|
||||
/// position until after they're hoisted. This lets us adjust auto values
|
||||
/// after the fact.
|
||||
pub(crate) fn adjust_offsets(&mut self, offsets: LogicalVec2<Au>) {
|
||||
self.box_offsets.inline.adjust_offset(offsets.inline);
|
||||
self.box_offsets.block.adjust_offset(offsets.block);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub(crate) enum AbsoluteBoxOffsets {
|
||||
StaticStart {
|
||||
start: Au,
|
||||
},
|
||||
Start {
|
||||
start: LengthPercentage,
|
||||
},
|
||||
End {
|
||||
end: LengthPercentage,
|
||||
},
|
||||
Both {
|
||||
start: LengthPercentage,
|
||||
end: LengthPercentage,
|
||||
},
|
||||
}
|
||||
|
||||
impl AbsoluteBoxOffsets {
|
||||
pub(crate) fn both_specified(&self) -> bool {
|
||||
matches!(self, AbsoluteBoxOffsets::Both { .. })
|
||||
}
|
||||
|
||||
pub(crate) fn adjust_offset(&mut self, new_offset: Au) {
|
||||
if let AbsoluteBoxOffsets::StaticStart { ref mut start } = *self {
|
||||
*start = new_offset
|
||||
}
|
||||
/// `inset: auto`-positioned elements do not know their precise position until after
|
||||
/// they're hoisted. This lets us adjust auto values after the fact.
|
||||
pub(crate) fn adjust_offsets(&mut self, offset: &PhysicalVec<Au>) {
|
||||
self.static_position_rect = self.static_position_rect.translate(*offset);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ use crate::ContainingBlock;
|
|||
|
||||
pub type PhysicalPoint<U> = euclid::Point2D<U, CSSPixel>;
|
||||
pub type PhysicalSize<U> = euclid::Size2D<U, CSSPixel>;
|
||||
pub type PhysicalVec<U> = euclid::Vector2D<U, CSSPixel>;
|
||||
pub type PhysicalRect<U> = euclid::Rect<U, CSSPixel>;
|
||||
pub type PhysicalSides<U> = euclid::SideOffsets2D<U, CSSPixel>;
|
||||
pub type AuOrAuto = AutoOr<Au>;
|
||||
|
|
|
@ -7,9 +7,8 @@ use rayon::iter::IntoParallelRefMutIterator;
|
|||
use rayon::prelude::{IndexedParallelIterator, ParallelIterator};
|
||||
use serde::Serialize;
|
||||
use style::computed_values::position::T as Position;
|
||||
use style::logical_geometry::WritingMode;
|
||||
use style::properties::ComputedValues;
|
||||
use style::values::computed::Length;
|
||||
use style::values::specified::align::{AlignFlags, AxisDirection};
|
||||
use style::values::specified::text::TextDecorationLine;
|
||||
use style::Zero;
|
||||
|
||||
|
@ -19,12 +18,11 @@ use crate::dom::NodeExt;
|
|||
use crate::dom_traversal::{Contents, NodeAndStyleInfo};
|
||||
use crate::formatting_contexts::IndependentFormattingContext;
|
||||
use crate::fragment_tree::{
|
||||
AbsoluteBoxOffsets, BoxFragment, CollapsedBlockMargins, Fragment, FragmentFlags,
|
||||
HoistedSharedFragment,
|
||||
BoxFragment, CollapsedBlockMargins, Fragment, FragmentFlags, HoistedSharedFragment,
|
||||
};
|
||||
use crate::geom::{
|
||||
AuOrAuto, LengthOrAuto, LengthPercentageOrAuto, LogicalRect, LogicalSides, LogicalVec2,
|
||||
PhysicalPoint, PhysicalRect, ToLogical,
|
||||
PhysicalPoint, PhysicalRect, PhysicalVec, ToLogical,
|
||||
};
|
||||
use crate::style_ext::{ComputedValuesExt, DisplayInside};
|
||||
use crate::{ContainingBlock, DefiniteContainingBlock, IndefiniteContainingBlock};
|
||||
|
@ -72,49 +70,16 @@ impl AbsolutelyPositionedBox {
|
|||
}
|
||||
|
||||
pub(crate) fn to_hoisted(
|
||||
self_: ArcRefCell<Self>,
|
||||
initial_start_corner: LogicalVec2<Length>,
|
||||
containing_block: &ContainingBlock,
|
||||
absolutely_positioned_box: ArcRefCell<Self>,
|
||||
static_position_rectangle: PhysicalRect<Au>,
|
||||
resolved_alignment: LogicalVec2<AlignFlags>,
|
||||
) -> HoistedAbsolutelyPositionedBox {
|
||||
fn absolute_box_offsets(
|
||||
initial_static_start: Length,
|
||||
start: LengthPercentageOrAuto<'_>,
|
||||
end: LengthPercentageOrAuto<'_>,
|
||||
) -> AbsoluteBoxOffsets {
|
||||
match (start.non_auto(), end.non_auto()) {
|
||||
(None, None) => AbsoluteBoxOffsets::StaticStart {
|
||||
start: initial_static_start.into(),
|
||||
},
|
||||
(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 = {
|
||||
let box_ = self_.borrow();
|
||||
let box_offsets = box_.context.style().box_offsets(containing_block);
|
||||
LogicalVec2 {
|
||||
inline: absolute_box_offsets(
|
||||
initial_start_corner.inline,
|
||||
box_offsets.inline_start,
|
||||
box_offsets.inline_end,
|
||||
),
|
||||
block: absolute_box_offsets(
|
||||
initial_start_corner.block,
|
||||
box_offsets.block_start,
|
||||
box_offsets.block_end,
|
||||
),
|
||||
}
|
||||
};
|
||||
HoistedAbsolutelyPositionedBox {
|
||||
fragment: ArcRefCell::new(HoistedSharedFragment::new(box_offsets)),
|
||||
absolutely_positioned_box: self_,
|
||||
fragment: ArcRefCell::new(HoistedSharedFragment::new(
|
||||
static_position_rectangle,
|
||||
resolved_alignment,
|
||||
)),
|
||||
absolutely_positioned_box,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +143,6 @@ impl PositioningContext {
|
|||
pub(crate) fn adjust_static_position_of_hoisted_fragments(
|
||||
&mut self,
|
||||
parent_fragment: &Fragment,
|
||||
parent_fragment_writing_mode: WritingMode,
|
||||
index: PositioningContextLength,
|
||||
) {
|
||||
let start_offset = match &parent_fragment {
|
||||
|
@ -186,37 +150,39 @@ impl PositioningContext {
|
|||
Fragment::AbsoluteOrFixedPositioned(_) => return,
|
||||
Fragment::Positioning(fragment) => &fragment.rect.origin,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
.to_logical(parent_fragment_writing_mode);
|
||||
self.adjust_static_position_of_hoisted_fragments_with_offset(&start_offset, index);
|
||||
};
|
||||
self.adjust_static_position_of_hoisted_fragments_with_offset(
|
||||
&start_offset.to_vector(),
|
||||
index,
|
||||
);
|
||||
}
|
||||
|
||||
/// See documentation for [PositioningContext::adjust_static_position_of_hoisted_fragments].
|
||||
pub(crate) fn adjust_static_position_of_hoisted_fragments_with_offset(
|
||||
&mut self,
|
||||
start_offset: &LogicalVec2<Au>,
|
||||
offset: &PhysicalVec<Au>,
|
||||
index: PositioningContextLength,
|
||||
) {
|
||||
let update_fragment_if_needed = |hoisted_fragment: &mut HoistedAbsolutelyPositionedBox| {
|
||||
let mut fragment = hoisted_fragment.fragment.borrow_mut();
|
||||
if let AbsoluteBoxOffsets::StaticStart { start } = &mut fragment.box_offsets.inline {
|
||||
*start += start_offset.inline;
|
||||
}
|
||||
if let AbsoluteBoxOffsets::StaticStart { start } = &mut fragment.box_offsets.block {
|
||||
*start += start_offset.block;
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(hoisted_boxes) = self.for_nearest_positioned_ancestor.as_mut() {
|
||||
hoisted_boxes
|
||||
.iter_mut()
|
||||
.skip(index.for_nearest_positioned_ancestor)
|
||||
.for_each(update_fragment_if_needed);
|
||||
.for_each(|hoisted_fragment| {
|
||||
hoisted_fragment
|
||||
.fragment
|
||||
.borrow_mut()
|
||||
.adjust_offsets(offset)
|
||||
})
|
||||
}
|
||||
self.for_nearest_containing_block_for_all_descendants
|
||||
.iter_mut()
|
||||
.skip(index.for_nearest_containing_block_for_all_descendants)
|
||||
.for_each(update_fragment_if_needed);
|
||||
.for_each(|hoisted_fragment| {
|
||||
hoisted_fragment
|
||||
.fragment
|
||||
.borrow_mut()
|
||||
.adjust_offsets(offset)
|
||||
})
|
||||
}
|
||||
|
||||
/// Given `fragment_layout_fn`, a closure which lays out a fragment in a provided
|
||||
|
@ -486,11 +452,9 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
let cbis = containing_block.size.inline;
|
||||
let cbbs = containing_block.size.block;
|
||||
let mut absolutely_positioned_box = self.absolutely_positioned_box.borrow_mut();
|
||||
let containing_block_writing_mode = containing_block.effective_writing_mode();
|
||||
let pbm = absolutely_positioned_box
|
||||
.context
|
||||
.style()
|
||||
.padding_border_margin(&containing_block.into());
|
||||
let containing_block_writing_mode = containing_block.style.effective_writing_mode();
|
||||
let style = absolutely_positioned_box.context.style().clone();
|
||||
let pbm = style.padding_border_margin(&containing_block.into());
|
||||
|
||||
let computed_size = match &absolutely_positioned_box.context {
|
||||
IndependentFormattingContext::Replaced(replaced) => {
|
||||
|
@ -506,28 +470,62 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
block: LengthOrAuto::LengthPercentage(used_size.block.into()),
|
||||
}
|
||||
},
|
||||
IndependentFormattingContext::NonReplaced(non_replaced) => non_replaced
|
||||
.style
|
||||
.content_box_size(&containing_block.into(), &pbm),
|
||||
IndependentFormattingContext::NonReplaced(..) => {
|
||||
style.content_box_size(&containing_block.into(), &pbm)
|
||||
},
|
||||
};
|
||||
|
||||
let shared_fragment = self.fragment.borrow();
|
||||
let static_position_rect = shared_fragment
|
||||
.static_position_rect
|
||||
.to_logical(containing_block_writing_mode);
|
||||
|
||||
let indefinite_containing_block = containing_block.into();
|
||||
let box_offset = style.box_offsets(&indefinite_containing_block);
|
||||
|
||||
// When the "static-position rect" doesn't come into play, we do not do any alignment
|
||||
// in the inline axis.
|
||||
let inline_box_offsets = AbsoluteBoxOffsets {
|
||||
start: box_offset.inline_start,
|
||||
end: box_offset.inline_end,
|
||||
};
|
||||
let inline_alignment = match inline_box_offsets.either_specified() {
|
||||
true => AlignFlags::START | AlignFlags::SAFE,
|
||||
false => shared_fragment.resolved_alignment.inline,
|
||||
};
|
||||
|
||||
let inline_axis_solver = AbsoluteAxisSolver {
|
||||
axis: AxisDirection::Inline,
|
||||
containing_size: cbis,
|
||||
padding_border_sum: pbm.padding_border_sums.inline,
|
||||
computed_margin_start: pbm.margin.inline_start,
|
||||
computed_margin_end: pbm.margin.inline_end,
|
||||
avoid_negative_margin_start: true,
|
||||
box_offsets: &shared_fragment.box_offsets.inline,
|
||||
box_offsets: inline_box_offsets,
|
||||
static_position_rect_axis: static_position_rect.get_axis(AxisDirection::Inline),
|
||||
alignment: inline_alignment,
|
||||
};
|
||||
|
||||
// When the "static-position rect" doesn't come into play, we re-resolve "align-self"
|
||||
// against this containing block.
|
||||
let block_box_offsets = AbsoluteBoxOffsets {
|
||||
start: box_offset.block_start,
|
||||
end: box_offset.block_end,
|
||||
};
|
||||
let block_alignment = match block_box_offsets.either_specified() {
|
||||
true => style.clone_align_self().0 .0,
|
||||
false => shared_fragment.resolved_alignment.block,
|
||||
};
|
||||
let block_axis_solver = AbsoluteAxisSolver {
|
||||
axis: AxisDirection::Block,
|
||||
containing_size: cbbs,
|
||||
padding_border_sum: pbm.padding_border_sums.block,
|
||||
computed_margin_start: pbm.margin.block_start,
|
||||
computed_margin_end: pbm.margin.block_end,
|
||||
avoid_negative_margin_start: false,
|
||||
box_offsets: &shared_fragment.box_offsets.block,
|
||||
box_offsets: block_box_offsets,
|
||||
static_position_rect_axis: static_position_rect.get_axis(AxisDirection::Block),
|
||||
alignment: block_alignment,
|
||||
};
|
||||
let overconstrained = LogicalVec2 {
|
||||
inline: inline_axis_solver.is_overconstrained_for_size(computed_size.inline),
|
||||
|
@ -560,7 +558,7 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
// https://drafts.csswg.org/css2/#min-max-heights
|
||||
let min_size = non_replaced
|
||||
.style
|
||||
.content_min_box_size(&containing_block.into(), &pbm)
|
||||
.content_min_box_size(&indefinite_containing_block, &pbm)
|
||||
.map(|t| t.map(Au::from).auto_is(Au::zero));
|
||||
let max_size = non_replaced
|
||||
.style
|
||||
|
@ -720,7 +718,7 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
},
|
||||
};
|
||||
|
||||
let content_rect = LogicalRect {
|
||||
let mut content_rect = LogicalRect {
|
||||
start_corner: LogicalVec2 {
|
||||
inline: inline_start,
|
||||
block: block_start,
|
||||
|
@ -728,6 +726,13 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
size: content_size,
|
||||
};
|
||||
|
||||
let margin_box_rect = content_rect
|
||||
.inflate(&pbm.padding)
|
||||
.inflate(&pbm.border)
|
||||
.inflate(&margin);
|
||||
block_axis_solver.solve_alignment(margin_box_rect, &mut content_rect);
|
||||
inline_axis_solver.solve_alignment(margin_box_rect, &mut content_rect);
|
||||
|
||||
let physical_overconstrained =
|
||||
overconstrained.to_physical_size(containing_block.effective_writing_mode());
|
||||
|
||||
|
@ -754,10 +759,7 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
// other elements. If any of them have a static start position though, we need to
|
||||
// adjust it to account for the start corner of this absolute.
|
||||
positioning_context.adjust_static_position_of_hoisted_fragments_with_offset(
|
||||
&new_fragment
|
||||
.content_rect
|
||||
.origin
|
||||
.to_logical(containing_block_writing_mode),
|
||||
&new_fragment.content_rect.origin.to_vector(),
|
||||
PositioningContextLength::zero(),
|
||||
);
|
||||
|
||||
|
@ -768,6 +770,42 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct RectAxis {
|
||||
origin: Au,
|
||||
length: Au,
|
||||
}
|
||||
|
||||
impl LogicalRect<Au> {
|
||||
fn get_axis(&self, axis: AxisDirection) -> RectAxis {
|
||||
match axis {
|
||||
AxisDirection::Block => RectAxis {
|
||||
origin: self.start_corner.block,
|
||||
length: self.size.block,
|
||||
},
|
||||
AxisDirection::Inline => RectAxis {
|
||||
origin: self.start_corner.inline,
|
||||
length: self.size.inline,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct AbsoluteBoxOffsets<'a> {
|
||||
start: LengthPercentageOrAuto<'a>,
|
||||
end: LengthPercentageOrAuto<'a>,
|
||||
}
|
||||
|
||||
impl AbsoluteBoxOffsets<'_> {
|
||||
pub(crate) fn both_specified(&self) -> bool {
|
||||
!self.start.is_auto() && !self.end.is_auto()
|
||||
}
|
||||
|
||||
pub(crate) fn either_specified(&self) -> bool {
|
||||
!self.start.is_auto() || !self.end.is_auto()
|
||||
}
|
||||
}
|
||||
enum Anchor {
|
||||
Start(Au),
|
||||
End(Au),
|
||||
|
@ -781,12 +819,15 @@ struct AxisResult {
|
|||
}
|
||||
|
||||
struct AbsoluteAxisSolver<'a> {
|
||||
axis: AxisDirection,
|
||||
containing_size: Au,
|
||||
padding_border_sum: Au,
|
||||
computed_margin_start: AuOrAuto,
|
||||
computed_margin_end: AuOrAuto,
|
||||
avoid_negative_margin_start: bool,
|
||||
box_offsets: &'a AbsoluteBoxOffsets,
|
||||
box_offsets: AbsoluteBoxOffsets<'a>,
|
||||
static_position_rect_axis: RectAxis,
|
||||
alignment: AlignFlags,
|
||||
}
|
||||
|
||||
impl<'a> AbsoluteAxisSolver<'a> {
|
||||
|
@ -802,14 +843,17 @@ impl<'a> AbsoluteAxisSolver<'a> {
|
|||
///
|
||||
/// In the replaced case, `size` is never `Auto`.
|
||||
fn solve_for_size(&self, computed_size: AuOrAuto) -> AxisResult {
|
||||
match self.box_offsets {
|
||||
AbsoluteBoxOffsets::StaticStart { start } => AxisResult {
|
||||
anchor: Anchor::Start(*start),
|
||||
match (
|
||||
self.box_offsets.start.non_auto(),
|
||||
self.box_offsets.end.non_auto(),
|
||||
) {
|
||||
(None, None) => AxisResult {
|
||||
anchor: Anchor::Start(self.static_position_rect_axis.origin),
|
||||
size: computed_size,
|
||||
margin_start: self.computed_margin_start.auto_is(Au::zero),
|
||||
margin_end: self.computed_margin_end.auto_is(Au::zero),
|
||||
},
|
||||
AbsoluteBoxOffsets::Start { start } => AxisResult {
|
||||
(Some(start), None) => AxisResult {
|
||||
anchor: Anchor::Start(
|
||||
start
|
||||
.percentage_relative_to(self.containing_size.into())
|
||||
|
@ -819,7 +863,7 @@ impl<'a> AbsoluteAxisSolver<'a> {
|
|||
margin_start: self.computed_margin_start.auto_is(Au::zero),
|
||||
margin_end: self.computed_margin_end.auto_is(Au::zero),
|
||||
},
|
||||
AbsoluteBoxOffsets::End { end } => AxisResult {
|
||||
(None, Some(end)) => AxisResult {
|
||||
anchor: Anchor::End(
|
||||
end.percentage_relative_to(self.containing_size.into())
|
||||
.into(),
|
||||
|
@ -828,7 +872,7 @@ impl<'a> AbsoluteAxisSolver<'a> {
|
|||
margin_start: self.computed_margin_start.auto_is(Au::zero),
|
||||
margin_end: self.computed_margin_end.auto_is(Au::zero),
|
||||
},
|
||||
AbsoluteBoxOffsets::Both { start, end } => {
|
||||
(Some(start), Some(end)) => {
|
||||
let start = start.percentage_relative_to(self.containing_size.into());
|
||||
let end = end.percentage_relative_to(self.containing_size.into());
|
||||
|
||||
|
@ -894,6 +938,66 @@ impl<'a> AbsoluteAxisSolver<'a> {
|
|||
!self.computed_margin_start.is_auto() &&
|
||||
!self.computed_margin_end.is_auto()
|
||||
}
|
||||
|
||||
fn origin_for_alignment_or_justification(&self, margin_box_axis: RectAxis) -> Option<Au> {
|
||||
let alignment_container = match (
|
||||
self.box_offsets.start.non_auto(),
|
||||
self.box_offsets.end.non_auto(),
|
||||
) {
|
||||
(None, None) => self.static_position_rect_axis,
|
||||
(Some(start), Some(end)) => {
|
||||
let start = start.percentage_relative_to(self.containing_size.into());
|
||||
let end = end.percentage_relative_to(self.containing_size.into());
|
||||
|
||||
RectAxis {
|
||||
origin: start.into(),
|
||||
length: self.containing_size - (end + start).into(),
|
||||
}
|
||||
},
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
let mut value_after_safety = self.alignment.value();
|
||||
if self.alignment.flags() == AlignFlags::SAFE &&
|
||||
margin_box_axis.length > alignment_container.length
|
||||
{
|
||||
value_after_safety = AlignFlags::START;
|
||||
}
|
||||
|
||||
match value_after_safety {
|
||||
AlignFlags::CENTER | AlignFlags::SPACE_AROUND | AlignFlags::SPACE_EVENLY => Some(
|
||||
alignment_container.origin +
|
||||
((alignment_container.length - margin_box_axis.length) / 2),
|
||||
),
|
||||
AlignFlags::FLEX_END | AlignFlags::END => Some(
|
||||
alignment_container.origin + alignment_container.length - margin_box_axis.length,
|
||||
),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn solve_alignment(
|
||||
&self,
|
||||
margin_box_rect: LogicalRect<Au>,
|
||||
content_box_rect: &mut LogicalRect<Au>,
|
||||
) {
|
||||
let Some(new_origin) =
|
||||
self.origin_for_alignment_or_justification(margin_box_rect.get_axis(self.axis))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
match self.axis {
|
||||
AxisDirection::Block => {
|
||||
content_box_rect.start_corner.block +=
|
||||
new_origin - margin_box_rect.start_corner.block
|
||||
},
|
||||
AxisDirection::Inline => {
|
||||
content_box_rect.start_corner.inline +=
|
||||
new_origin - margin_box_rect.start_corner.inline
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn vec_append_owned<T>(a: &mut Vec<T>, mut b: Vec<T>) {
|
||||
|
|
|
@ -15,10 +15,13 @@ use style::properties::longhands::column_span::computed_value::T as ColumnSpan;
|
|||
use style::properties::ComputedValues;
|
||||
use style::values::computed::basic_shape::ClipPath;
|
||||
use style::values::computed::image::Image as ComputedImageLayer;
|
||||
use style::values::computed::{Length, LengthPercentage, NonNegativeLengthPercentage, Size};
|
||||
use style::values::computed::{
|
||||
AlignItems, Length, LengthPercentage, NonNegativeLengthPercentage, Size,
|
||||
};
|
||||
use style::values::generics::box_::Perspective;
|
||||
use style::values::generics::length::MaxSize;
|
||||
use style::values::generics::position::{GenericAspectRatio, PreferredRatio};
|
||||
use style::values::specified::align::AlignFlags;
|
||||
use style::values::specified::{box_ as stylo, Overflow};
|
||||
use style::values::CSSFloat;
|
||||
use style::Zero;
|
||||
|
@ -283,6 +286,11 @@ pub(crate) trait ComputedValuesExt {
|
|||
fn background_is_transparent(&self) -> bool;
|
||||
fn get_webrender_primitive_flags(&self) -> wr::PrimitiveFlags;
|
||||
fn bidi_control_chars(&self) -> (&'static str, &'static str);
|
||||
fn resolve_align_self(
|
||||
&self,
|
||||
resolved_auto_value: AlignItems,
|
||||
resolved_normal_value: AlignItems,
|
||||
) -> AlignItems;
|
||||
}
|
||||
|
||||
impl ComputedValuesExt for ComputedValues {
|
||||
|
@ -873,6 +881,18 @@ impl ComputedValuesExt for ComputedValues {
|
|||
(UnicodeBidi::Plaintext, _) => ("\u{2068}", "\u{2069}"),
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_align_self(
|
||||
&self,
|
||||
resolved_auto_value: AlignItems,
|
||||
resolved_normal_value: AlignItems,
|
||||
) -> AlignItems {
|
||||
match self.clone_align_self().0 .0 {
|
||||
AlignFlags::AUTO => resolved_auto_value,
|
||||
AlignFlags::NORMAL => resolved_normal_value,
|
||||
value => AlignItems(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<stylo::Display> for Display {
|
||||
|
|
|
@ -1646,7 +1646,6 @@ impl<'a> TableLayout<'a> {
|
|||
let caption_fragment = Fragment::Box(caption_fragment);
|
||||
positioning_context.adjust_static_position_of_hoisted_fragments(
|
||||
&caption_fragment,
|
||||
table_writing_mode,
|
||||
original_positioning_context_length,
|
||||
);
|
||||
Some(caption_fragment)
|
||||
|
@ -1683,7 +1682,6 @@ impl<'a> TableLayout<'a> {
|
|||
let grid_fragment = Fragment::Box(grid_fragment);
|
||||
positioning_context.adjust_static_position_of_hoisted_fragments(
|
||||
&grid_fragment,
|
||||
table_writing_mode,
|
||||
original_positioning_context_length,
|
||||
);
|
||||
table_layout.fragments.push(grid_fragment);
|
||||
|
@ -1719,7 +1717,6 @@ impl<'a> TableLayout<'a> {
|
|||
let caption_fragment = Fragment::Box(caption_fragment);
|
||||
positioning_context.adjust_static_position_of_hoisted_fragments(
|
||||
&caption_fragment,
|
||||
table_writing_mode,
|
||||
original_positioning_context_length,
|
||||
);
|
||||
Some(caption_fragment)
|
||||
|
@ -2591,10 +2588,12 @@ impl TableSlotCell {
|
|||
// TODO(mrobinson): This is correct for absolutes that are direct children of the table
|
||||
// cell, but wrong for absolute fragments that are more deeply nested in the hierarchy of
|
||||
// fragments.
|
||||
let physical_cell_rect =
|
||||
cell_content_rect.to_physical(table_style.effective_writing_mode());
|
||||
layout
|
||||
.positioning_context
|
||||
.adjust_static_position_of_hoisted_fragments_with_offset(
|
||||
&cell_content_rect.start_corner,
|
||||
&physical_cell_rect.origin.to_vector(),
|
||||
PositioningContextLength::zero(),
|
||||
);
|
||||
positioning_context.append(layout.positioning_context);
|
||||
|
@ -2603,7 +2602,7 @@ impl TableSlotCell {
|
|||
base_fragment_info,
|
||||
self.style.clone(),
|
||||
vec![Fragment::Positioning(vertical_align_fragment)],
|
||||
cell_content_rect.to_physical(table_style.effective_writing_mode()),
|
||||
physical_cell_rect,
|
||||
layout
|
||||
.padding
|
||||
.to_physical(table_style.effective_writing_mode()),
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
[safe-align-self-htb.html]
|
||||
[.item 7]
|
||||
expected: FAIL
|
||||
|
||||
[.item 8]
|
||||
expected: FAIL
|
||||
|
||||
[.item 9]
|
||||
expected: FAIL
|
||||
|
||||
[.item 10]
|
||||
expected: FAIL
|
||||
|
||||
[.item 11]
|
||||
expected: FAIL
|
||||
|
||||
[.item 12]
|
||||
expected: FAIL
|
||||
|
||||
[.item 19]
|
||||
expected: FAIL
|
||||
|
||||
[.item 20]
|
||||
expected: FAIL
|
||||
|
||||
[.item 21]
|
||||
expected: FAIL
|
||||
|
||||
[.item 22]
|
||||
expected: FAIL
|
||||
|
||||
[.item 23]
|
||||
expected: FAIL
|
||||
|
||||
[.item 24]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[flex-abspos-staticpos-fallback-justify-content-001.html]
|
||||
expected: FAIL
|
|
@ -8,24 +8,12 @@
|
|||
[.flexbox 34]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 35]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 36]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 37]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 30]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 31]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 33]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 89]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -53,18 +41,6 @@
|
|||
[.flexbox 17]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 15]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 12]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 13]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 10]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 18]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -116,9 +92,6 @@
|
|||
[.flexbox 67]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 66]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 65]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -149,9 +122,6 @@
|
|||
[.flexbox 75]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 76]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 77]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -188,9 +158,6 @@
|
|||
[.flexbox 44]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 47]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 46]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -227,21 +194,9 @@
|
|||
[.flexbox 104]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 5]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 6]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 2]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 3]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 8]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 9]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -263,35 +218,38 @@
|
|||
[.flexbox 56]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 57]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 54]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 55]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 28]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 27]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 25]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 24]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 23]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 21]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 20]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 120]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 7]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 26]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 52]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 71]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 87]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 106]
|
||||
expected: FAIL
|
||||
|
|
|
@ -5,12 +5,6 @@
|
|||
[.flexbox 4]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 3]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 2]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 8]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
[position-absolute-012.html]
|
||||
[.flexbox 38]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 39]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 35]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -38,9 +32,6 @@
|
|||
[.flexbox 85]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 84]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 86]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -50,33 +41,15 @@
|
|||
[.flexbox 14]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 12]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 13]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 10]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 11]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 18]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 19]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 96]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 94]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 92]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 93]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -86,12 +59,6 @@
|
|||
[.flexbox 91]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 63]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 62]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 61]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -107,9 +74,6 @@
|
|||
[.flexbox 69]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 68]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 70]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -122,9 +86,6 @@
|
|||
[.flexbox 75]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 76]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 77]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -137,12 +98,6 @@
|
|||
[.flexbox 44]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 47]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 46]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 41]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -152,21 +107,12 @@
|
|||
[.flexbox 49]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 4]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 5]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 6]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 2]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 3]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 8]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -185,24 +131,9 @@
|
|||
[.flexbox 57]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 54]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 55]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 29]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 28]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 27]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 26]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 24]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -212,5 +143,50 @@
|
|||
[.flexbox 21]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 20]
|
||||
[.flexbox 7]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 15]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 23]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 31]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 34]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 40]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 42]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 48]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 50]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 56]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 58]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 64]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 71]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 79]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 87]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 95]
|
||||
expected: FAIL
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
[.flexbox 302]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 305]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 304]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -17,12 +14,6 @@
|
|||
[.flexbox 306]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 38]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 39]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 34]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -32,9 +23,6 @@
|
|||
[.flexbox 36]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 37]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 32]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -53,9 +41,6 @@
|
|||
[.flexbox 393]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 390]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 391]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -65,21 +50,9 @@
|
|||
[.flexbox 275]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 274]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 277]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 276]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 272]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 374]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 375]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -95,9 +68,6 @@
|
|||
[.flexbox 373]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 89]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 80]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -107,27 +77,15 @@
|
|||
[.flexbox 82]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 85]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 84]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 87]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 86]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 182]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 180]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 187]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 186]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -137,33 +95,15 @@
|
|||
[.flexbox 184]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 189]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 118]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 119]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 111]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 112]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 113]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 114]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 116]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 239]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 238]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -176,15 +116,9 @@
|
|||
[.flexbox 232]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 235]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 234]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 237]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 331]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -212,9 +146,6 @@
|
|||
[.flexbox 46]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 41]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 43]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -224,9 +155,6 @@
|
|||
[.flexbox 248]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 249]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 244]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -236,9 +164,6 @@
|
|||
[.flexbox 246]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 247]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 240]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -302,21 +227,9 @@
|
|||
[.flexbox 389]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 388]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 200]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 201]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 202]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 204]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 205]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -335,24 +248,15 @@
|
|||
[.flexbox 363]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 362]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 361]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 360]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 99]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 96]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 97]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 94]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -368,9 +272,6 @@
|
|||
[.flexbox 72]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 73]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 428]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -380,15 +281,9 @@
|
|||
[.flexbox 420]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 421]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 422]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 423]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 424]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -398,27 +293,12 @@
|
|||
[.flexbox 427]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 293]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 109]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 108]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 103]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 102]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 101]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 100]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 106]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -440,9 +320,6 @@
|
|||
[.flexbox 327]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 326]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 325]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -455,30 +332,15 @@
|
|||
[.flexbox 59]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 52]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 53]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 50]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 56]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 57]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 54]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 55]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 259]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 258]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -494,12 +356,6 @@
|
|||
[.flexbox 253]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 251]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 411]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 410]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -524,63 +380,30 @@
|
|||
[.flexbox 171]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 177]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 174]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 175]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 178]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 179]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 16]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 17]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 14]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 11]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 18]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 19]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 213]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 212]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 211]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 217]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 216]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 214]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 352]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 353]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 219]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -599,21 +422,9 @@
|
|||
[.flexbox 358]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 62]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 67]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 66]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 65]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 64]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 280]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -623,12 +434,6 @@
|
|||
[.flexbox 282]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 284]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 286]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 287]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -641,42 +446,21 @@
|
|||
[.flexbox 359]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 288]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 136]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 134]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 135]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 132]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 133]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 130]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 131]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 138]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 139]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 317]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 314]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 315]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -695,18 +479,6 @@
|
|||
[.flexbox 69]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 29]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 27]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 26]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 25]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 24]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -722,15 +494,9 @@
|
|||
[.flexbox 269]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 263]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 260]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 261]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 266]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -749,21 +515,12 @@
|
|||
[.flexbox 404]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 402]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 400]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 401]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 190]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 191]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 192]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -788,18 +545,9 @@
|
|||
[.flexbox 169]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 168]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 165]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 164]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 166]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 161]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -812,18 +560,9 @@
|
|||
[.flexbox 226]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 227]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 225]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 222]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 223]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 220]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -836,9 +575,6 @@
|
|||
[.flexbox 347]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 341]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 340]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -857,15 +593,6 @@
|
|||
[.flexbox 299]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 74]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 75]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 77]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 292]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -887,33 +614,15 @@
|
|||
[.flexbox 368]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 4]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 5]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 6]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 7]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 2]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 8]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 9]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 154]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 156]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 157]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -923,9 +632,6 @@
|
|||
[.flexbox 151]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 152]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 153]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -938,29 +644,221 @@
|
|||
[.flexbox 408]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 409]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 121]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 120]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 123]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 122]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 124]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 127]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 126]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 129]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 10]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 12]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 20]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 31]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 33]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 47]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 58]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 60]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 68]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 79]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 81]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 95]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 107]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 115]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 117]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 128]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 142]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 144]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 146]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 155]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 160]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 162]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 167]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 173]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 176]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 181]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 183]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 188]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 194]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 203]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 208]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 210]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 215]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 221]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 224]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 229]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 231]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 236]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 241]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 243]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 250]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 252]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 257]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 262]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 264]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 268]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 270]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 271]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 273]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 278]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 283]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 285]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 298]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 300]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 308]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 319]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 321]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 335]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 346]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 348]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 356]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 367]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 369]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 383]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 395]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 403]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 405]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 416]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 430]
|
||||
expected: FAIL
|
||||
|
||||
[.flexbox 432]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
[position-absolute-015.html]
|
||||
[#abspos 1]
|
||||
expected: FAIL
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[position-absolute-containing-block-001.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[position-absolute-center-003.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[position-absolute-center-004.html]
|
||||
expected: FAIL
|
Loading…
Add table
Add a link
Reference in a new issue