Commit 89aa7bd6 authored by David Grogan's avatar David Grogan Committed by Commit Bot

[css] Fix scroll anchor X dirty table layout crash

When an element is selected as scroll anchor, we need to get its
bounding box. But when a table has unlaid out table parts, we DCHECK
that its borders aren't being queried. When a table with unlaid out
table parts is the scroll anchor, the DCHECK was triggered.

The "fix" in this CL is to use the old border widths when scroll
anchoring code is looking for an anchor.

Bug: 746570
Change-Id: I424e3807c2ed7a7a20f02617e2e0586dba83e708
Reviewed-on: https://chromium-review.googlesource.com/679994Reviewed-by: default avatarSteve Kobes <skobes@chromium.org>
Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: David Grogan <dgrogan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#504279}
parent fdae685f
<!doctype html>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
body {
height:200vh;
}
table {
height: 200px;
width: 200px;
background-color: lime;
border-collapse: collapse; /* triggers problematic border calculation */
}
</style>
<table id=table1></table>
<script>
test(function(t) {
window.scrollBy(0, 10);
table1.innerHTML = "<tr><td style='background-color:lightblue'></td></tr>";
}, "No crash when a table with dirty internal layout is the scroll anchor.");
</script>
......@@ -52,6 +52,15 @@ namespace blink {
using namespace HTMLNames;
namespace {
bool g_disable_updating_collapsed_borders = false;
} // namespace
LayoutTable::DisableUpdatingCollapsedBorders::DisableUpdatingCollapsedBorders()
: disabler_(&g_disable_updating_collapsed_borders, true) {}
LayoutTable::LayoutTable(Element* element)
: LayoutBlock(element),
head_(nullptr),
......@@ -1650,6 +1659,12 @@ void LayoutTable::UpdateCollapsedOuterBorders() const {
if (collapsed_outer_borders_valid_)
return;
// If further valid code paths are found to call this function when
// needs_section_recalc_ is true, then we should remove this check in favor of
// if (NeedsSectionRecalc()) return;
if (g_disable_updating_collapsed_borders)
return;
collapsed_outer_borders_valid_ = true;
if (!ShouldCollapseBorders())
return;
......
......@@ -425,6 +425,17 @@ class CORE_EXPORT LayoutTable final : public LayoutBlock {
// Expose for LayoutTableCol::LocalVisualRectIgnoringVisibility().
using LayoutBlock::LocalVisualRectIgnoringVisibility;
class DisableUpdatingCollapsedBorders {
STACK_ALLOCATED();
WTF_MAKE_NONCOPYABLE(DisableUpdatingCollapsedBorders);
public:
DisableUpdatingCollapsedBorders();
private:
AutoReset<bool> disabler_;
};
protected:
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
void SimplifiedNormalFlowLayout() override;
......
......@@ -7,6 +7,7 @@
#include "core/frame/LocalFrameView.h"
#include "core/frame/UseCounter.h"
#include "core/layout/LayoutBlockFlow.h"
#include "core/layout/LayoutTable.h"
#include "core/layout/api/LayoutBoxItem.h"
#include "core/layout/line/InlineTextBox.h"
#include "core/paint/PaintLayer.h"
......@@ -246,6 +247,11 @@ void ScrollAnchor::NotifyBeforeLayout() {
}
if (!anchor_object_) {
// FindAnchor() and ComputeRelativeOffset() query a box's borders as part of
// its geometry. But when collapsed, table borders can depend on internal
// parts, which get sorted during a layout pass. When a table with dirty
// internal structure is checked as an anchor candidate, a DCHECK was hit.
LayoutTable::DisableUpdatingCollapsedBorders scoped_disabler;
FindAnchor();
if (!anchor_object_)
return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment