mirror of
https://github.com/servo/servo.git
synced 2025-09-17 02:18:23 +01:00
layout: Ensure IFC for abspos with inline-level original display (#39041)
Absolutely positioned elements get blockified, but their static position still depends on the original display. Therefore, if we encounter an abspos with an inline-level original display, we will now ensure that it's handled in an inline formatting context. This way its static position will correctly take into account things like `text-align`. Testing: Several WPT tests are now passing. Fixes: #39017 Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
665ee150a6
commit
9264ef1a95
17 changed files with 42 additions and 44 deletions
|
@ -10,6 +10,7 @@ use style::properties::ComputedValues;
|
||||||
use style::properties::longhands::list_style_position::computed_value::T as ListStylePosition;
|
use style::properties::longhands::list_style_position::computed_value::T as ListStylePosition;
|
||||||
use style::selector_parser::PseudoElement;
|
use style::selector_parser::PseudoElement;
|
||||||
use style::str::char_is_whitespace;
|
use style::str::char_is_whitespace;
|
||||||
|
use style::values::specified::box_::DisplayOutside as StyloDisplayOutside;
|
||||||
|
|
||||||
use super::OutsideMarker;
|
use super::OutsideMarker;
|
||||||
use super::inline::construct::InlineFormattingContextBuilder;
|
use super::inline::construct::InlineFormattingContextBuilder;
|
||||||
|
@ -587,22 +588,34 @@ impl<'dom> BlockContainerBuilder<'dom, '_> {
|
||||||
contents: Contents,
|
contents: Contents,
|
||||||
box_slot: BoxSlot<'dom>,
|
box_slot: BoxSlot<'dom>,
|
||||||
) {
|
) {
|
||||||
if let Some(builder) = self.inline_formatting_context_builder.as_mut() {
|
// If the original display was inline-level, then we need an inline formatting context
|
||||||
if !builder.is_empty {
|
// in order to compute the static position correctly.
|
||||||
let constructor = || {
|
// If it was block-level, we don't want to break an existing inline formatting context,
|
||||||
ArcRefCell::new(AbsolutelyPositionedBox::construct(
|
// so push it there (`LineItemLayout::layout_absolute` can handle this well). But if
|
||||||
self.context,
|
// there is no inline formatting context, then we can avoid creating one.
|
||||||
info,
|
let needs_inline_builder =
|
||||||
display_inside,
|
info.style.get_box().original_display.outside() == StyloDisplayOutside::Inline;
|
||||||
contents,
|
if needs_inline_builder {
|
||||||
))
|
self.ensure_inline_formatting_context_builder();
|
||||||
};
|
}
|
||||||
let old_layout_box = box_slot.take_layout_box_if_undamaged(info.damage);
|
let inline_builder = self
|
||||||
let inline_level_box =
|
.inline_formatting_context_builder
|
||||||
builder.push_absolutely_positioned_box(constructor, old_layout_box);
|
.as_mut()
|
||||||
box_slot.set(LayoutBox::InlineLevel(vec![inline_level_box]));
|
.filter(|builder| needs_inline_builder || !builder.is_empty);
|
||||||
return;
|
if let Some(inline_builder) = inline_builder {
|
||||||
}
|
let constructor = || {
|
||||||
|
ArcRefCell::new(AbsolutelyPositionedBox::construct(
|
||||||
|
self.context,
|
||||||
|
info,
|
||||||
|
display_inside,
|
||||||
|
contents,
|
||||||
|
))
|
||||||
|
};
|
||||||
|
let old_layout_box = box_slot.take_layout_box_if_undamaged(info.damage);
|
||||||
|
let inline_level_box =
|
||||||
|
inline_builder.push_absolutely_positioned_box(constructor, old_layout_box);
|
||||||
|
box_slot.set(LayoutBox::InlineLevel(vec![inline_level_box]));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let kind = BlockLevelCreator::OutOfFlowAbsolutelyPositionedBox {
|
let kind = BlockLevelCreator::OutOfFlowAbsolutelyPositionedBox {
|
||||||
|
|
|
@ -15,6 +15,7 @@ use servo_arc::Arc;
|
||||||
use style::dom::{NodeInfo, TNode};
|
use style::dom::{NodeInfo, TNode};
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::values::computed::Overflow;
|
use style::values::computed::Overflow;
|
||||||
|
use style::values::specified::box_::DisplayOutside;
|
||||||
use style_traits::CSSPixel;
|
use style_traits::CSSPixel;
|
||||||
|
|
||||||
use crate::cell::ArcRefCell;
|
use crate::cell::ArcRefCell;
|
||||||
|
@ -338,6 +339,12 @@ impl<'dom> IncrementalBoxTreeUpdate<'dom> {
|
||||||
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(_)
|
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(_)
|
||||||
if box_style.position.is_absolutely_positioned() =>
|
if box_style.position.is_absolutely_positioned() =>
|
||||||
{
|
{
|
||||||
|
// If the outer type of its original display changed from block to inline,
|
||||||
|
// a block-level abspos needs to be placed in an inline formatting context,
|
||||||
|
// see [`BlockContainerBuilder::handle_absolutely_positioned_element()`].
|
||||||
|
if box_style.original_display.outside() == DisplayOutside::Inline {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
DirtyRootBoxTreeNode::AbsolutelyPositionedBlockLevelBox(
|
DirtyRootBoxTreeNode::AbsolutelyPositionedBlockLevelBox(
|
||||||
block_level_box.clone(),
|
block_level_box.clone(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -615,6 +615,12 @@ impl<'dom> style::dom::TElement for ServoLayoutElement<'dom> {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if new_box.position.is_absolutely_positioned() &&
|
||||||
|
old_box.original_display != new_box.original_display
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if old.get_font() != new.get_font() {
|
if old.get_font() != new.get_font() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[position-absolute-dynamic-static-position-floats-001.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[position-absolute-dynamic-static-position-floats-002.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[position-absolute-dynamic-static-position-floats-003.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[position-absolute-dynamic-static-position-floats-004.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[inline-level-absolute-in-block-level-context-001.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[inline-level-absolute-in-block-level-context-002.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[inline-level-absolute-in-block-level-context-003.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[inline-level-absolute-in-block-level-context-005.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[inline-level-absolute-in-block-level-context-006.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[inline-level-absolute-in-block-level-context-008.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[inline-level-absolute-in-block-level-context-009.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[inline-level-absolute-in-block-level-context-010.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[inline-level-absolute-in-block-level-context-011.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[inline-level-absolute-in-block-level-context-012.html]
|
|
||||||
expected: FAIL
|
|
Loading…
Add table
Add a link
Reference in a new issue