Commit dfed6d16 authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

Fix |LayoutNGBlockFlowMixin::NodeAtPoint()| for block fragmentation

This patch fixes |NodeAtPoint()| so that:
* The |LayoutObject| function does not support block
  fragmented objects.
* Make sure we traverse fragment tree, without going through
  |LayoutObject|, whenever it may have fragmented children.

The current code calls |LayoutBlock::HitTestChildren()| when
|!ChildrenInline()|. It is fixed to traverse fragment tree to
achieve the second point above.

The same philosophy as |Paint| in r824316 <crrev.com/c/2515429>.

Bug: 1061423
Change-Id: Ie153bfab663e9d7353378355b0734e725ed0516d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2517215Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Reviewed-by: default avatarMorten Stenshorne <mstensho@chromium.org>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#824886}
parent 9e285c75
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
#include "third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h" #include "third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h"
#include "third_party/blink/renderer/core/paint/block_paint_invalidator.h" #include "third_party/blink/renderer/core/paint/block_paint_invalidator.h"
#include "third_party/blink/renderer/core/paint/block_painter.h" #include "third_party/blink/renderer/core/paint/block_painter.h"
#include "third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h"
#include "third_party/blink/renderer/core/paint/object_paint_invalidator.h" #include "third_party/blink/renderer/core/paint/object_paint_invalidator.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
...@@ -1263,13 +1264,24 @@ bool LayoutBlock::HitTestChildren(HitTestResult& result, ...@@ -1263,13 +1264,24 @@ bool LayoutBlock::HitTestChildren(HitTestResult& result,
const PhysicalOffset& accumulated_offset, const PhysicalOffset& accumulated_offset,
HitTestAction hit_test_action) { HitTestAction hit_test_action) {
NOT_DESTROYED(); NOT_DESTROYED();
DCHECK(!ChildrenInline());
if (PhysicalFragmentCount() && CanTraversePhysicalFragments()) {
DCHECK(!Parent()->CanTraversePhysicalFragments());
DCHECK_LE(PhysicalFragmentCount(), 1u);
const NGPhysicalBoxFragment* fragment = GetPhysicalFragment(0);
DCHECK(fragment);
DCHECK(!fragment->HasItems());
return NGBoxFragmentPainter(*fragment).NodeAtPoint(
result, hit_test_location, accumulated_offset, hit_test_action);
}
// We may use legacy code to hit-test the anonymous fieldset content wrapper // We may use legacy code to hit-test the anonymous fieldset content wrapper
// child. The layout object for the rendered legend will be a child of that // child. The layout object for the rendered legend will be a child of that
// one, and has to be skipped here, since its fragment is actually laid out on // one, and has to be skipped here, since its fragment is actually laid out on
// the outside and is a sibling of the anonymous wrapper. // the outside and is a sibling of the anonymous wrapper.
bool may_contain_rendered_legend = IsAnonymousNGFieldsetContentWrapper(); bool may_contain_rendered_legend = IsAnonymousNGFieldsetContentWrapper();
DCHECK(!ChildrenInline());
PhysicalOffset scrolled_offset = accumulated_offset; PhysicalOffset scrolled_offset = accumulated_offset;
if (IsScrollContainer()) if (IsScrollContainer())
scrolled_offset -= PhysicalOffset(PixelSnappedScrolledContentOffset()); scrolled_offset -= PhysicalOffset(PixelSnappedScrolledContentOffset());
......
...@@ -231,6 +231,14 @@ bool LayoutNGBlockFlowMixin<Base>::NodeAtPoint( ...@@ -231,6 +231,14 @@ bool LayoutNGBlockFlowMixin<Base>::NodeAtPoint(
const HitTestLocation& hit_test_location, const HitTestLocation& hit_test_location,
const PhysicalOffset& accumulated_offset, const PhysicalOffset& accumulated_offset,
HitTestAction action) { HitTestAction action) {
// When |this| is NG block fragmented, the painter should traverse fragemnts
// instead of |LayoutObject|, because this function cannot handle block
// fragmented objects. We can come here only when |this| cannot traverse
// fragments, or the parent is legacy.
DCHECK(!Base::CanTraversePhysicalFragments() ||
!Base::Parent()->CanTraversePhysicalFragments());
DCHECK_LE(Base::PhysicalFragmentCount(), 1u);
if (!Base::MayIntersect(result, hit_test_location, accumulated_offset)) if (!Base::MayIntersect(result, hit_test_location, accumulated_offset))
return false; return false;
...@@ -245,7 +253,9 @@ bool LayoutNGBlockFlowMixin<Base>::NodeAtPoint( ...@@ -245,7 +253,9 @@ bool LayoutNGBlockFlowMixin<Base>::NodeAtPoint(
} }
if (UNLIKELY(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())) { if (UNLIKELY(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())) {
if (const NGPhysicalBoxFragment* fragment = CurrentFragment()) { if (Base::PhysicalFragmentCount()) {
const NGPhysicalBoxFragment* fragment = Base::GetPhysicalFragment(0);
DCHECK(fragment);
if (fragment->HasItems() || if (fragment->HasItems() ||
// Check descendants of this fragment because floats may be in the // Check descendants of this fragment because floats may be in the
// |NGFragmentItems| of the descendants. // |NGFragmentItems| of the descendants.
......
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