diff --git a/Base/home/anon/www/inline-block.html b/Base/home/anon/www/inline-block.html
new file mode 100644
index 00000000000..72ecf0d0992
--- /dev/null
+++ b/Base/home/anon/www/inline-block.html
@@ -0,0 +1,20 @@
+
+
+
+ display: inline-block
+
+
+
+ Hello friends! This div has display: inline-block :^)
+ Hello friends! That means its laid out like a block on the inside.
+ Hello friends! But it acts like an atomic inline box on the outside!
+
+
diff --git a/Base/home/anon/www/welcome.html b/Base/home/anon/www/welcome.html
index d9ed0eb87ae..2fffcb8f6cc 100644
--- a/Base/home/anon/www/welcome.html
+++ b/Base/home/anon/www/welcome.html
@@ -28,6 +28,7 @@ span#ua {
Your user agent is:
Some small test pages:
+ - display: inline-block; test
- canvas path quadratic curve test
- pngsuite odd sizes test
- pngsuite basic formats test
diff --git a/Libraries/LibWeb/DOM/Element.cpp b/Libraries/LibWeb/DOM/Element.cpp
index c439e5c7d66..85fbfc90dca 100644
--- a/Libraries/LibWeb/DOM/Element.cpp
+++ b/Libraries/LibWeb/DOM/Element.cpp
@@ -130,8 +130,11 @@ RefPtr Element::create_layout_node(const StyleProperties* parent_sty
return adopt(*new LayoutTableRow(*this, move(style)));
if (display == "table-cell")
return adopt(*new LayoutTableCell(*this, move(style)));
- if (display == "inline-block")
- return adopt(*new LayoutBlock(this, move(style)));
+ if (display == "inline-block") {
+ auto inline_block = adopt(*new LayoutBlock(this, move(style)));
+ inline_block->set_inline(true);
+ return inline_block;
+ }
dbg() << "Unknown display type: _" << display << "_";
return adopt(*new LayoutInline(*this, move(style)));
diff --git a/Libraries/LibWeb/Layout/LayoutBlock.cpp b/Libraries/LibWeb/Layout/LayoutBlock.cpp
index 95b78887edd..ebe2abaaff6 100644
--- a/Libraries/LibWeb/Layout/LayoutBlock.cpp
+++ b/Libraries/LibWeb/Layout/LayoutBlock.cpp
@@ -56,7 +56,9 @@ LayoutNode& LayoutBlock::inline_wrapper()
void LayoutBlock::layout()
{
compute_width();
- compute_position();
+
+ if (!is_inline())
+ compute_position();
if (children_are_inline())
layout_inline_children();
@@ -168,6 +170,12 @@ void LayoutBlock::layout_inline_children()
if (is(fragment.layout_node()))
const_cast(to(fragment.layout_node())).set_rect(fragment.rect());
+ if (fragment.layout_node().is_inline_block()) {
+ auto& inline_block = const_cast(to(fragment.layout_node()));
+ inline_block.set_rect(fragment.rect());
+ inline_block.layout();
+ }
+
float final_line_box_width = 0;
for (auto& fragment : line_box.fragments())
final_line_box_width += fragment.rect().width();
@@ -418,4 +426,16 @@ LineBox& LayoutBlock::add_line_box()
return m_line_boxes.last();
}
+void LayoutBlock::split_into_lines(LayoutBlock& container)
+{
+ ASSERT(is_inline());
+
+ layout();
+
+ auto* line_box = &container.ensure_last_line_box();
+ if (line_box->width() > 0 && line_box->width() + width() > container.width())
+ line_box = &container.add_line_box();
+ line_box->add_fragment(*this, 0, 0, width(), height());
+}
+
}
diff --git a/Libraries/LibWeb/Layout/LayoutBlock.h b/Libraries/LibWeb/Layout/LayoutBlock.h
index 0eaab2520cb..269eb2b6aa0 100644
--- a/Libraries/LibWeb/Layout/LayoutBlock.h
+++ b/Libraries/LibWeb/Layout/LayoutBlock.h
@@ -63,6 +63,8 @@ public:
template
void for_each_fragment(Callback) const;
+ virtual void split_into_lines(LayoutBlock& container) override;
+
private:
virtual bool is_block() const override { return true; }
diff --git a/Libraries/LibWeb/Layout/LayoutNode.h b/Libraries/LibWeb/Layout/LayoutNode.h
index 84f2f8bc148..a9d64d61f58 100644
--- a/Libraries/LibWeb/Layout/LayoutNode.h
+++ b/Libraries/LibWeb/Layout/LayoutNode.h
@@ -97,6 +97,8 @@ public:
bool is_inline() const { return m_inline; }
void set_inline(bool b) { m_inline = b; }
+ bool is_inline_block() const { return is_inline() && is_block(); }
+
virtual void layout();
virtual void render(RenderingContext&);