Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 23 additions & 9 deletions Libraries/LibWeb/Rust/src/layout/flex_formatting_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ struct FlexItem<'pass> {
padding: DirectionAgnosticMargins,
is_min_violation: bool,
is_max_violation: bool,
content_baselines: DerivedBaselines,
}

impl<'pass> FlexItem<'pass> {
Expand Down Expand Up @@ -94,6 +95,7 @@ impl<'pass> FlexItem<'pass> {
padding: DirectionAgnosticMargins::default(),
is_min_violation: false,
is_max_violation: false,
content_baselines: DerivedBaselines::default(),
}
}

Expand Down Expand Up @@ -2295,8 +2297,16 @@ impl<'pass> FlexFormattingContext<'pass> {
}
}

fn box_baseline(&self, node: Node) -> CssPixels {
crate::layout::box_baseline(self.state, &self.callbacks, node, crate::layout::BaselineSet::First)
fn item_box_baseline(&self, index: usize) -> CssPixels {
let item = &self.flex_items[index];
crate::layout::box_baseline_with_content_baselines(
self.state,
&self.callbacks,
item.box_,
item.used_values,
crate::layout::BaselineSet::First,
item.content_baselines,
)
}

// https://drafts.csswg.org/css-flexbox-1/#valdef-align-items-baseline
Expand All @@ -2319,13 +2329,13 @@ impl<'pass> FlexFormattingContext<'pass> {
let mut max_baseline = CssPixels::default();
for index in self.flex_lines[line_index].items.iter().copied() {
if participates(self, index) {
max_baseline = max_baseline.max(self.box_baseline(self.flex_items[index].box_));
max_baseline = max_baseline.max(self.item_box_baseline(index));
}
}
for item_position in 0..self.flex_lines[line_index].items.len() {
let index = self.flex_lines[line_index].items[item_position];
if participates(self, index) {
let baseline = self.box_baseline(self.flex_items[index].box_);
let baseline = self.item_box_baseline(index);
self.flex_items[index].cross_offset += max_baseline - baseline;
}
}
Expand Down Expand Up @@ -2387,11 +2397,15 @@ impl<'pass> FlexFormattingContext<'pass> {
input.sizing.forced_min_border_box_block_size = Some(intrinsic_size + extra);
}

match crate::layout::layout_inside_child(run, None, None, node, LayoutMode::Normal, input, false) {
crate::layout::ChildLayoutOutcome::Created(_) => {}
crate::layout::ChildLayoutOutcome::ReenterCurrent => self.run(run, input),
crate::layout::ChildLayoutOutcome::Skipped => {}
}
self.flex_items[index].content_baselines =
match crate::layout::layout_inside_child(run, None, None, node, LayoutMode::Normal, input, false) {
crate::layout::ChildLayoutOutcome::Created(result) => result.baselines,
crate::layout::ChildLayoutOutcome::ReenterCurrent => {
self.run(run, input);
self.item_used(index).content_baselines_from_cells()
}
crate::layout::ChildLayoutOutcome::Skipped => self.item_used(index).content_baselines_from_cells(),
};

let container_inline_size = self.container_used().content_inline_size.get();
let container_block_size = self.container_used().content_block_size.get();
Expand Down
62 changes: 34 additions & 28 deletions Libraries/LibWeb/Rust/src/layout/formatting_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,12 +484,22 @@ pub(crate) fn box_baseline(
state: &LayoutState,
callbacks: &FfiLayoutFcCallbacks,
box_: Node,
used: &UsedValues,
baseline_set: BaselineSet,
) -> CssPixels {
box_baseline_with_content_baselines(state, callbacks, box_, used, baseline_set, used.content_baselines_from_cells())
}

pub(crate) fn box_baseline_with_content_baselines(
state: &LayoutState,
callbacks: &FfiLayoutFcCallbacks,
box_: Node,
used: &UsedValues,
mut baseline_set: BaselineSet,
content_baselines: DerivedBaselines,
) -> CssPixels {
let facts = state.node_facts(callbacks, box_);
let style = state.style_facts(callbacks, box_);
let used_pointer = state.used_values(callbacks, box_);
let used = used_pointer;
let collapsed = used.uses_collapsing_borders_model.get();

// https://drafts.csswg.org/css2/#propdef-vertical-align
Expand Down Expand Up @@ -559,9 +569,8 @@ pub(crate) fn box_baseline(
let input_derives_from_children = facts.is_html_input_element() && !facts.children_are_inline();

let content_baseline = match baseline_set {
BaselineSet::First if used.has_first_baseline.get() => Some(used.first_baseline.get()),
BaselineSet::Last if used.has_last_baseline.get() => Some(used.last_baseline.get()),
_ => None,
BaselineSet::First => content_baselines.first,
BaselineSet::Last => content_baselines.last,
};
if let Some(content_baseline) = content_baseline
&& (derive_baseline_from_content || input_derives_from_children)
Expand Down Expand Up @@ -630,7 +639,7 @@ pub(crate) fn derive_baselines(
let block_child_state = state.used_values(callbacks, fragment_node);
let child_offset_from_margin_edge = block_child_state.content_offset.get().y
- block_child_state.margin_box_top(block_child_state.uses_collapsing_borders_model.get());
child_offset_from_margin_edge + box_baseline(state, callbacks, fragment_node, baseline_set)
child_offset_from_margin_edge + box_baseline(state, callbacks, fragment_node, block_child_state, baseline_set)
};

let mut first_line_index = 0;
Expand Down Expand Up @@ -706,7 +715,7 @@ pub(crate) fn derive_baselines(
}
let child_offset_from_margin_edge = child_state.content_offset.get().y
- child_state.margin_box_top(child_state.uses_collapsing_borders_model.get());
return Some(child_offset_from_margin_edge + box_baseline(state, callbacks, child, baseline_set));
return Some(child_offset_from_margin_edge + box_baseline(state, callbacks, child, child_state, baseline_set));
}
None
};
Expand Down Expand Up @@ -762,6 +771,7 @@ pub struct FfiBordersData {
pub(crate) struct ChildLayoutResult {
pub automatic_content_inline_size: CssPixels,
pub automatic_content_block_size: CssPixels,
pub baselines: DerivedBaselines,
}

pub(crate) enum ChildLayoutOutcome {
Expand Down Expand Up @@ -1489,57 +1499,53 @@ fn run_formatting_context<'pass>(
None
};
let mut implementation = None;
let result = if let Some(cached_block_size) = cached_atomic_block_size {
let result = if let Some((cached_block_size, cached_baselines)) = cached_atomic_block_size {
ChildLayoutResult {
automatic_content_block_size: cached_block_size,
baselines: cached_baselines,
..ChildLayoutResult::default()
}
} else {
let mut context_implementation = create_formatting_context_implementation(run, parent_grid, fc_type);
let result = match &mut context_implementation {
FormattingContextImplementation::Block(context) => {
context.run(run, body_input);
let result = ChildLayoutResult {
let baselines = context.derived_baselines_of_root_box();
store_derived_baselines(run.state.used_values(&run.callbacks, run.box_), baselines);
ChildLayoutResult {
automatic_content_inline_size: context.automatic_content_inline_size(),
automatic_content_block_size: context.automatic_content_block_size(),
};
store_derived_baselines(
run.state.used_values(&run.callbacks, run.box_),
context.derived_baselines_of_root_box(),
);
result
baselines,
}
}
FormattingContextImplementation::Flex(context) => {
context.run(run, body_input);
store_derived_baselines(
run.state.used_values(&run.callbacks, run.box_),
context.derived_baselines_of_root_box(),
);
let baselines = context.derived_baselines_of_root_box();
store_derived_baselines(run.state.used_values(&run.callbacks, run.box_), baselines);
ChildLayoutResult {
automatic_content_inline_size: context.automatic_content_inline_size(),
automatic_content_block_size: context.automatic_content_block_size(),
baselines,
}
}
FormattingContextImplementation::Grid(context) => {
context.run(run, body_input);
store_derived_baselines(
run.state.used_values(&run.callbacks, run.box_),
context.derived_baselines_of_root_box(),
);
let baselines = context.derived_baselines_of_root_box();
store_derived_baselines(run.state.used_values(&run.callbacks, run.box_), baselines);
ChildLayoutResult {
automatic_content_inline_size: context.automatic_content_inline_size(),
automatic_content_block_size: context.automatic_content_block_size(),
baselines,
}
}
FormattingContextImplementation::Table(context) => {
context.run(run, body_input);
store_derived_baselines(
run.state.used_values(&run.callbacks, run.box_),
context.derived_baselines_of_root_box(),
);
let baselines = context.derived_baselines_of_root_box();
store_derived_baselines(run.state.used_values(&run.callbacks, run.box_), baselines);
ChildLayoutResult {
automatic_content_inline_size: context.automatic_content_inline_size(),
automatic_content_block_size: context.automatic_content_block_size,
baselines,
}
}
FormattingContextImplementation::Svg(context) => {
Expand Down Expand Up @@ -1572,7 +1578,7 @@ fn run_formatting_context<'pass>(
finalize_atomic_root_block_size(
run,
&input,
cached_atomic_block_size,
cached_atomic_block_size.map(|(block_size, _)| block_size),
automatic_content_block_size_of_completed_body_run,
parent_block,
);
Expand Down
32 changes: 18 additions & 14 deletions Libraries/LibWeb/Rust/src/layout/inline_formatting_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -886,26 +886,28 @@ impl<'context, 'pass> InlineFormattingContext<'context, 'pass> {
next.map(|next| next - containing_block_offset_in_root)
}

fn layout_inside(&mut self, node: Node, available_space: AvailableSpace) {
fn layout_inside(&mut self, node: Node, available_space: AvailableSpace) -> DerivedBaselines {
let input = LayoutInput::new(
available_space,
self.input.containing_block_constraints,
ParticipationInParentFormattingContext::AtomicInline,
);
if let crate::layout::ChildLayoutOutcome::ReenterCurrent = crate::layout::layout_inside_child(
self.run,
Some(self.parent),
None,
node,
self.layout_mode,
input,
false,
) {
self.parent.run(self.run, input);
let content_baselines_from_cells = |used: &UsedValues| DerivedBaselines {
first: used.has_first_baseline.get().then(|| used.first_baseline.get()),
last: used.has_last_baseline.get().then(|| used.last_baseline.get()),
};
match crate::layout::layout_inside_child(self.run, Some(self.parent), None, node, self.layout_mode, input, false)
{
crate::layout::ChildLayoutOutcome::Created(result) => result.baselines,
crate::layout::ChildLayoutOutcome::ReenterCurrent => {
self.parent.run(self.run, input);
content_baselines_from_cells(self.used(node))
}
crate::layout::ChildLayoutOutcome::Skipped => content_baselines_from_cells(self.used(node)),
}
}

pub(crate) fn dimension_box_on_line(&mut self, node: Node) {
pub(crate) fn dimension_box_on_line(&mut self, node: Node) -> DerivedBaselines {
let available_space = self.input.available_space;
let facts = self.facts(node);
// Any fragmented inline box should have generated line box fragments already.
Expand All @@ -918,15 +920,16 @@ impl<'context, 'pass> InlineFormattingContext<'context, 'pass> {
self.callbacks.shell(node),
);
}
return;
return DerivedBaselines::default();
}

self.layout_inside(node, available_space);
let content_baselines = self.layout_inside(node, available_space);
debug_assert!(
self.used(node).has_definite_inline_size.get()
|| self.used(node).inline_size_constraint.get() != SizeConstraint::None,
"atomic inline-level run left its root's inline size unresolved"
);
content_baselines
}

fn clear_floating_boxes(&self, node: Node) -> bool {
Expand Down Expand Up @@ -1021,6 +1024,7 @@ impl<'context, 'pass> InlineFormattingContext<'context, 'pass> {
item.padding_end + item.border_end,
item.margin_start,
item.margin_end,
item.content_baselines,
);
}
ItemType::BlockLevelBox => {
Expand Down
5 changes: 4 additions & 1 deletion Libraries/LibWeb/Rust/src/layout/inline_level_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub(crate) struct Item {
pub(crate) is_collapsible_whitespace: bool,
pub(crate) can_break_before: bool,
pub(crate) preceded_by_unattached_inline_start_edges: bool,
pub(crate) content_baselines: DerivedBaselines,
}

impl Item {
Expand All @@ -51,6 +52,7 @@ impl Item {
is_collapsible_whitespace: false,
can_break_before: false,
preceded_by_unattached_inline_start_edges: false,
content_baselines: DerivedBaselines::default(),
}
}

Expand Down Expand Up @@ -552,8 +554,9 @@ impl<'iterator, 'context, 'pass> InlineLevelIteratorGenerator<'iterator, 'contex
self.context()
.create_used_values(node, self.context().input.containing_block_constraints)
};
self.context_mut().dimension_box_on_line(node);
let content_baselines = self.context_mut().dimension_box_on_line(node);
let mut item = Item::new(ItemType::Element, node);
item.content_baselines = content_baselines;
item.inline_size = used.content_inline_size.get();
item.padding_start = used.padding_left.get();
item.padding_end = used.padding_right.get();
Expand Down
2 changes: 2 additions & 0 deletions Libraries/LibWeb/Rust/src/layout/line_box_fragment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ pub(crate) struct LineBoxFragmentData {
pub(crate) first_available_font: *const c_void,
pub(crate) text_utf16: *const u16,
pub(crate) text_length_in_code_units: usize,
pub(crate) content_baselines: Option<DerivedBaselines>,
}

#[derive(Clone, Copy)]
Expand Down Expand Up @@ -103,6 +104,7 @@ impl LineBoxFragmentData {
first_available_font: facts.first_available_font,
text_utf16: facts.text_utf16,
text_length_in_code_units: facts.text_length_in_code_units,
content_baselines: None,
};
if let Some(glyphs) = &fragment.glyphs {
fragment.current_insert_direction = fragment.resolve_glyph_run_direction(glyphs.text_type);
Expand Down
16 changes: 14 additions & 2 deletions Libraries/LibWeb/Rust/src/layout/line_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ impl<'builder, 'context, 'pass> LineBuilder<'builder, 'context, 'pass> {
trailing_size: CssPixels,
leading_margin: CssPixels,
trailing_margin: CssPixels,
content_baselines: DerivedBaselines,
) {
self.prepare_to_append_inline_content();
let used = self.context().used(node);
Expand Down Expand Up @@ -244,6 +245,7 @@ impl<'builder, 'context, 'pass> LineBuilder<'builder, 'context, 'pass> {
fragment_facts,
text_align_is_justify,
);
self.line_mut(line_index).fragments[fragment_index].content_baselines = Some(content_baselines);
self.max_block_size_on_current_line = self.max_block_size_on_current_line.max(margin_block_size);
let used = self.context().used_mut(node);
used.has_containing_line_box_fragment.set(false);
Expand Down Expand Up @@ -557,18 +559,28 @@ impl<'builder, 'context, 'pass> LineBuilder<'builder, 'context, 'pass> {
let mut line_box_baseline = strut_baseline;
let fragment_count = self.line(line_index).fragments.len();
for fragment_index in 0..fragment_count {
let (node, style_source) = {
let (node, style_source, content_baselines) = {
let fragment = &self.line(line_index).fragments[fragment_index];
(fragment.layout_node, fragment.style_source)
(fragment.layout_node, fragment.style_source, fragment.content_baselines)
};
let style = self.context().style(style_source);
let fragment_baseline = if self.context().facts(node).is_text_node() {
Self::baseline_for_style(style, style.line_height())
} else if let Some(content_baselines) = content_baselines {
crate::layout::box_baseline_with_content_baselines(
self.context().state,
&self.context().callbacks,
node,
self.context().used(node),
crate::layout::BaselineSet::Last,
content_baselines,
)
} else {
crate::layout::box_baseline(
self.context().state,
&self.context().callbacks,
node,
self.context().used(node),
crate::layout::BaselineSet::Last,
)
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,6 @@ fn layout_replaced_with_children(run: &FormattingContextRun, layout_input: Layou
ChildLayoutResult {
automatic_content_inline_size: content_inline_size,
automatic_content_block_size: wrapper_layout.automatic_content_block_size,
baselines: DerivedBaselines::default(),
}
Comment on lines 69 to 73

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Trace whether ReplacedWithChildren roots ever get derived baselines stored
# through a path other than layout_replaced_with_children.
set -euo pipefail

rg -n 'ReplacedWithChildren' Libraries/LibWeb/Rust/src/layout -g '*.rs' -C5

echo '--- is_html_input_element / input_derives_from_children usage ---'
rg -n 'is_html_input_element|input_derives_from_children' Libraries/LibWeb/Rust/src/layout -g '*.rs' -C5

echo '--- finalize_block_level_root definition ---'
rg -n 'fn finalize_block_level_root' Libraries/LibWeb/Rust/src/layout -g '*.rs' -A40

echo '--- store_derived_baselines call sites ---'
rg -n 'store_derived_baselines\(' Libraries/LibWeb/Rust/src/layout -g '*.rs' -B3 -A1

Repository: LadybirdBrowser/ladybird

Length of output: 19900


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- formatting_context.rs baseline functions ---'
sed -n '540,610p' Libraries/LibWeb/Rust/src/layout/formatting_context.rs

echo '--- run_formatting_context relevant section ---'
sed -n '1500,1630p' Libraries/LibWeb/Rust/src/layout/formatting_context.rs

echo '--- replaced_with_children_formatting_context.rs ---'
sed -n '1,130p' Libraries/LibWeb/Rust/src/layout/replaced_with_children_formatting_context.rs

echo '--- all DerivedBaselines default/store/receive occurrences ---'
rg -n 'DerivedBaselines::default|derive_baselines|derived_baselines_of_root_box|content_baselines_from_cells|has_first_baseline|first_baseline|baselines:' Libraries/LibWeb/Rust/src/layout -g '*.rs' -C2

Repository: LadybirdBrowser/ladybird

Length of output: 50380


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

root = Path("Libraries/LibWeb/Rust/src/layout")

def text(path):
    return path.read_text()

ctx = text(root / "formatting_context.rs")
repr = text(root / "used_values.rs")
bfc = text(root / "block_formatting_context.rs")
replaced = text(root / "replaced_with_children_formatting_context.rs")
inline = text(root / "inline_formatting_context.rs")
flex = text(root / "flex_formatting_context.rs")
grid = text(root / "grid_formatting_context.rs")
table = text(root / "table_formatting_context.rs")

for name, pattern, file in [
    ("derive_baselines", r"pub\(crate\) fn derive_baselines", root/"formatting_context.rs"),
    ("FinalizeAtomicRootBlock", r"fn finalize_atomic_root_block_size", root/"formatting_context.rs"),
    ("compute_and_store_baselines Call", r"self\.compute_and_store_baselines\s*\(", root/"block_formatting_context.rs"),
    ("DeriveBaselines Call", r"crate::layout::derive_baselines\s*\(", file),
]:
    idx = file.find(pattern)
    print(f"--- {name}: {file} ---")
    if idx == -1:
        print("not found")
        continue
    start = file.rfind("\n", 0, max(0, idx - 1000)) + 1
    end = min(idx + 2500, len(file))
    print(file[start:end])

# Read-only invariants focused on the baseline storage data flow.
print("--- invariants ---")

# In run_formatting_context ReplacedWithChildren branch, the result is returned directly and
# the only post-run block-level finalize is finalize_block_level_root().
rf = ctx.find("FormattingContextImplementation::ReplacedWithChildren => layout_replaced_with_children(run, body_input),")
final = ctx.find("fn finalize_block_level_root(", rf)
print(f"run_formatting_context ReplacedWithChildren returns before finalize_block_level_root after child layout: {0 < rf < final}")

# Locate finalize_block_level_root and check it does not call store_derived_baselines.
start = ctx.find("fn finalize_block_level_root(")
end = ctx.find("\nfn size_skipped_independent_root", start)
frag = ctx[start:end]
print(f"finalize_block_level_root calls store_derived_baselines: {'store_derived_baselines(' in frag}")
print(f"finalize_block_level_root records_replaced_block_size: {'record_replaced_block_size(' in frag}")

# Locate derive_baselines and check ReplacedWithChildren children are never treated as derived baselines.
start = ctx.find("// pub(crate) fn derive_baselines", None if "pub(crate) fn derive_baselines" not in ctx else None)
start = ctx.find("pub(crate) fn derive_baselines")
end = ctx.find("pub(crate) struct ChildLayoutResult", start)
ds = ctx[start:end]
print(f"derive_baselines handles child formatting-context boxes: {'is_flex_container' in ds or 'GridFormattingContext' in ds or 'TableFormattingContext' in ds or 'block_container' in ds}")
print(f"derivation first baseline source line count around child-derived baselines:")
for m in re.finditer(r"(has_first_baseline|first_baseline|children_are_inline|BlockFormattingContext)", ds):
    line = ds[:m.start()].count("\n") + 1
    print(f"  line {line}: {m.group()}")
PY

Repository: LadybirdBrowser/ladybird

Length of output: 274


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

root = Path("Libraries/LibWeb/Rust/src/layout")

def text(path):
    return path.read_text()

ctx = text(root / "formatting_context.rs")
repr = text(root / "used_values.rs")
bfc = text(root / "block_formatting_context.rs")
replaced = text(root / "replaced_with_children_formatting_context.rs")
inline = text(root / "inline_formatting_context.rs")
flex = text(root / "flex_formatting_context.rs")
grid = text(root / "grid_formatting_context.rs")
table = text(root / "table_formatting_context.rs")

fragments = [
    ("derive_baselines", root / "formatting_context.rs"),
    ("finalize_atomic_root_block_size", root / "formatting_context.rs"),
    ("compute_and_store_baselines in block FC", root / "block_formatting_context.rs"),
    ("derive_baselines calls", root / "block_formatting_context.rs"),
    ("box_baseline_with_content_baselines", root / "formatting_context.rs"),
    ("input_derives_from_children handling", root / "formatting_context.rs"),
    ("derive_baselines implementation", None),
]
for (name, file) in fragments:
    print(f"--- {name}: {file or 'formatting_context.rs'} ---")
    target = file.read_text() if file else ctx
    if name == "derive_baselines implementation":
        start = target.find("pub(crate) fn derive_baselines")
        end = target.find("pub(crate) struct ChildLayoutResult", start)
    else:
        start = target.find("pub(crate) fn " + name)
        if start == -1:
            start = target.find("fn " + name)
        if start == -1:
            print("not found")
            continue
        if name == "derive_baselines implementation":
            end = target.find("pub(crate) struct ChildLayoutResult", start)
        else:
            next_new = target.find("\nfn ", start + 1)
            end = target.find("\n}", target.rfind("{", start, next_new if next_new != -1 else len(target))) + 2 if next_new != -1 else len(target)
            if target.find("\n)", end) != -1:
                end = target.find("\n)", end) + 2
            end = min(end, target.find("\n}", end) + 2)
    print(target[start:end])

print("--- invariants ---")

rf = ctx.find("FormattingContextImplementation::ReplacedWithChildren => layout_replaced_with_children(run, body_input),")
final_start = ctx.find("fn finalize_block_level_root(", rf)
print(f"run_formatting_context ReplacedWithChildren branch exists: {rf != -1}")
print(f"finalize_block_level_root exists after ReplacedWithChildren case: {final_start != -1}")
print(f"finalize_block_level_root contains store_derived_baselines: {'store_derived_baselines(' in ctx[final_start:ctx.find('fn size_skipped_independent_root', final_start)]}")
print(f"finalize_block_level_root contains record_replaced_block_size: {'record_replaced_block_size(' in ctx[final_start:ctx.find('fn size_skipped_independent_root', final_start)]}")

ds_start = ctx.find("pub(crate) fn derive_baselines")
ds_end = ctx.find("pub(crate) struct ChildLayoutResult", ds_start)
ds = ctx[ds_start:ds_end]
print(f"derive_baselines handles block container children: {'child_state.content_baselines_from_cells' in ds}")
print(f"derive_baselines handles flex container children: {'fctx.derived_baselines_of_root_box' in ds}")
print(f"derive_baselines handles grid container children: {'gctx.derived_baselines_of_root_box' in ds}")
print(f"derive_baselines handles table formatting context: {'TableFormattingContext' in ds}")

stored_calls = []
for p in [root / "block_formatting_context.rs", root / "inline_formatting_context.rs", root / "flex_formatting_context.rs", root / "grid_formatting_context.rs", root / "table_formatting_context.rs"]:
    pc = p.read_text()
    if "crate::layout::store_derived_baselines(" in pc:
        for m in re.finditer(r"crate::layout::store_derived_baselines\s*\(", pc):
            line = pc[:m.start()].count("\n") + 1
            stored_calls.append((p, line, pc[pc.rfind("\n", 0, m.start()-1):pc.find("\n", m.start()) + 1].strip()))
print("store_derived_baselines call sites:")
for p,line,snippet in stored_calls:
    print(f"  {p}:{line} {snippet}")
PY

Repository: LadybirdBrowser/ladybird

Length of output: 50380


Store baselines for ReplacedWithChildren roots.

layout_replaced_with_children always returns DerivedBaselines::default(), and run_formatting_context does not call store_derived_baselines for ReplacedWithChildren roots. Derive and forward the wrapper baseline result from layout_replaced_with_children, or explicitly derive/store baselines from the wrapper child instead of relying on finalize_block_level_root, so <input> elements with block shadow-tree children do not collapse to the margin-box bottom edge.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Libraries/LibWeb/Rust/src/layout/replaced_with_children_formatting_context.rs`
around lines 69 - 73, Update layout_replaced_with_children and the
ReplacedWithChildren path in run_formatting_context to derive and store the
wrapper child’s baselines instead of returning DerivedBaselines::default().
Ensure the derived baselines are forwarded or explicitly passed to
store_derived_baselines so input elements with block shadow-tree children retain
the wrapper baseline.

}
Loading
Loading