Commit 20cbbf21 authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

[FragmentItem] Remove |NodeForHitTest| from |NGPaintFragment|

It looks like we tried to copy the logic in |LayoutObject::
NodeForHitTest| to |NGPaintFragment|. As part of deprecating
|NGPaintFragment|, this patch moves it to |NGPhysicalFragment|,
using the existing logic in |LayoutObject|.

In future, this logic might be moved to |Node| or something
that represents the box tree. Until then, using the logic in
|LayoutObject| looks most reasonable.

Bug: 982194
Change-Id: Ib6b967dc616714eb2cb1a16585493d106c44c504
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1937953Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#719562}
parent 077c539b
...@@ -3330,17 +3330,22 @@ bool LayoutObject::HitTestAllPhases(HitTestResult& result, ...@@ -3330,17 +3330,22 @@ bool LayoutObject::HitTestAllPhases(HitTestResult& result,
} }
Node* LayoutObject::NodeForHitTest() const { Node* LayoutObject::NodeForHitTest() const {
Node* node = GetNode(); if (Node* node = GetNode())
return node;
// If we hit the anonymous layoutObjects inside generated content we should // If we hit the anonymous layoutObjects inside generated content we should
// actually hit the generated content so walk up to the PseudoElement. // actually hit the generated content so walk up to the PseudoElement.
if (!node && Parent() && Parent()->IsBeforeOrAfterContent()) { if (const LayoutObject* parent = Parent()) {
for (LayoutObject* layout_object = Parent(); layout_object && !node; if (parent->IsBeforeOrAfterContent() ||
layout_object = layout_object->Parent()) parent->StyleRef().StyleType() == kPseudoIdFirstLetter) {
node = layout_object->GetNode(); for (; parent; parent = parent->Parent()) {
if (Node* node = parent->GetNode())
return node;
}
}
} }
return node; return nullptr;
} }
void LayoutObject::UpdateHitTestResult(HitTestResult& result, void LayoutObject::UpdateHitTestResult(HitTestResult& result,
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h" #include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
#include "third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h" #include "third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
...@@ -32,6 +33,21 @@ static_assert(sizeof(NGPhysicalFragment) == ...@@ -32,6 +33,21 @@ static_assert(sizeof(NGPhysicalFragment) ==
sizeof(SameSizeAsNGPhysicalFragment), sizeof(SameSizeAsNGPhysicalFragment),
"NGPhysicalFragment should stay small"); "NGPhysicalFragment should stay small");
const LayoutObject* ListMarkerFromMarkerOrMarkerContent(
const LayoutObject* object) {
if (object->IsLayoutNGListMarkerIncludingInside())
return object;
// Check if this is a marker content.
if (object->IsAnonymous()) {
const LayoutObject* parent = object->Parent();
if (parent && parent->IsLayoutNGListMarkerIncludingInside())
return parent;
}
return nullptr;
}
bool AppendFragmentOffsetAndSize(const NGPhysicalFragment* fragment, bool AppendFragmentOffsetAndSize(const NGPhysicalFragment* fragment,
base::Optional<PhysicalOffset> fragment_offset, base::Optional<PhysicalOffset> fragment_offset,
StringBuilder* builder, StringBuilder* builder,
...@@ -488,6 +504,22 @@ bool NGPhysicalFragment::ShouldPaintDragCaret() const { ...@@ -488,6 +504,22 @@ bool NGPhysicalFragment::ShouldPaintDragCaret() const {
return false; return false;
} }
Node* NGPhysicalFragment::NodeForHitTest() const {
if (Node* node = layout_object_->NodeForHitTest())
return node;
// When the fragment is a list marker, return the list item.
if (const LayoutObject* marker =
ListMarkerFromMarkerOrMarkerContent(layout_object_)) {
if (const LayoutNGListItem* list_item =
LayoutNGListItem::FromMarker(*marker))
return list_item->GetNode();
return nullptr;
}
return nullptr;
}
String NGPhysicalFragment::ToString() const { String NGPhysicalFragment::ToString() const {
StringBuilder output; StringBuilder output;
output.AppendFormat("Type: '%d' Size: '%s'", Type(), output.AppendFormat("Type: '%d' Size: '%s'", Type(),
......
...@@ -202,6 +202,9 @@ class CORE_EXPORT NGPhysicalFragment ...@@ -202,6 +202,9 @@ class CORE_EXPORT NGPhysicalFragment
Node* GeneratingNode() const { Node* GeneratingNode() const {
return IsCSSBox() ? layout_object_->GeneratingNode() : nullptr; return IsCSSBox() ? layout_object_->GeneratingNode() : nullptr;
} }
// The node to return when hit-testing on this fragment. This can be different
// from GetNode() when this fragment is content of a pseudo node.
Node* NodeForHitTest() const;
// Whether there is a PaintLayer associated with the fragment. // Whether there is a PaintLayer associated with the fragment.
bool HasLayer() const { return IsCSSBox() && layout_object_->HasLayer(); } bool HasLayer() const { return IsCSSBox() && layout_object_->HasLayer(); }
......
...@@ -178,40 +178,10 @@ base::Optional<PositionWithAffinity> PositionForPointInChild( ...@@ -178,40 +178,10 @@ base::Optional<PositionWithAffinity> PositionForPointInChild(
return base::nullopt; return base::nullopt;
} }
// ::before, ::after and ::first-letter can be hit test targets.
bool CanBeHitTestTargetPseudoNode(const Node& node) {
auto* pseudo_element = DynamicTo<PseudoElement>(node);
if (!pseudo_element)
return false;
switch (pseudo_element->GetPseudoId()) {
case kPseudoIdBefore:
case kPseudoIdAfter:
case kPseudoIdFirstLetter:
return true;
default:
return false;
}
}
bool IsLastBRInPage(const LayoutObject& layout_object) { bool IsLastBRInPage(const LayoutObject& layout_object) {
return layout_object.IsBR() && !layout_object.NextInPreOrder(); return layout_object.IsBR() && !layout_object.NextInPreOrder();
} }
const LayoutObject* ListMarkerFromMarkerOrMarkerContent(
const LayoutObject* object) {
if (object->IsLayoutNGListMarkerIncludingInside())
return object;
// Check if this is a marker content.
if (object->IsAnonymous()) {
const LayoutObject* parent = object->Parent();
if (parent && parent->IsLayoutNGListMarkerIncludingInside())
return parent;
}
return nullptr;
}
} // namespace } // namespace
NGPaintFragment::NGPaintFragment( NGPaintFragment::NGPaintFragment(
...@@ -1152,44 +1122,6 @@ PositionWithAffinity NGPaintFragment::PositionForPoint( ...@@ -1152,44 +1122,6 @@ PositionWithAffinity NGPaintFragment::PositionForPoint(
return PositionForPointInInlineLevelBox(point); return PositionForPointInInlineLevelBox(point);
} }
Node* NGPaintFragment::NodeForHitTest() const {
if (GetNode())
return GetNode();
if (PhysicalFragment().IsLineBox())
return Parent()->NodeForHitTest();
// When the fragment is a list marker, return the list item.
if (const LayoutObject* object = GetLayoutObject()) {
if (const LayoutObject* marker =
ListMarkerFromMarkerOrMarkerContent(object)) {
if (const LayoutNGListItem* list_item =
LayoutNGListItem::FromMarker(*marker))
return list_item->GetNode();
return nullptr;
}
}
for (const NGPaintFragment* runner = Parent(); runner;
runner = runner->Parent()) {
// When the fragment is inside a ::first-letter, ::before or ::after pseudo
// node, return the pseudo node.
if (Node* node = runner->GetNode()) {
if (CanBeHitTestTargetPseudoNode(*node))
return node;
return nullptr;
}
// When the fragment is inside a list marker, return the list item.
if (runner->GetLayoutObject() &&
runner->GetLayoutObject()->IsLayoutNGListMarker()) {
return runner->NodeForHitTest();
}
}
return nullptr;
}
String NGPaintFragment::DebugName() const { String NGPaintFragment::DebugName() const {
StringBuilder name; StringBuilder name;
......
...@@ -217,7 +217,7 @@ class CORE_EXPORT NGPaintFragment : public RefCounted<NGPaintFragment>, ...@@ -217,7 +217,7 @@ class CORE_EXPORT NGPaintFragment : public RefCounted<NGPaintFragment>,
// The node to return when hit-testing on this fragment. This can be different // The node to return when hit-testing on this fragment. This can be different
// from GetNode() when this fragment is content of a pseudo node. // from GetNode() when this fragment is content of a pseudo node.
Node* NodeForHitTest() const; Node* NodeForHitTest() const { return PhysicalFragment().NodeForHitTest(); }
// Returns true when associated fragment of |layout_object| has line box. // Returns true when associated fragment of |layout_object| has line box.
static bool TryMarkFirstLineBoxDirtyFor(const LayoutObject& layout_object); static bool TryMarkFirstLineBoxDirtyFor(const LayoutObject& layout_object);
......
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