mirror of
https://github.com/RGBCube/serenity
synced 2025-07-15 09:47:37 +00:00
LibWeb: Improve computation of a layout node's containing block
In particular, we now compute the containing block of boxes with position:absolute and position:fixed (more) correctly.
This commit is contained in:
parent
762617a028
commit
7fcf61be35
3 changed files with 43 additions and 5 deletions
|
@ -45,6 +45,8 @@ public:
|
||||||
|
|
||||||
void did_set_viewport_rect(Badge<Frame>, const Gfx::Rect&);
|
void did_set_viewport_rect(Badge<Frame>, const Gfx::Rect&);
|
||||||
|
|
||||||
|
virtual bool is_root() const override { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LayoutRange m_selection;
|
LayoutRange m_selection;
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,7 +29,9 @@
|
||||||
#include <LibWeb/DOM/Element.h>
|
#include <LibWeb/DOM/Element.h>
|
||||||
#include <LibWeb/Frame.h>
|
#include <LibWeb/Frame.h>
|
||||||
#include <LibWeb/Layout/LayoutBlock.h>
|
#include <LibWeb/Layout/LayoutBlock.h>
|
||||||
|
#include <LibWeb/Layout/LayoutDocument.h>
|
||||||
#include <LibWeb/Layout/LayoutNode.h>
|
#include <LibWeb/Layout/LayoutNode.h>
|
||||||
|
#include <LibWeb/Layout/LayoutReplaced.h>
|
||||||
|
|
||||||
namespace Web {
|
namespace Web {
|
||||||
|
|
||||||
|
@ -53,13 +55,36 @@ void LayoutNode::layout(LayoutMode layout_mode)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LayoutNode::can_contain_boxes_with_position_absolute() const
|
||||||
|
{
|
||||||
|
return style().position() != CSS::Position::Static || is_root();
|
||||||
|
}
|
||||||
|
|
||||||
const LayoutBlock* LayoutNode::containing_block() const
|
const LayoutBlock* LayoutNode::containing_block() const
|
||||||
{
|
{
|
||||||
for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
|
if (is_text()) {
|
||||||
if (is<LayoutBlock>(*ancestor))
|
auto* ancestor = parent();
|
||||||
|
while (ancestor && ((ancestor->is_inline() && !is<LayoutReplaced>(*ancestor)) || !is<LayoutBlock>(*ancestor)))
|
||||||
|
ancestor = ancestor->parent();
|
||||||
return to<LayoutBlock>(ancestor);
|
return to<LayoutBlock>(ancestor);
|
||||||
}
|
}
|
||||||
return nullptr;
|
|
||||||
|
if (is_absolutely_positioned()) {
|
||||||
|
auto* ancestor = parent();
|
||||||
|
while (ancestor && !ancestor->can_contain_boxes_with_position_absolute())
|
||||||
|
ancestor = ancestor->parent();
|
||||||
|
while (ancestor && (!is<LayoutBlock>(ancestor) || ancestor->is_anonymous()))
|
||||||
|
ancestor = ancestor->containing_block();
|
||||||
|
return to<LayoutBlock>(ancestor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (style().position() == CSS::Position::Fixed)
|
||||||
|
return &root();
|
||||||
|
|
||||||
|
auto* ancestor = parent();
|
||||||
|
while (ancestor && ((ancestor->is_inline() && !is<LayoutReplaced>(*ancestor)) || !is<LayoutBlock>(*ancestor)))
|
||||||
|
ancestor = ancestor->parent();
|
||||||
|
return to<LayoutBlock>(ancestor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayoutNode::render(RenderingContext& context)
|
void LayoutNode::render(RenderingContext& context)
|
||||||
|
@ -155,4 +180,10 @@ Gfx::FloatPoint LayoutNode::box_type_agnostic_position() const
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LayoutNode::is_absolutely_positioned() const
|
||||||
|
{
|
||||||
|
return style().position() == CSS::Position::Absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,8 @@ public:
|
||||||
callback(*node);
|
callback(*node);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const char* class_name() const { return "LayoutNode"; }
|
virtual const char* class_name() const = 0;
|
||||||
|
virtual bool is_root() const { return false; }
|
||||||
virtual bool is_text() const { return false; }
|
virtual bool is_text() const { return false; }
|
||||||
virtual bool is_block() const { return false; }
|
virtual bool is_block() const { return false; }
|
||||||
virtual bool is_replaced() const { return false; }
|
virtual bool is_replaced() const { return false; }
|
||||||
|
@ -108,8 +109,12 @@ public:
|
||||||
virtual void layout(LayoutMode);
|
virtual void layout(LayoutMode);
|
||||||
virtual void render(RenderingContext&);
|
virtual void render(RenderingContext&);
|
||||||
|
|
||||||
|
bool is_absolutely_positioned() const;
|
||||||
|
|
||||||
const LayoutBlock* containing_block() const;
|
const LayoutBlock* containing_block() const;
|
||||||
|
|
||||||
|
bool can_contain_boxes_with_position_absolute() const;
|
||||||
|
|
||||||
virtual LayoutNode& inline_wrapper() { return *this; }
|
virtual LayoutNode& inline_wrapper() { return *this; }
|
||||||
|
|
||||||
const StyleProperties& style() const;
|
const StyleProperties& style() const;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue