Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Layout `position: fixed` in the initial containing block #25273

Merged
merged 13 commits into from Dec 13, 2019
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Make `for_maybe_position_relative` take care of relative adjustment.

  • Loading branch information
SimonSapin committed Dec 13, 2019
commit 58b7005a9bb0e6c7a4c339bf82abec9b3b20eef2
@@ -9,10 +9,10 @@ use crate::formatting_contexts::IndependentFormattingContext;
use crate::fragments::CollapsedBlockMargins;
use crate::fragments::{AnonymousFragment, BoxFragment, Fragment, TextFragment};
use crate::geom::flow_relative::{Rect, Sides, Vec2};
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
use crate::positioned::{relative_adjustement, AbsolutelyPositionedBox, PositioningContext};
use crate::sizing::ContentSizes;
use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, DisplayOutside};
use crate::{relative_adjustement, ContainingBlock};
use crate::ContainingBlock;
use app_units::Au;
use gfx::text::text_run::GlyphRun;
use servo_arc::Arc;
@@ -367,11 +367,9 @@ impl InlineBox {
block: padding.block_start + border.block_start + margin.block_start,
inline: ifc.inline_position - ifc.current_nesting_level.inline_start,
};
start_corner += &relative_adjustement(
&style,
ifc.containing_block.inline_size,
ifc.containing_block.block_size,
);
if style.clone_position().is_relative() {
start_corner += &relative_adjustement(&style, ifc.containing_block)
}
PartialInlineBoxFragment {
style,
start_corner,
@@ -457,11 +455,9 @@ fn layout_atomic<'box_tree>(
block: pbm.block_start,
inline: ifc.inline_position - ifc.current_nesting_level.inline_start,
};
start_corner += &relative_adjustement(
&atomic.style,
ifc.containing_block.inline_size,
ifc.containing_block.block_size,
);
if atomic.style.clone_position().is_relative() {
start_corner += &relative_adjustement(&atomic.style, ifc.containing_block)
}

