mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-03 08:08:43 +00:00
LibWeb: Apply scroll offset and clip rectangle to table borders
Moves paint_table_borders() call into PaintableBox::paint() to make scroll offset and clip rectangle of enclosing scrollable be applied in ::before_paint().
This commit is contained in:
parent
cf25a06d67
commit
2cc2646f55
Notes:
github-actions[bot]
2024-07-31 19:44:04 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: 2cc2646f55
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/902
5 changed files with 196 additions and 12 deletions
|
@ -0,0 +1,82 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<style>
|
||||
* {
|
||||
scrollbar-width: none;
|
||||
}
|
||||
#scrollable-div {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
overflow: auto;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
th,
|
||||
td {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
height: 50px;
|
||||
box-sizing: content-box;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="scrollable-div">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Row 2, Cell 1</td>
|
||||
<td>Row 2, Cell 2</td>
|
||||
<td>Row 2, Cell 3</td>
|
||||
<td>Row 2, Cell 4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Row 3, Cell 1</td>
|
||||
<td>Row 3, Cell 2</td>
|
||||
<td>Row 3, Cell 3</td>
|
||||
<td>Row 3, Cell 4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Row 4, Cell 1</td>
|
||||
<td>Row 4, Cell 2</td>
|
||||
<td>Row 4, Cell 3</td>
|
||||
<td>Row 4, Cell 4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Row 5, Cell 1</td>
|
||||
<td>Row 5, Cell 2</td>
|
||||
<td>Row 5, Cell 3</td>
|
||||
<td>Row 5, Cell 4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Row 6, Cell 1</td>
|
||||
<td>Row 6, Cell 2</td>
|
||||
<td>Row 6, Cell 3</td>
|
||||
<td>Row 6, Cell 4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Row 7, Cell 1</td>
|
||||
<td>Row 7, Cell 2</td>
|
||||
<td>Row 7, Cell 3</td>
|
||||
<td>Row 7, Cell 4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Row 8, Cell 1</td>
|
||||
<td>Row 8, Cell 2</td>
|
||||
<td>Row 8, Cell 3</td>
|
||||
<td>Row 8, Cell 4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Row 9, Cell 1</td>
|
||||
<td>Row 9, Cell 2</td>
|
||||
<td>Row 9, Cell 3</td>
|
||||
<td>Row 9, Cell 4</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
101
Tests/LibWeb/Ref/scrollable-contains-table.html
Normal file
101
Tests/LibWeb/Ref/scrollable-contains-table.html
Normal file
|
@ -0,0 +1,101 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="match" href="reference/scrollable-contains-table-ref.html" />
|
||||
<head>
|
||||
<style>
|
||||
* {
|
||||
scrollbar-width: none;
|
||||
}
|
||||
#scrollable-div {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
overflow: auto;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
th,
|
||||
td {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
height: 50px;
|
||||
box-sizing: content-box;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="scrollable-div">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Header 1</th>
|
||||
<th>Header 2</th>
|
||||
<th>Header 3</th>
|
||||
<th>Header 4</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Row 1, Cell 1</td>
|
||||
<td>Row 1, Cell 2</td>
|
||||
<td>Row 1, Cell 3</td>
|
||||
<td>Row 1, Cell 4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Row 2, Cell 1</td>
|
||||
<td>Row 2, Cell 2</td>
|
||||
<td>Row 2, Cell 3</td>
|
||||
<td>Row 2, Cell 4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Row 3, Cell 1</td>
|
||||
<td>Row 3, Cell 2</td>
|
||||
<td>Row 3, Cell 3</td>
|
||||
<td>Row 3, Cell 4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Row 4, Cell 1</td>
|
||||
<td>Row 4, Cell 2</td>
|
||||
<td>Row 4, Cell 3</td>
|
||||
<td>Row 4, Cell 4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Row 5, Cell 1</td>
|
||||
<td>Row 5, Cell 2</td>
|
||||
<td>Row 5, Cell 3</td>
|
||||
<td>Row 5, Cell 4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Row 6, Cell 1</td>
|
||||
<td>Row 6, Cell 2</td>
|
||||
<td>Row 6, Cell 3</td>
|
||||
<td>Row 6, Cell 4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Row 7, Cell 1</td>
|
||||
<td>Row 7, Cell 2</td>
|
||||
<td>Row 7, Cell 3</td>
|
||||
<td>Row 7, Cell 4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Row 8, Cell 1</td>
|
||||
<td>Row 8, Cell 2</td>
|
||||
<td>Row 8, Cell 3</td>
|
||||
<td>Row 8, Cell 4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Row 9, Cell 1</td>
|
||||
<td>Row 9, Cell 2</td>
|
||||
<td>Row 9, Cell 3</td>
|
||||
<td>Row 9, Cell 4</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
const scrollContainer = document.getElementById("scrollable-div");
|
||||
scrollContainer.scrollTop = 100;
|
||||
</script>
|
|
@ -16,6 +16,7 @@ namespace Web::Painting {
|
|||
enum class PaintPhase {
|
||||
Background,
|
||||
Border,
|
||||
TableCollapsedBorder,
|
||||
Foreground,
|
||||
Outline,
|
||||
Overlay,
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <LibWeb/Painting/SVGPaintable.h>
|
||||
#include <LibWeb/Painting/SVGSVGPaintable.h>
|
||||
#include <LibWeb/Painting/StackingContext.h>
|
||||
#include <LibWeb/Painting/TableBordersPainting.h>
|
||||
#include <LibWeb/Painting/TextPaintable.h>
|
||||
#include <LibWeb/Painting/ViewportPaintable.h>
|
||||
#include <LibWeb/Platform/FontPlugin.h>
|
||||
|
@ -309,10 +310,15 @@ void PaintableBox::paint(PaintContext& context, PaintPhase phase) const
|
|||
paint_box_shadow(context);
|
||||
}
|
||||
|
||||
if (phase == PaintPhase::Border) {
|
||||
auto const is_table_with_collapsed_borders = display().is_table_inside() && computed_values().border_collapse() == CSS::BorderCollapse::Collapse;
|
||||
if (!display().is_table_cell() && !is_table_with_collapsed_borders && phase == PaintPhase::Border) {
|
||||
paint_border(context);
|
||||
}
|
||||
|
||||
if ((display().is_table_inside() || computed_values().border_collapse() == CSS::BorderCollapse::Collapse) && phase == PaintPhase::TableCollapsedBorder) {
|
||||
paint_table_borders(context, *this);
|
||||
}
|
||||
|
||||
if (phase == PaintPhase::Outline) {
|
||||
auto const& outline_data = this->outline_data();
|
||||
if (outline_data.has_value()) {
|
||||
|
@ -519,7 +525,7 @@ void PaintableBox::reset_scroll_offset(PaintContext& context, PaintPhase) const
|
|||
|
||||
void PaintableBox::apply_clip_overflow_rect(PaintContext& context, PaintPhase phase) const
|
||||
{
|
||||
if (!AK::first_is_one_of(phase, PaintPhase::Background, PaintPhase::Border, PaintPhase::Foreground, PaintPhase::Outline))
|
||||
if (!AK::first_is_one_of(phase, PaintPhase::Background, PaintPhase::Border, PaintPhase::TableCollapsedBorder, PaintPhase::Foreground, PaintPhase::Outline))
|
||||
return;
|
||||
|
||||
if (clip_rect().has_value()) {
|
||||
|
@ -542,7 +548,7 @@ void PaintableBox::apply_clip_overflow_rect(PaintContext& context, PaintPhase ph
|
|||
|
||||
void PaintableBox::clear_clip_overflow_rect(PaintContext& context, PaintPhase phase) const
|
||||
{
|
||||
if (!AK::first_is_one_of(phase, PaintPhase::Background, PaintPhase::Border, PaintPhase::Foreground, PaintPhase::Outline))
|
||||
if (!AK::first_is_one_of(phase, PaintPhase::Background, PaintPhase::Border, PaintPhase::TableCollapsedBorder, PaintPhase::Foreground, PaintPhase::Outline))
|
||||
return;
|
||||
|
||||
if (m_clipping_overflow) {
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <LibWeb/Painting/PaintableBox.h>
|
||||
#include <LibWeb/Painting/SVGPaintable.h>
|
||||
#include <LibWeb/Painting/StackingContext.h>
|
||||
#include <LibWeb/Painting/TableBordersPainting.h>
|
||||
#include <LibWeb/SVG/SVGMaskElement.h>
|
||||
|
||||
namespace Web::Painting {
|
||||
|
@ -134,13 +133,9 @@ void StackingContext::paint_descendants(PaintContext& context, Paintable const&
|
|||
case StackingContextPaintPhase::BackgroundAndBorders:
|
||||
if (!child_is_inline_or_replaced && !child.is_floating()) {
|
||||
paint_node(child, context, PaintPhase::Background);
|
||||
bool is_table_with_collapsed_borders = child.display().is_table_inside() && child.computed_values().border_collapse() == CSS::BorderCollapse::Collapse;
|
||||
if (!child.display().is_table_cell() && !is_table_with_collapsed_borders)
|
||||
paint_node(child, context, PaintPhase::Border);
|
||||
paint_node(child, context, PaintPhase::Border);
|
||||
paint_descendants(context, child, phase);
|
||||
if (child.display().is_table_inside() || child.computed_values().border_collapse() == CSS::BorderCollapse::Collapse) {
|
||||
paint_table_borders(context, verify_cast<PaintableBox>(child));
|
||||
}
|
||||
paint_node(child, context, PaintPhase::TableCollapsedBorder);
|
||||
}
|
||||
break;
|
||||
case StackingContextPaintPhase::Floats:
|
||||
|
@ -155,8 +150,7 @@ void StackingContext::paint_descendants(PaintContext& context, Paintable const&
|
|||
if (child_is_inline_or_replaced) {
|
||||
paint_node(child, context, PaintPhase::Background);
|
||||
paint_node(child, context, PaintPhase::Border);
|
||||
if (child.display().is_table_inside() && child.computed_values().border_collapse() == CSS::BorderCollapse::Separate)
|
||||
paint_table_borders(context, verify_cast<PaintableBox>(child));
|
||||
paint_node(child, context, PaintPhase::TableCollapsedBorder);
|
||||
paint_descendants(context, child, StackingContextPaintPhase::BackgroundAndBorders);
|
||||
}
|
||||
paint_descendants(context, child, phase);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue