mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
layout: Check if root before establishing containing block (#36360)
As per [w3.org/TR/filter-effects-1#FilterProperty](https://www.w3.org/TR/filter-effects-1/#FilterProperty), `filter` shouldn't make the root element establish a containing block for absolute and fixed positioned descendants. `will-change: filter` has matching behavior. This PR adds a check for if we are the root element before establishing such a block. To know if we are the root element, we look at the `FragmentFlags` passed in. Previously for our function, these were dummy flags, always constructed as empty. Thus, this PR also makes sure the correct FragmentFlags are passed down the chain to the function `establishes_containing_block_for_all_descendants`. Testing: - `/css/filter-effects/filtered-html-is-not-container.html` now passes - `/css/css-will-change/will-change-fixedpos-cb-003.html` now passes - Manual tests are working Fixes: #35391 --------- Signed-off-by: haval0 <56519858+haval0@users.noreply.github.com> Signed-off-by: Oriol Brufau <obrufau@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
bab788f5d5
commit
ec88b5d752
11 changed files with 44 additions and 35 deletions
|
@ -29,6 +29,7 @@ use crate::geom::{
|
|||
PhysicalPoint, PhysicalRect, PhysicalSides, PhysicalSize, PhysicalVec, Size, Sizes, ToLogical,
|
||||
ToLogicalWithContainingBlock,
|
||||
};
|
||||
use crate::layout_box_base::LayoutBoxBase;
|
||||
use crate::sizing::ContentSizes;
|
||||
use crate::style_ext::{Clamp, ComputedValuesExt, ContentBoxSizesAndPBM, DisplayInside};
|
||||
use crate::{
|
||||
|
@ -103,6 +104,20 @@ impl AbsolutelyPositionedBox {
|
|||
}
|
||||
}
|
||||
|
||||
impl IndependentFormattingContext {
|
||||
#[inline]
|
||||
pub(crate) fn new_positioning_context(&self) -> Option<PositioningContext> {
|
||||
self.base.new_positioning_context()
|
||||
}
|
||||
}
|
||||
|
||||
impl LayoutBoxBase {
|
||||
#[inline]
|
||||
pub(crate) fn new_positioning_context(&self) -> Option<PositioningContext> {
|
||||
PositioningContext::new_for_style(&self.style, &self.base_fragment_info.flags)
|
||||
}
|
||||
}
|
||||
|
||||
impl PositioningContext {
|
||||
pub(crate) fn new_for_containing_block_for_all_descendants() -> Self {
|
||||
Self {
|
||||
|
@ -130,14 +145,10 @@ impl PositioningContext {
|
|||
self.for_nearest_positioned_ancestor.is_some()
|
||||
}
|
||||
|
||||
pub(crate) fn new_for_style(style: &ComputedValues) -> Option<Self> {
|
||||
// NB: We never make PositioningContexts for replaced elements, which is why we always
|
||||
// pass false here.
|
||||
if style.establishes_containing_block_for_all_descendants(FragmentFlags::empty()) {
|
||||
fn new_for_style(style: &ComputedValues, flags: &FragmentFlags) -> Option<Self> {
|
||||
if style.establishes_containing_block_for_all_descendants(*flags) {
|
||||
Some(Self::new_for_containing_block_for_all_descendants())
|
||||
} else if style
|
||||
.establishes_containing_block_for_absolute_descendants(FragmentFlags::empty())
|
||||
{
|
||||
} else if style.establishes_containing_block_for_absolute_descendants(*flags) {
|
||||
Some(Self {
|
||||
for_nearest_positioned_ancestor: Some(Vec::new()),
|
||||
for_nearest_containing_block_for_all_descendants: Vec::new(),
|
||||
|
@ -213,12 +224,12 @@ impl PositioningContext {
|
|||
&mut self,
|
||||
layout_context: &LayoutContext,
|
||||
containing_block: &ContainingBlock,
|
||||
style: &ComputedValues,
|
||||
base: &LayoutBoxBase,
|
||||
fragment_layout_fn: impl FnOnce(&mut Self) -> BoxFragment,
|
||||
) -> BoxFragment {
|
||||
// Try to create a context, but if one isn't necessary, simply create the fragment
|
||||
// using the given closure and the current `PositioningContext`.
|
||||
let mut new_context = match Self::new_for_style(style) {
|
||||
let mut new_context = match base.new_positioning_context() {
|
||||
Some(new_context) => new_context,
|
||||
None => return fragment_layout_fn(self),
|
||||
};
|
||||
|
@ -229,9 +240,8 @@ impl PositioningContext {
|
|||
// If the new context has any hoisted boxes for the nearest containing block for
|
||||
// pass them up the tree.
|
||||
self.append(new_context);
|
||||
|
||||
if style.clone_position() == Position::Relative {
|
||||
new_fragment.content_rect.origin += relative_adjustement(style, containing_block)
|
||||
if base.style.clone_position() == Position::Relative {
|
||||
new_fragment.content_rect.origin += relative_adjustement(&base.style, containing_block)
|
||||
.to_physical_vector(containing_block.style.writing_mode)
|
||||
}
|
||||
|
||||
|
@ -586,7 +596,7 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
.sizes
|
||||
}));
|
||||
|
||||
let mut positioning_context = PositioningContext::new_for_style(&style).unwrap();
|
||||
let mut positioning_context = context.new_positioning_context().unwrap();
|
||||
let mut new_fragment = {
|
||||
let content_size: LogicalVec2<Au>;
|
||||
let fragments;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue