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
6 changes: 0 additions & 6 deletions Libraries/LibWeb/Layout/LayoutRustBridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1118,12 +1118,6 @@ RustFFI::FfiLayoutFcCallbacks LayoutRustBridge::formatting_context_callbacks()
.arena = m_commit_root->arena_handle(),
.initial_containing_block_inline_size = m_commit_root->document().viewport_rect().width().raw_value(),
.document_in_quirks_mode = m_commit_root->document().in_quirks_mode(),
.needs_inset_resolution = [](void*, void* node) {
auto const& styled_node = *static_cast<NodeWithStyle const*>(node);
if (styled_node.computed_values().position() == CSS::Positioning::Relative)
return true;
auto const* box = as_if<Box>(styled_node);
return box && box_inset_properties_contain_anchor_functions(*box); },
.report_unexpected_fragmented_inline = [](void*, void* node) {
auto const& box = *static_cast<Box const*>(node);
dbgln("FIXME: InlineFormattingContext::dimension_box_on_line got unexpected box in inline context:");
Expand Down
23 changes: 11 additions & 12 deletions Libraries/LibWeb/Rust/src/layout/abspos_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1805,25 +1805,24 @@ impl AbsposEngine {
treat_block_axis_percentage_insets_as_auto_beyond_root: bool,
) {
// Most boxes are neither relatively positioned nor carry anchor()
// insets. Preserve the old C++ fast path without populating the
// comprehensive Rust facts caches for those boxes.
// SAFETY: The callback only reads the live node's computed values.
if !unsafe {
(self.callbacks.needs_inset_resolution)(self.callbacks.context, self.callbacks.shell(node))
} {
return;
}
// insets, and both facts come straight from the node's style payload.
let initial_style = self.style(node);
let resolved = if initial_style.inset_top().contains_anchor_function()
let has_anchor_insets = initial_style.inset_top().contains_anchor_function()
|| initial_style.inset_right().contains_anchor_function()
|| initial_style.inset_bottom().contains_anchor_function()
|| initial_style.inset_left().contains_anchor_function()
{
|| initial_style.inset_left().contains_anchor_function();
if !has_anchor_insets && initial_style.position() != positioning::RELATIVE {
return;
}
// Anchor resolution also refreshes the box's default scroll shift, so
// an anchor-bearing box resolves its insets even when it turns out not
// to be relatively positioned.
let resolved = if has_anchor_insets {
self.resolve_anchor_insets(node, None, NodeSlotId::INVALID)
} else {
Comment on lines +1814 to 1822

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Preserve stale scroll-shift cleanup for relative nodes.

When a relative node has no anchor() inset, this branch skips resolve_anchor_insets. That helper clears the existing default scroll shift before checking for anchor insets at Lines 558-568. If a node changes from anchor-bearing to ordinary relative positioning, stale scroll-shift state can remain and produce incorrect layout.

Keep the early return for nodes that are neither relative nor anchor-bearing, but call resolve_anchor_insets for every node that passes that gate.

Proposed fix
-        let resolved = if has_anchor_insets {
-            self.resolve_anchor_insets(node, None, NodeSlotId::INVALID)
-        } else {
-            None
-        };
+        let resolved = self.resolve_anchor_insets(node, None, NodeSlotId::INVALID);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if !has_anchor_insets && initial_style.position() != positioning::RELATIVE {
return;
}
// Anchor resolution also refreshes the box's default scroll shift, so
// an anchor-bearing box resolves its insets even when it turns out not
// to be relatively positioned.
let resolved = if has_anchor_insets {
self.resolve_anchor_insets(node, None, NodeSlotId::INVALID)
} else {
if !has_anchor_insets && initial_style.position() != positioning::RELATIVE {
return;
}
// Anchor resolution also refreshes the box's default scroll shift, so
// an anchor-bearing box resolves its insets even when it turns out not
// to be relatively positioned.
let resolved = self.resolve_anchor_insets(node, None, NodeSlotId::INVALID);
🤖 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/abspos_engine.rs` around lines 1814 - 1822,
Update the early-return flow in the relative-positioning logic so nodes that are
relative, including those without anchor insets, always call
resolve_anchor_insets. Retain the early return only when the node is neither
relative nor anchor-bearing, ensuring stale default scroll-shift state is
cleared for ordinary relative nodes.

None
};
let style = self.style(node).with_resolved_insets(resolved.as_ref());
let style = initial_style.with_resolved_insets(resolved.as_ref());
if style.position() != positioning::RELATIVE {
return;
}
Expand Down
1 change: 0 additions & 1 deletion Libraries/LibWeb/Rust/src/layout/formatting_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,6 @@ pub struct FfiLayoutFcCallbacks {
pub arena: *mut c_void,
pub initial_containing_block_inline_size: CssPixels,
pub document_in_quirks_mode: bool,
pub needs_inset_resolution: unsafe extern "C" fn(*mut c_void, *mut c_void) -> bool,
pub report_unexpected_fragmented_inline: unsafe extern "C" fn(*mut c_void, *mut c_void),
pub build_svg_facts: unsafe extern "C" fn(*mut c_void, *mut c_void) -> FfiSvgElementFacts,
pub read_paintable_geometry:
Expand Down
Loading