Skip to content

Commit

Permalink
LibWeb: Use fit-content width if button's computed width is "auto"
Browse files Browse the repository at this point in the history
Implements following line from the spec:
"If the computed value of 'inline-size' is 'auto', then the used value
is the fit-content inline size."
  • Loading branch information
kalenikaliaksandr authored and awesomekling committed Sep 12, 2023
1 parent 7eee3f6 commit 6393944
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 1 deletion.
29 changes: 29 additions & 0 deletions Tests/LibWeb/Layout/expected/block-and-inline/button-width.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x58.9375 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x42.9375 children: not-inline
BlockContainer <button.btn.fixed-width> at (13,10) content-size 190x17.46875 children: not-inline
BlockContainer <(anonymous)> at (13,10) content-size 190x17.46875 flex-container(column) [FFC] children: not-inline
BlockContainer <(anonymous)> at (13,10) content-size 190x17.46875 flex-item [BFC] children: inline
line 0 width: 94.921875, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 11, rect: [61,10 94.921875x17.46875]
"200px width"
TextNode <#text>
BlockContainer <button.btn> at (13,31.46875) content-size 324.671875x17.46875 children: not-inline
BlockContainer <(anonymous)> at (13,31.46875) content-size 324.671875x17.46875 flex-container(column) [FFC] children: not-inline
BlockContainer <(anonymous)> at (13,31.46875) content-size 324.671875x17.46875 flex-item [BFC] children: inline
line 0 width: 324.671875, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 39, rect: [13,31.46875 324.671875x17.46875]
"auto width should behave as fit-content"
TextNode <#text>

ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x58.9375]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x42.9375]
PaintableWithLines (BlockContainer<BUTTON>.btn.fixed-width) [8,8 200x21.46875]
PaintableWithLines (BlockContainer(anonymous)) [13,10 190x17.46875]
PaintableWithLines (BlockContainer(anonymous)) [13,10 190x17.46875]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<BUTTON>.btn) [8,29.46875 334.671875x21.46875]
PaintableWithLines (BlockContainer(anonymous)) [13,31.46875 324.671875x17.46875]
PaintableWithLines (BlockContainer(anonymous)) [13,31.46875 324.671875x17.46875]
TextPaintable (TextNode<#text>)
9 changes: 9 additions & 0 deletions Tests/LibWeb/Layout/input/block-and-inline/button-width.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!DOCTYPE html><style>
.btn {
display: block;
}

.fixed-width {
width: 200px;
}
</style><button class="btn fixed-width">200px width</button><button class="btn">auto width should behave as fit-content</button>
1 change: 1 addition & 0 deletions Userland/Libraries/LibWeb/DOM/Node.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class Node : public EventTarget {
virtual bool is_html_table_row_element() const { return false; }
virtual bool is_html_table_cell_element() const { return false; }
virtual bool is_html_br_element() const { return false; }
virtual bool is_html_button_element() const { return false; }
virtual bool is_navigable_container() const { return false; }

WebIDL::ExceptionOr<JS::NonnullGCPtr<Node>> pre_insert(JS::NonnullGCPtr<Node>, JS::GCPtr<Node>);
Expand Down
7 changes: 7 additions & 0 deletions Userland/Libraries/LibWeb/HTML/HTMLButtonElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,17 @@ class HTMLButtonElement final
virtual DeprecatedString value() const override;

private:
virtual bool is_html_button_element() const override { return true; }

HTMLButtonElement(DOM::Document&, DOM::QualifiedName);

// ^DOM::Element
virtual i32 default_tab_index_value() const override;
};

}

namespace Web::DOM {
template<>
inline bool Node::fast_is<HTML::HTMLButtonElement>() const { return is_html_button_element(); }
}
9 changes: 8 additions & 1 deletion Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,11 +366,18 @@ ErrorOr<void> TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder::
}
}

// https://html.spec.whatwg.org/multipage/rendering.html#button-layout
// If the computed value of 'inline-size' is 'auto', then the used value is the fit-content inline size.
if (dom_node.is_html_button_element() && dom_node.layout_node()->computed_values().width().is_auto()) {
auto& computed_values = verify_cast<NodeWithStyle>(*dom_node.layout_node()).mutable_computed_values();
computed_values.set_width(CSS::Size::make_fit_content());
}

// https://html.spec.whatwg.org/multipage/rendering.html#button-layout
// If the element is an input element, or if it is a button element and its computed value for
// 'display' is not 'inline-grid', 'grid', 'inline-flex', or 'flex', then the element's box has
// a child anonymous button content box with the following behaviors:
if (is<HTML::HTMLButtonElement>(dom_node) && !display.is_grid_inside() && !display.is_flex_inside()) {
if (dom_node.is_html_button_element() && !display.is_grid_inside() && !display.is_flex_inside()) {
auto& parent = *dom_node.layout_node();

// If the box does not overflow in the vertical axis, then it is centered vertically.
Expand Down

0 comments on commit 6393944

Please sign in to comment.