mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-05-05 06:32:30 +02:00
LibWeb: Make foreignObject establish a containing block for abspos
Absolutely positioned elements inside SVG foreignObject were being positioned relative to an ancestor containing block outside the SVG, instead of relative to the foreignObject itself. Per a W3C resolution and the behavior of other browsers, foreignObject should establish a containing block for absolutely and fixed positioned elements. With this fix, the `has_abspos_with_external_containing_block` check in `set_needs_layout_update()` and the abspos preservation loop in `relayout_svg_root()` become dead code — remove both and simplify the ancestor loops. Rename related tests to reflect the new behavior. Fixes https://github.com/LadybirdBrowser/ladybird/issues/3241
This commit is contained in:
committed by
Alexander Kalenik
parent
fa49de8956
commit
b3231ea2a0
Notes:
github-actions[bot]
2026-02-17 15:49:36 +00:00
Author: https://github.com/kalenikaliaksandr Commit: https://github.com/LadybirdBrowser/ladybird/commit/b3231ea2a04 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/7993 Reviewed-by: https://github.com/gmta
@@ -0,0 +1,62 @@
|
||||
<!DOCTYPE html>
|
||||
<script src="../include.js"></script>
|
||||
<style>
|
||||
.container {
|
||||
position: relative;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
.abspos {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
width: 25%;
|
||||
height: 25%;
|
||||
background: green;
|
||||
}
|
||||
</style>
|
||||
<div class="container">
|
||||
<svg width="100" height="100">
|
||||
<rect id="target" width="50" height="50" fill="blue"/>
|
||||
<foreignObject width="100" height="100">
|
||||
<div class="abspos" id="abspos"></div>
|
||||
</foreignObject>
|
||||
</svg>
|
||||
</div>
|
||||
<script>
|
||||
asyncTest(done => {
|
||||
// Force initial layout and capture "before" values without any DOM changes
|
||||
// (println modifies the DOM, which would cause full relayout instead of partial SVG relayout)
|
||||
document.body.offsetWidth;
|
||||
const absposBefore = document.getElementById("abspos").getBoundingClientRect();
|
||||
|
||||
// Trigger partial SVG relayout by changing an SVG attribute
|
||||
document.getElementById("target").setAttribute("transform", "translate(10,10)");
|
||||
|
||||
// Wait for layout to happen, then check values
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
const absposAfter = document.getElementById("abspos").getBoundingClientRect();
|
||||
|
||||
// Now it's safe to print (layout checks are done)
|
||||
println(`Before SVG relayout:`);
|
||||
println(` abspos width: ${absposBefore.width}`);
|
||||
println(` abspos height: ${absposBefore.height}`);
|
||||
println(` abspos x: ${absposBefore.x}`);
|
||||
println(` abspos y: ${absposBefore.y}`);
|
||||
println(`After SVG relayout:`);
|
||||
println(` abspos width: ${absposAfter.width}`);
|
||||
println(` abspos height: ${absposAfter.height}`);
|
||||
println(` abspos x: ${absposAfter.x}`);
|
||||
println(` abspos y: ${absposAfter.y}`);
|
||||
println(`Abspos preserved after SVG relayout:`);
|
||||
println(` width unchanged: ${absposAfter.width === absposBefore.width}`);
|
||||
println(` height unchanged: ${absposAfter.height === absposBefore.height}`);
|
||||
println(` x unchanged: ${absposAfter.x === absposBefore.x}`);
|
||||
println(` y unchanged: ${absposAfter.y === absposBefore.y}`);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user