1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 06:07:34 +00:00

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
8 changed files with 120 additions and 0 deletions

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, {}));