LibWeb: Naively implement the CSS clear property

This is definitely not fully-featured, but basically we now handle
the clear property by forcing the cleared box below the bottom-most
floated box on the relevant side.
This commit is contained in:
Andreas Kling 2020-12-06 01:45:51 +01:00
parent 26a9ab7cd5
commit af757a1659
Notes: sideshowbarker 2024-07-19 01:02:07 +09:00
8 changed files with 120 additions and 0 deletions

View file

@ -0,0 +1,64 @@
<style>
#lefty {
float: left;
background: red;
width: 100px;
height: 100px;
}
#righty {
float: right;
background: green;
width: 50px;
height: 50px;
}
#lefty2 {
float: left;
background: orange;
width: 80px;
height: 80px;
}
#righty2 {
float: right;
background: magenta;
width: 30px;
height: 30px;
}
#lefty3 {
float: left;
background: cyan;
width: 40px;
height: 40px;
}
#righty3 {
float: right;
background: silver;
width: 20px;
height: 20px;
}
#clearo {
clear: left;
}
</style>
</style>
<body>
<div>
<div id=lefty>L</div>
<div id=righty>R</div>
</div>
<div>
<div id=lefty2>L2</div>
<div id=righty2>R2</div>
</div>
<div>
lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
<div id=clearo></div>
<div>
<div id=lefty3>L3</div>
<div id=righty3>R3</div>
</div>
lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
</div>
</body>

View file

@ -38,6 +38,7 @@ span#loadtime {
<p>This page loaded in <b><span id="loadtime"></span></b> ms</p>
<p>Some small test pages:</p>
<ul>
<li><a href="clear-1.html">clearing floats</a></li>
<li><a href="float-1.html">floating boxes</a></li>
<li><a href="padding-inline.html">inline elements with padding</a></li>
<li><a href="event-bubbling-and-multiple-listeners.html">event bubbling and multiple listeners</a></li>

View file

@ -303,6 +303,23 @@ Optional<CSS::Float> StyleProperties::float_() const
return {};
}
Optional<CSS::Clear> StyleProperties::clear() const
{
auto value = property(CSS::PropertyID::Clear);
if (!value.has_value() || !value.value()->is_string())
return {};
auto string = value.value()->to_string();
if (string == "none")
return CSS::Clear::None;
if (string == "left")
return CSS::Clear::Left;
if (string == "right")
return CSS::Clear::Right;
if (string == "both")
return CSS::Clear::Both;
return {};
}
CSS::Display StyleProperties::display() const
{
auto display = string_or_fallback(CSS::PropertyID::Display, "inline");

View file

@ -63,6 +63,7 @@ public:
CSS::TextAlign text_align() const;
CSS::Display display() const;
Optional<CSS::Float> float_() const;
Optional<CSS::Clear> clear() const;
Optional<CSS::WhiteSpace> white_space() const;
Optional<CSS::LineStyle> line_style(CSS::PropertyID) const;

View file

@ -149,6 +149,13 @@ enum class Float {
Right,
};
enum class Clear {
None,
Left,
Right,
Both,
};
enum class LineStyle {
None,
Hidden,

View file

@ -565,6 +565,28 @@ void BlockFormattingContext::place_block_level_non_replaced_element_in_normal_fl
}
}
if (box.style().clear() == CSS::Clear::Left || box.style().clear() == CSS::Clear::Both) {
if (!m_left_floating_boxes.is_empty()) {
float clearance_y = 0;
for (auto* floating_box : m_left_floating_boxes) {
clearance_y = max(clearance_y, floating_box->effective_offset().y() + floating_box->box_model().margin_box(*floating_box).bottom);
}
y = max(y, clearance_y);
m_left_floating_boxes.clear();
}
}
if (box.style().clear() == CSS::Clear::Right || box.style().clear() == CSS::Clear::Both) {
if (!m_right_floating_boxes.is_empty()) {
float clearance_y = 0;
for (auto* floating_box : m_right_floating_boxes) {
clearance_y = max(clearance_y, floating_box->effective_offset().y() + floating_box->box_model().margin_box(*floating_box).bottom);
}
y = max(y, clearance_y);
m_right_floating_boxes.clear();
}
}
box.set_offset(x, y);
}

View file

@ -35,6 +35,7 @@ namespace Web {
class InitialValues {
public:
static CSS::Float float_() { return CSS::Float::None; }
static CSS::Clear clear() { return CSS::Clear::None; }
static CSS::WhiteSpace white_space() { return CSS::WhiteSpace::Normal; }
};
@ -48,6 +49,7 @@ public:
class LayoutStyle {
public:
CSS::Float float_() const { return m_float; }
CSS::Clear clear() const { return m_clear; }
Optional<int> z_index() const { return m_z_index; }
CSS::TextAlign text_align() const { return m_text_align; }
CSS::Position position() const { return m_position; }
@ -70,6 +72,7 @@ public:
protected:
CSS::Float m_float { InitialValues::float_() };
CSS::Clear m_clear { InitialValues::clear() };
Optional<int> m_z_index;
CSS::TextAlign m_text_align;
CSS::Position m_position;
@ -95,6 +98,7 @@ class ImmutableLayoutStyle final : public LayoutStyle {
class MutableLayoutStyle final : public LayoutStyle {
public:
void set_float(CSS::Float value) { m_float = value; }
void set_clear(CSS::Clear value) { m_clear = value; }
void set_z_index(Optional<int> value) { m_z_index = value; }
void set_text_align(CSS::TextAlign text_align) { m_text_align = text_align; }
void set_position(CSS::Position position) { m_position = position; }

View file

@ -231,6 +231,10 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& specified_style)
if (float_.has_value())
style.set_float(float_.value());
auto clear = specified_style.clear();
if (clear.has_value())
style.set_clear(clear.value());
style.set_z_index(specified_style.z_index());
style.set_width(specified_style.length_or_fallback(CSS::PropertyID::Width, {}));
style.set_min_width(specified_style.length_or_fallback(CSS::PropertyID::MinWidth, {}));