mirror of
https://github.com/lexmount/moli.git
synced 2026-10-30 16:07:24 +00:00
fix(layout): retain grid track areas for positioned descendants
This commit is contained in:
@@ -8,7 +8,7 @@ use crate::{
|
||||
|
||||
pub(crate) fn project_resolved_grid_tracks(
|
||||
style: &taffy::Style<Atom>,
|
||||
detailed: taffy::DetailedGridInfo<Atom>,
|
||||
detailed: &taffy::DetailedGridInfo<Atom>,
|
||||
) -> Option<LayoutResolvedGridTracks> {
|
||||
let row_line_names = expanded_line_names(
|
||||
&style.grid_template_rows,
|
||||
@@ -23,13 +23,13 @@ pub(crate) fn project_resolved_grid_tracks(
|
||||
usize::from(detailed.columns.auto_repetitions),
|
||||
)?;
|
||||
Some(LayoutResolvedGridTracks {
|
||||
rows: project_tracks(detailed.rows, row_line_names)?,
|
||||
columns: project_tracks(detailed.columns, column_line_names)?,
|
||||
rows: project_tracks(&detailed.rows, row_line_names)?,
|
||||
columns: project_tracks(&detailed.columns, column_line_names)?,
|
||||
})
|
||||
}
|
||||
|
||||
fn project_tracks(
|
||||
tracks: taffy::DetailedGridTracksInfo<Atom>,
|
||||
tracks: &taffy::DetailedGridTracksInfo<Atom>,
|
||||
explicit_line_names: Vec<Vec<Atom>>,
|
||||
) -> Option<LayoutResolvedGridTrackList> {
|
||||
let track_count = usize::from(tracks.negative_implicit_tracks)
|
||||
@@ -42,7 +42,7 @@ fn project_tracks(
|
||||
}
|
||||
let used_track_sizes = tracks
|
||||
.positions
|
||||
.into_iter()
|
||||
.iter()
|
||||
.map(|position| to_blink_layout_unit(position.end - position.start))
|
||||
.collect::<Option<Vec<_>>>()?;
|
||||
Some(LayoutResolvedGridTrackList {
|
||||
|
||||
@@ -139,6 +139,7 @@ where
|
||||
N: Copy + Debug + Eq + Hash,
|
||||
{
|
||||
world.resolved_grid_tracks.clear();
|
||||
world.native_grid_details.clear();
|
||||
for index in 0..world.boxes.len() {
|
||||
world.clear_layout_caches(LayoutBoxId::from_index(index));
|
||||
let layout_box = &mut world.boxes[index];
|
||||
@@ -1907,25 +1908,33 @@ where
|
||||
node_id: NodeId,
|
||||
detailed_grid_info: DetailedGridInfo<Atom>,
|
||||
) {
|
||||
let layout_box = &self.boxes[LayoutBoxId::from_taffy(node_id).index()];
|
||||
if layout_box
|
||||
let id = LayoutBoxId::from_taffy(node_id);
|
||||
let layout_box = &self.boxes[id.index()];
|
||||
let expose_to_cssom = !layout_box
|
||||
.capability_diagnostics
|
||||
.contains(&LayoutCapabilityDiagnostic::GridTemplateModeDeferred)
|
||||
// The current backend reports detailed Grid tracks in physical
|
||||
// axes. Publishing them for a vertical container would expose its
|
||||
// width as the used `grid-template-columns` inline size. Keep the
|
||||
// computed value until logical Grid constraints land in Taffy.
|
||||
|| !layout_box.style.uses_horizontal_writing_mode()
|
||||
{
|
||||
return;
|
||||
&& layout_box.style.uses_horizontal_writing_mode();
|
||||
let resolved_grid_tracks = expose_to_cssom
|
||||
.then(|| {
|
||||
crate::grid::project_resolved_grid_tracks(
|
||||
&layout_box.style.taffy,
|
||||
&detailed_grid_info,
|
||||
)
|
||||
})
|
||||
.flatten();
|
||||
// The native OOF pass needs these positions even when the browser's
|
||||
// CSSOM projection deliberately retains the computed track value.
|
||||
self.native_grid_details.insert(
|
||||
id,
|
||||
taffy::DetailedLayoutInfo::Grid(Box::new(detailed_grid_info)),
|
||||
);
|
||||
if let Some(tracks) = resolved_grid_tracks {
|
||||
self.resolved_grid_tracks.insert(id, tracks);
|
||||
}
|
||||
let Some(resolved_grid_tracks) =
|
||||
crate::grid::project_resolved_grid_tracks(&layout_box.style.taffy, detailed_grid_info)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
self.resolved_grid_tracks
|
||||
.insert(LayoutBoxId::from_taffy(node_id), resolved_grid_tracks);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3270,6 +3279,14 @@ impl<N: Copy + Debug + Eq + Hash> taffy::LayoutContainingBlock for LayoutWorld<N
|
||||
fn get_oof_item_style(&self, node: NodeId) -> Self::OofItemStyle<'_> {
|
||||
self.get_core_container_style(node)
|
||||
}
|
||||
fn get_detailed_layout_info(&self, node: NodeId) -> &taffy::DetailedLayoutInfo<Atom> {
|
||||
if self.is_viewport_taffy_node(node) {
|
||||
return &taffy::DetailedLayoutInfo::None;
|
||||
}
|
||||
self.native_grid_details
|
||||
.get(&LayoutBoxId::from_taffy(node))
|
||||
.unwrap_or(&taffy::DetailedLayoutInfo::None)
|
||||
}
|
||||
fn get_containing_block_claims(&self, _: NodeId) -> taffy::ContainingBlockClaims {
|
||||
// prepare_layout_tree has already attached every positioned box to
|
||||
// its CSS containing block. Internal static-position probes retain
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::{collections::HashMap, fmt::Debug, hash::Hash, num::NonZeroU32, sync::Arc};
|
||||
|
||||
use style::Atom;
|
||||
use taffy::{Cache, Layout, Point, Style};
|
||||
use taffy::{Cache, DetailedLayoutInfo, Layout, Point, Style};
|
||||
|
||||
use crate::{
|
||||
LayoutCssImageReference, LayoutElementSemantics, LayoutError, LayoutPoint, LayoutPseudo,
|
||||
@@ -639,6 +639,8 @@ where
|
||||
/// Used Grid tracks for actual owners. Their canonical result is frozen
|
||||
/// for CSSOM before this pass-local map is released.
|
||||
pub(crate) resolved_grid_tracks: HashMap<LayoutBoxId, LayoutResolvedGridTracks>,
|
||||
/// Native track positions and names read by Taffy's out-of-flow pass.
|
||||
pub(crate) native_grid_details: HashMap<LayoutBoxId, DetailedLayoutInfo<Atom>>,
|
||||
pub(crate) source_mapping: HashMap<N, LayoutBoxId>,
|
||||
pub(crate) display_contents_mapping: HashMap<N, Vec<LayoutBoxId>>,
|
||||
pub(crate) root: LayoutBoxId,
|
||||
@@ -669,6 +671,7 @@ where
|
||||
box_caches: Vec::new(),
|
||||
collapsed_table_borders: HashMap::new(),
|
||||
resolved_grid_tracks: HashMap::new(),
|
||||
native_grid_details: HashMap::new(),
|
||||
source_mapping: HashMap::new(),
|
||||
display_contents_mapping: HashMap::new(),
|
||||
root: LayoutBoxId::from_index(0),
|
||||
|
||||
@@ -709,6 +709,73 @@ fn grid_item_placement_and_self_alignment_use_the_selected_grid_area() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn absolute_grid_items_use_retained_track_areas_in_both_directions() {
|
||||
for (direction, x) in [
|
||||
(taffy::Direction::Ltr, 135.0),
|
||||
(taffy::Direction::Rtl, 95.0),
|
||||
] {
|
||||
let source = FixtureSource {
|
||||
nodes: vec![
|
||||
FixtureNode::div("grid", vec![1]),
|
||||
FixtureNode::div("positioned", Vec::new()),
|
||||
],
|
||||
};
|
||||
let mut styles = FixtureStyles::default();
|
||||
styles.0.insert(
|
||||
0,
|
||||
resolved(
|
||||
LayoutDisplay::Grid,
|
||||
Style {
|
||||
display: Display::Grid,
|
||||
direction,
|
||||
box_sizing: BoxSizing::ContentBox,
|
||||
size: Size {
|
||||
width: length(400.0),
|
||||
height: length(300.0),
|
||||
},
|
||||
padding: Rect::length(10.0),
|
||||
border: Rect::length(5.0),
|
||||
gap: Size {
|
||||
width: length(20.0),
|
||||
height: length(10.0),
|
||||
},
|
||||
grid_template_columns: vec![length(100.0), length(200.0)],
|
||||
grid_template_rows: vec![length(50.0), length(100.0)],
|
||||
..Style::default()
|
||||
},
|
||||
PaintColor::TRANSPARENT,
|
||||
)
|
||||
.with_position(LayoutPosition::Relative),
|
||||
);
|
||||
styles.0.insert(
|
||||
1,
|
||||
resolved(
|
||||
LayoutDisplay::Block,
|
||||
Style {
|
||||
inset: Rect::length(0.0),
|
||||
grid_column: Line {
|
||||
start: line(2),
|
||||
end: line(3),
|
||||
},
|
||||
grid_row: Line {
|
||||
start: line(2),
|
||||
end: line(3),
|
||||
},
|
||||
..Style::default()
|
||||
},
|
||||
RED,
|
||||
)
|
||||
.with_position(LayoutPosition::Absolute),
|
||||
);
|
||||
let snapshot = render(&source, &mut styles, PaintViewport::new(800, 600, 1.0));
|
||||
assert_rect(
|
||||
solid_rect(&snapshot, RED),
|
||||
PaintRect::new(x, 75.0, 200.0, 100.0),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grid_container_justify_items_center_shrink_wraps_an_auto_sized_item() {
|
||||
let source = FixtureSource {
|
||||
|
||||
Reference in New Issue
Block a user