let fragment = match atomic.as_replaced() {
Ok(replaced) => {
@@ -14,7 +14,7 @@ use crate::geom::flow_relative::{Rect, Sides, Vec2};
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
use crate::replaced::ReplacedContent;
use crate::style_ext::ComputedValuesExt;
use crate::{relative_adjustement, ContainingBlock};
use crate::ContainingBlock;
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
use rayon_croissant::ParallelIteratorExt;
use servo_arc::Arc;
@@ -271,6 +271,7 @@ impl BlockLevelBox {
BlockLevelBox::SameFormattingContextBlock { style, contents } => {
Fragment::Box(positioning_context.for_maybe_position_relative(
layout_context,
containing_block,
style,
|positioning_context| {
layout_in_flow_non_replaced_block_level(
@@ -288,6 +289,7 @@ impl BlockLevelBox {
BlockLevelBox::Independent(contents) => {
Fragment::Box(positioning_context.for_maybe_position_relative(
layout_context,
containing_block,
&contents.style,
|positioning_context| match contents.as_replaced() {
Ok(replaced) => layout_in_flow_replaced_block_level(
@@ -470,14 +472,13 @@ fn layout_in_flow_non_replaced_block_level<'a>(
content_block_size = independent_layout.content_block_size;
},
};
let relative_adjustement = relative_adjustement(style, inline_size, block_size);
let block_size = block_size.auto_is(|| {
content_block_size.clamp_between_extremums(min_box_size.block, max_box_size.block)
});
let content_rect = Rect {
start_corner: Vec2 {
block: pb.block_start + relative_adjustement.block,
inline: pb.inline_start + relative_adjustement.inline + margin.inline_start,
block: pb.block_start,
inline: pb.inline_start,
},
size: Vec2 {
block: block_size,
@@ -525,15 +526,10 @@ fn layout_in_flow_replaced_block_level<'a>(
block_end: computed_margin.block_end.auto_is(Length::zero),
};
let fragments = replaced.make_fragments(style, size.clone());
let relative_adjustement = relative_adjustement(
style,
size.inline,
LengthOrAuto::LengthPercentage(size.block),
);
let content_rect = Rect {
start_corner: Vec2 {
block: pb.block_start + relative_adjustement.block,
inline: pb.inline_start + relative_adjustement.inline + margin.inline_start,
block: pb.block_start,
inline: pb.inline_start + margin.inline_start,
},
size,
};
@@ -27,11 +27,8 @@ pub mod wrapper;
pub use flow::{BoxTreeRoot, FragmentTreeRoot};

use crate::geom::flow_relative::Vec2;
use crate::style_ext::ComputedValuesExt;
use style::computed_values::position::T as Position;
use style::properties::ComputedValues;
use style::values::computed::{Length, LengthOrAuto};
use style::Zero;

struct ContainingBlock<'a> {
inline_size: Length,
@@ -53,30 +50,3 @@ impl<'a> From<&'_ DefiniteContainingBlock<'a>> for ContainingBlock<'a> {
}
}
}

/// https://drafts.csswg.org/css2/visuren.html#relative-positioning
fn relative_adjustement(
style: &ComputedValues,
inline_size: Length,
block_size: LengthOrAuto,
) -> Vec2<Length> {
if style.get_box().position != Position::Relative {
return Vec2::zero();
}
fn adjust(start: LengthOrAuto, end: LengthOrAuto) -> Length {
match (start, end) {
(LengthOrAuto::Auto, LengthOrAuto::Auto) => Length::zero(),
(LengthOrAuto::Auto, LengthOrAuto::LengthPercentage(end)) => -end,
(LengthOrAuto::LengthPercentage(start), _) => start,
}
}
let block_size = block_size.auto_is(Length::zero);
let box_offsets = style.box_offsets().map_inline_and_block_axes(
|v| v.percentage_relative_to(inline_size),
|v| v.percentage_relative_to(block_size),
);
Vec2 {
inline: adjust(box_offsets.inline_start, box_offsets.inline_end),
block: adjust(box_offsets.block_start, box_offsets.block_end),
}
}
@@ -150,11 +150,17 @@ impl<'box_tree> PositioningContext<'box_tree> {
pub(crate) fn for_maybe_position_relative(
&mut self,
layout_context: &LayoutContext,
containing_block: &ContainingBlock,
style: &ComputedValues,
f: impl FnOnce(&mut Self) -> BoxFragment,
) -> BoxFragment {
if style.clone_position() == Position::Relative {
Self::for_positioned(layout_context, &mut self.for_initial_containing_block, f)
let mut fragment =
// Establing a containing block for absolutely positioned descendants
Self::for_positioned(layout_context, &mut self.for_initial_containing_block, f);

fragment.content_rect.start_corner += &relative_adjustement(style, containing_block);
fragment
} else {
f(self)
}
@@ -610,3 +616,27 @@ fn vec_append_owned<T>(a: &mut Vec<T>, mut b: Vec<T>) {
a.append(&mut b)
}
}

/// https://drafts.csswg.org/css2/visuren.html#relative-positioning
pub(crate) fn relative_adjustement(
style: &ComputedValues,
containing_block: &ContainingBlock,
) -> Vec2<Length> {
let cbis = containing_block.inline_size;
let cbbs = containing_block.block_size.auto_is(Length::zero);
let box_offsets = style.box_offsets().map_inline_and_block_axes(
|v| v.percentage_relative_to(cbis),
|v| v.percentage_relative_to(cbbs),
);
fn adjust(start: LengthOrAuto, end: LengthOrAuto) -> Length {
match (start, end) {
(LengthOrAuto::Auto, LengthOrAuto::Auto) => Length::zero(),
(LengthOrAuto::Auto, LengthOrAuto::LengthPercentage(end)) => -end,
(LengthOrAuto::LengthPercentage(start), _) => start,
}
}
Vec2 {
inline: adjust(box_offsets.inline_start, box_offsets.inline_end),
block: adjust(box_offsets.block_start, box_offsets.block_end),
}
}
@@ -55,6 +55,9 @@ impl computed_value::T {
pub fn is_absolutely_positioned(self) -> bool {
matches!(self, Self::Absolute | Self::Fixed)
}
pub fn is_relative(self) -> bool {
self == Self::Relative
}
}
</%helpers:single_keyword>

This file was deleted.

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.