Commit e88bfe61 authored by Yoshifumi Inoue's avatar Yoshifumi Inoue Committed by Commit Bot

Add DCHECK for Before/After position

This patch adds |DCHECK()| to narrow down the case of returning null from
|Position::ComputeContainerNode()| for helping to search the root cause of
the bug[1] caused by |ComputeContainerNode()| returning null for non-null
position.

This patch also changes tests using before/after position of shadow root.
Node: document and document fragment, including shadow root, can not be an
anchor node of before/after position, since these position can not be represent
by RangeBoundaryPoint == container node with offset of child.

[1] https://crbug.com/882592 SelectionEditor should not call
Node::ContainsIncludingHostElements() with null

Bug: 882592, 889737
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_layout_ng
Change-Id: I9c7b0c8ad1c97d20a9080aa9baddea69faf805c5
Reviewed-on: https://chromium-review.googlesource.com/1248361Reviewed-by: default avatarKent Tamura <tkent@chromium.org>
Reviewed-by: default avatarYoichi Osato <yoichio@chromium.org>
Commit-Queue: Yoshifumi Inoue <yosin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#594636}
parent 96a9db16
...@@ -341,7 +341,8 @@ TEST_F(DocumentTest, CreateRangeAdjustedToTreeScopeWithPositionInShadowTree) { ...@@ -341,7 +341,8 @@ TEST_F(DocumentTest, CreateRangeAdjustedToTreeScopeWithPositionInShadowTree) {
"<div><select><option>012</option></div>"); "<div><select><option>012</option></div>");
Element* const select_element = GetDocument().QuerySelector("select"); Element* const select_element = GetDocument().QuerySelector("select");
const Position& position = const Position& position =
Position::AfterNode(*select_element->UserAgentShadowRoot()); Position(*select_element->UserAgentShadowRoot(),
select_element->UserAgentShadowRoot()->CountChildren());
Range* const range = Range* const range =
Document::CreateRangeAdjustedToTreeScope(GetDocument(), position); Document::CreateRangeAdjustedToTreeScope(GetDocument(), position);
EXPECT_EQ(range->startContainer(), select_element->parentNode()); EXPECT_EQ(range->startContainer(), select_element->parentNode());
......
...@@ -97,25 +97,23 @@ PositionTemplate<Strategy>::PositionTemplate(const Node* anchor_node, ...@@ -97,25 +97,23 @@ PositionTemplate<Strategy>::PositionTemplate(const Node* anchor_node,
: anchor_node_(const_cast<Node*>(anchor_node)), : anchor_node_(const_cast<Node*>(anchor_node)),
offset_(0), offset_(0),
anchor_type_(anchor_type) { anchor_type_(anchor_type) {
if (!anchor_node_) { #if DCHECK_IS_ON()
anchor_type_ = PositionAnchorType::kOffsetInAnchor; DCHECK(anchor_node_);
return; DCHECK_NE(anchor_type_, PositionAnchorType::kOffsetInAnchor);
} DCHECK(CanBeAnchorNode<Strategy>(anchor_node_.Get())) << anchor_node_;
if (anchor_node_->IsTextNode()) { if (anchor_node_->IsTextNode()) {
DCHECK(anchor_type_ == PositionAnchorType::kBeforeAnchor || DCHECK(anchor_type_ == PositionAnchorType::kBeforeAnchor ||
anchor_type_ == PositionAnchorType::kAfterAnchor); anchor_type_ == PositionAnchorType::kAfterAnchor)
<< *this;
return; return;
} }
if (anchor_node_->IsDocumentNode()) { if (!Strategy::Parent(*anchor_node_)) {
// Since |RangeBoundaryPoint| can't represent before/after Document, we // Before/After |anchor_node_| should have a parent node for converting
// should not use them. // to offset in anchor position.
DCHECK(IsBeforeChildren() || IsAfterChildren()) << anchor_type_; DCHECK(IsBeforeChildren() || IsAfterChildren()) << *this;
return; return;
} }
#if DCHECK_IS_ON()
DCHECK(CanBeAnchorNode<Strategy>(anchor_node_.Get())) << anchor_node_;
#endif #endif
DCHECK_NE(anchor_type_, PositionAnchorType::kOffsetInAnchor);
} }
// TODO(editing-dev): Once we change type of |anchor_node_| to // TODO(editing-dev): Once we change type of |anchor_node_| to
...@@ -190,8 +188,12 @@ Node* PositionTemplate<Strategy>::ComputeContainerNode() const { ...@@ -190,8 +188,12 @@ Node* PositionTemplate<Strategy>::ComputeContainerNode() const {
case PositionAnchorType::kOffsetInAnchor: case PositionAnchorType::kOffsetInAnchor:
return anchor_node_.Get(); return anchor_node_.Get();
case PositionAnchorType::kBeforeAnchor: case PositionAnchorType::kBeforeAnchor:
case PositionAnchorType::kAfterAnchor: case PositionAnchorType::kAfterAnchor: {
return Strategy::Parent(*anchor_node_); Node* const parent = Strategy::Parent(*anchor_node_);
// TODO(https://crbug.com/889737), Once we fix the issue, we should have
// |DCHECK(parent)|.
return parent;
}
} }
NOTREACHED(); NOTREACHED();
return nullptr; return nullptr;
......
...@@ -201,12 +201,6 @@ TEST_F(PositionTest, ToPositionInFlatTreeWithShadowRoot) { ...@@ -201,12 +201,6 @@ TEST_F(PositionTest, ToPositionInFlatTreeWithShadowRoot) {
EXPECT_EQ(PositionInFlatTree(host, PositionAnchorType::kBeforeChildren), EXPECT_EQ(PositionInFlatTree(host, PositionAnchorType::kBeforeChildren),
ToPositionInFlatTree( ToPositionInFlatTree(
Position(shadow_root, PositionAnchorType::kBeforeChildren))); Position(shadow_root, PositionAnchorType::kBeforeChildren)));
EXPECT_EQ(PositionInFlatTree(host, PositionAnchorType::kAfterAnchor),
ToPositionInFlatTree(
Position(shadow_root, PositionAnchorType::kAfterAnchor)));
EXPECT_EQ(PositionInFlatTree(host, PositionAnchorType::kBeforeAnchor),
ToPositionInFlatTree(
Position(shadow_root, PositionAnchorType::kBeforeAnchor)));
} }
TEST_F(PositionTest, TEST_F(PositionTest,
......
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