Commit a9076200 authored by Oriol Brufau's avatar Oriol Brufau Committed by Commit Bot

[editing] Fix DCHECK failure in ToPositionInFlatTree

A Shadow DOM V0 insertion point can't participate in the flat tree, so
attempting to convert a Position with such an anchor node into a
PositionInFlatTree used to produce a DCHECK failure.

This patch makes ToPositionInFlatTree use a position with the parent
node, if the given one is a V0 insertion point.

Bug: 1151536

Test=PositionTest.ToPositionInFlatTreeWithV0InsertionPoint1
Test=PositionTest.ToPositionInFlatTreeWithV0InsertionPoint2
Test=PositionTest.ToPositionInFlatTreeWithV0InsertionPoint3

Change-Id: I2d823294ed092ceb7dca4cd708fd75eca5a55f92
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2551131
Commit-Queue: Oriol Brufau <obrufau@igalia.com>
Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#830527}
parent b956187f
......@@ -592,6 +592,10 @@ PositionInFlatTree ToPositionInFlatTree(const Position& pos) {
if (pos.IsOffsetInAnchor()) {
if (anchor->IsCharacterDataNode())
return PositionInFlatTree(anchor, pos.ComputeOffsetInContainerNode());
if (IsActiveV0InsertionPoint(*anchor)) {
return ToPositionInFlatTree(Position(NodeTraversal::Parent(*anchor),
NodeTraversal::Index(*anchor)));
}
DCHECK(!anchor->IsElementNode() || anchor->CanParticipateInFlatTree());
int offset = pos.ComputeOffsetInContainerNode();
Node* child = NodeTraversal::ChildAt(*anchor, offset);
......@@ -620,9 +624,11 @@ PositionInFlatTree ToPositionInFlatTree(const Position& pos) {
if (anchor->IsShadowRoot())
return PositionInFlatTree(anchor->OwnerShadowHost(), pos.AnchorType());
if (IsActiveV0InsertionPoint(*anchor))
return ToPositionInFlatTree(pos.ToOffsetInAnchor());
DCHECK(anchor->CanParticipateInFlatTree());
if (pos.IsBeforeAnchor() || pos.IsAfterAnchor()) {
if (anchor->CanParticipateInFlatTree() &&
!FlatTreeTraversal::Parent(*anchor)) {
if (!FlatTreeTraversal::Parent(*anchor)) {
// For Before/AfterAnchor, if |anchor| doesn't have parent in the flat
// tree, there is no valid corresponding PositionInFlatTree.
// Since this function is a primitive function, we do not adjust |pos|
......
......@@ -228,6 +228,62 @@ TEST_F(PositionTest, ToPositionInFlatTreeWithEmptyShadowRoot) {
ToPositionInFlatTree(Position(shadow_root, 0)));
}
TEST_F(PositionTest, ToPositionInFlatTreeWithV0InsertionPoint1) {
SetBodyContent("<p id=host></p>");
ShadowRoot* shadow_root = SetShadowContent("<content></content>", "host");
Element* host = GetDocument().getElementById("host");
Node* content = shadow_root->QuerySelector("content");
EXPECT_FALSE(content->CanParticipateInFlatTree());
EXPECT_EQ(PositionInFlatTree(host, 0),
ToPositionInFlatTree(Position::BeforeNode(*content)));
EXPECT_EQ(PositionInFlatTree(host, 0),
ToPositionInFlatTree(Position::FirstPositionInNode(*content)));
EXPECT_EQ(PositionInFlatTree(host, 0),
ToPositionInFlatTree(Position(content, 0)));
EXPECT_EQ(PositionInFlatTree(host, 0),
ToPositionInFlatTree(Position::LastPositionInNode(*content)));
EXPECT_EQ(PositionInFlatTree::LastPositionInNode(*host),
ToPositionInFlatTree(Position::AfterNode(*content)));
}
TEST_F(PositionTest, ToPositionInFlatTreeWithV0InsertionPoint2) {
SetBodyContent("<p id=host></p>");
ShadowRoot* shadow_root =
SetShadowContent("foo<content></content>bar", "host");
Element* host = GetDocument().getElementById("host");
Node* content = shadow_root->QuerySelector("content");
EXPECT_FALSE(content->CanParticipateInFlatTree());
EXPECT_EQ(PositionInFlatTree(host, 1),
ToPositionInFlatTree(Position::BeforeNode(*content)));
EXPECT_EQ(PositionInFlatTree(host, 1),
ToPositionInFlatTree(Position::FirstPositionInNode(*content)));
EXPECT_EQ(PositionInFlatTree(host, 1),
ToPositionInFlatTree(Position(content, 0)));
EXPECT_EQ(PositionInFlatTree(host, 1),
ToPositionInFlatTree(Position::LastPositionInNode(*content)));
EXPECT_EQ(PositionInFlatTree(host, 1),
ToPositionInFlatTree(Position::AfterNode(*content)));
}
TEST_F(PositionTest, ToPositionInFlatTreeWithV0InsertionPoint3) {
SetBodyContent("<p id=host><b>11</b><b>22</b></p>");
ShadowRoot* shadow_root =
SetShadowContent("foo<content></content>bar", "host");
Element* host = GetDocument().getElementById("host");
Node* content = shadow_root->QuerySelector("content");
EXPECT_FALSE(content->CanParticipateInFlatTree());
EXPECT_EQ(PositionInFlatTree(host, 1),
ToPositionInFlatTree(Position::BeforeNode(*content)));
EXPECT_EQ(PositionInFlatTree(host, 1),
ToPositionInFlatTree(Position::FirstPositionInNode(*content)));
EXPECT_EQ(PositionInFlatTree(host, 1),
ToPositionInFlatTree(Position(content, 0)));
EXPECT_EQ(PositionInFlatTree(host, 1),
ToPositionInFlatTree(Position::LastPositionInNode(*content)));
EXPECT_EQ(PositionInFlatTree(host, 3),
ToPositionInFlatTree(Position::AfterNode(*content)));
}
TEST_F(PositionTest, NullPositionNotConnected) {
EXPECT_FALSE(Position().IsConnected());
EXPECT_FALSE(PositionInFlatTree().IsConnected());
......
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