mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 20:17:44 +00:00
LibWeb: Override width calculation for table wrappers
Introduce `TableWrapper` type so table wrappers could be distinguished from block containers and override width calculation for table wrappers (CSS 2.2 spec, section 17.5.2) inside BFCs in the way that their width should be equal to width of table box they wrap.
This commit is contained in:
parent
7526f9a8b7
commit
709fe01f52
8 changed files with 74 additions and 1 deletions
|
@ -347,6 +347,7 @@ set(SOURCES
|
||||||
Layout/TableFormattingContext.cpp
|
Layout/TableFormattingContext.cpp
|
||||||
Layout/TableRowBox.cpp
|
Layout/TableRowBox.cpp
|
||||||
Layout/TableRowGroupBox.cpp
|
Layout/TableRowGroupBox.cpp
|
||||||
|
Layout/TableWrapper.cpp
|
||||||
Layout/TextNode.cpp
|
Layout/TextNode.cpp
|
||||||
Layout/TreeBuilder.cpp
|
Layout/TreeBuilder.cpp
|
||||||
Loader/ContentFilter.cpp
|
Loader/ContentFilter.cpp
|
||||||
|
|
|
@ -454,6 +454,7 @@ class NodeWithStyle;
|
||||||
class NodeWithStyleAndBoxModelMetrics;
|
class NodeWithStyleAndBoxModelMetrics;
|
||||||
class RadioButton;
|
class RadioButton;
|
||||||
class ReplacedBox;
|
class ReplacedBox;
|
||||||
|
class TableWrapper;
|
||||||
class TextNode;
|
class TextNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include <LibWeb/Layout/ListItemBox.h>
|
#include <LibWeb/Layout/ListItemBox.h>
|
||||||
#include <LibWeb/Layout/ListItemMarkerBox.h>
|
#include <LibWeb/Layout/ListItemMarkerBox.h>
|
||||||
#include <LibWeb/Layout/ReplacedBox.h>
|
#include <LibWeb/Layout/ReplacedBox.h>
|
||||||
|
#include <LibWeb/Layout/TableBox.h>
|
||||||
|
#include <LibWeb/Layout/TableWrapper.h>
|
||||||
|
|
||||||
namespace Web::Layout {
|
namespace Web::Layout {
|
||||||
|
|
||||||
|
@ -193,6 +195,8 @@ void BlockFormattingContext::compute_width(Box const& box, AvailableSpace const&
|
||||||
};
|
};
|
||||||
|
|
||||||
auto input_width = [&] {
|
auto input_width = [&] {
|
||||||
|
if (is<TableWrapper>(box))
|
||||||
|
return CSS::Length::make_px(compute_width_for_table_wrapper(box, available_space));
|
||||||
if (should_treat_width_as_auto(box, available_space))
|
if (should_treat_width_as_auto(box, available_space))
|
||||||
return CSS::Length::make_auto();
|
return CSS::Length::make_auto();
|
||||||
return calculate_inner_width(box, available_space.width, computed_values.width());
|
return calculate_inner_width(box, available_space.width, computed_values.width());
|
||||||
|
@ -312,6 +316,18 @@ void BlockFormattingContext::compute_width_for_block_level_replaced_element_in_n
|
||||||
m_state.get_mutable(box).set_content_width(compute_width_for_replaced_element(m_state, box, available_space));
|
m_state.get_mutable(box).set_content_width(compute_width_for_replaced_element(m_state, box, available_space));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSSPixels BlockFormattingContext::compute_width_for_table_wrapper(Box const& box, AvailableSpace const& available_space)
|
||||||
|
{
|
||||||
|
// 17.5.2
|
||||||
|
// Table wrapper width should be equal to width of table box it contains
|
||||||
|
LayoutState throwaway_state(&m_state);
|
||||||
|
auto context = create_independent_formatting_context_if_needed(throwaway_state, box);
|
||||||
|
VERIFY(context);
|
||||||
|
context->run(box, LayoutMode::IntrinsicSizing, m_state.get(box).available_inner_space_or_constraints_from(available_space));
|
||||||
|
auto const* table_box = box.first_child_of_type<TableBox>();
|
||||||
|
return throwaway_state.get(*table_box).content_width();
|
||||||
|
}
|
||||||
|
|
||||||
void BlockFormattingContext::compute_height(Box const& box, AvailableSpace const& available_space)
|
void BlockFormattingContext::compute_height(Box const& box, AvailableSpace const& available_space)
|
||||||
{
|
{
|
||||||
auto const& computed_values = box.computed_values();
|
auto const& computed_values = box.computed_values();
|
||||||
|
|
|
@ -59,6 +59,8 @@ private:
|
||||||
|
|
||||||
void compute_width_for_block_level_replaced_element_in_normal_flow(ReplacedBox const&, AvailableSpace const&);
|
void compute_width_for_block_level_replaced_element_in_normal_flow(ReplacedBox const&, AvailableSpace const&);
|
||||||
|
|
||||||
|
CSSPixels compute_width_for_table_wrapper(Box const&, AvailableSpace const&);
|
||||||
|
|
||||||
void layout_initial_containing_block(LayoutMode, AvailableSpace const&);
|
void layout_initial_containing_block(LayoutMode, AvailableSpace const&);
|
||||||
|
|
||||||
void layout_block_level_children(BlockContainer const&, LayoutMode, AvailableSpace const&);
|
void layout_block_level_children(BlockContainer const&, LayoutMode, AvailableSpace const&);
|
||||||
|
|
|
@ -90,6 +90,7 @@ public:
|
||||||
virtual bool is_label() const { return false; }
|
virtual bool is_label() const { return false; }
|
||||||
virtual bool is_replaced_box() const { return false; }
|
virtual bool is_replaced_box() const { return false; }
|
||||||
virtual bool is_list_item_marker_box() const { return false; }
|
virtual bool is_list_item_marker_box() const { return false; }
|
||||||
|
virtual bool is_table_wrapper() const { return false; }
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool fast_is() const = delete;
|
bool fast_is() const = delete;
|
||||||
|
|
23
Userland/Libraries/LibWeb/Layout/TableWrapper.cpp
Normal file
23
Userland/Libraries/LibWeb/Layout/TableWrapper.cpp
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibWeb/Layout/TableWrapper.h>
|
||||||
|
|
||||||
|
namespace Web::Layout {
|
||||||
|
|
||||||
|
TableWrapper::TableWrapper(DOM::Document& document, DOM::Node* node, NonnullRefPtr<CSS::StyleProperties> style)
|
||||||
|
: BlockContainer(document, node, move(style))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TableWrapper::TableWrapper(DOM::Document& document, DOM::Node* node, CSS::ComputedValues computed_values)
|
||||||
|
: BlockContainer(document, node, move(computed_values))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TableWrapper::~TableWrapper() = default;
|
||||||
|
|
||||||
|
}
|
28
Userland/Libraries/LibWeb/Layout/TableWrapper.h
Normal file
28
Userland/Libraries/LibWeb/Layout/TableWrapper.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibWeb/Layout/BlockContainer.h>
|
||||||
|
|
||||||
|
namespace Web::Layout {
|
||||||
|
|
||||||
|
class TableWrapper : public BlockContainer {
|
||||||
|
JS_CELL(TableWrapper, BlockContainer);
|
||||||
|
|
||||||
|
public:
|
||||||
|
TableWrapper(DOM::Document&, DOM::Node*, NonnullRefPtr<CSS::StyleProperties>);
|
||||||
|
TableWrapper(DOM::Document&, DOM::Node*, CSS::ComputedValues);
|
||||||
|
virtual ~TableWrapper() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual bool is_table_wrapper() const final { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline bool Node::fast_is<TableWrapper>() const { return is_table_wrapper(); }
|
||||||
|
|
||||||
|
}
|
|
@ -24,6 +24,7 @@
|
||||||
#include <LibWeb/Layout/TableBox.h>
|
#include <LibWeb/Layout/TableBox.h>
|
||||||
#include <LibWeb/Layout/TableCellBox.h>
|
#include <LibWeb/Layout/TableCellBox.h>
|
||||||
#include <LibWeb/Layout/TableRowBox.h>
|
#include <LibWeb/Layout/TableRowBox.h>
|
||||||
|
#include <LibWeb/Layout/TableWrapper.h>
|
||||||
#include <LibWeb/Layout/TextNode.h>
|
#include <LibWeb/Layout/TextNode.h>
|
||||||
#include <LibWeb/Layout/TreeBuilder.h>
|
#include <LibWeb/Layout/TreeBuilder.h>
|
||||||
#include <LibWeb/SVG/SVGForeignObjectElement.h>
|
#include <LibWeb/SVG/SVGForeignObjectElement.h>
|
||||||
|
@ -598,7 +599,7 @@ void TreeBuilder::generate_missing_parents(NodeWithStyle& root)
|
||||||
mutable_wrapper_computed_values.set_margin(table_box->computed_values().margin());
|
mutable_wrapper_computed_values.set_margin(table_box->computed_values().margin());
|
||||||
table_box->reset_table_box_computed_values_used_by_wrapper_to_init_values();
|
table_box->reset_table_box_computed_values_used_by_wrapper_to_init_values();
|
||||||
|
|
||||||
auto wrapper = parent.heap().allocate_without_realm<BlockContainer>(parent.document(), nullptr, move(wrapper_computed_values));
|
auto wrapper = parent.heap().allocate_without_realm<TableWrapper>(parent.document(), nullptr, move(wrapper_computed_values));
|
||||||
|
|
||||||
parent.remove_child(*table_box);
|
parent.remove_child(*table_box);
|
||||||
wrapper->append_child(*table_box);
|
wrapper->append_child(*table_box);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue