Commit fec2c2ce authored by Xiaocheng Hu's avatar Xiaocheng Hu Committed by Commit Bot

Handle invisible ::first-letter in MostForwardCaretPosition

MostForwardCaretPosition asserts that, if we have moved to a visible
text node different from start node, the caret position can always be
found from the beginning of the text node, which is incorrect if the
text node contains invisible first letter part.

This patch fixes the incorrect assertion as the function already
returns correct result in this case.

Bug: 858965
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_layout_ng
Change-Id: I8daa0ef59e06d4e9878c2e2c29bd12bf1825ead0
Reviewed-on: https://chromium-review.googlesource.com/1136944Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#575563}
parent dfd67074
......@@ -811,6 +811,22 @@ PositionInFlatTree MostBackwardCaretPosition(const PositionInFlatTree& position,
return MostBackwardCaretPosition<EditingInFlatTreeStrategy>(position, rule);
}
namespace {
bool HasInvisibleFirstLetter(const Node* node) {
if (!node || !node->IsTextNode())
return false;
const LayoutTextFragment* remaining_text =
ToLayoutTextFragmentOrNull(node->GetLayoutObject());
if (!remaining_text || !remaining_text->IsRemainingTextLayoutObject())
return false;
const LayoutTextFragment* first_letter =
ToLayoutTextFragmentOrNull(AssociatedLayoutObjectOf(*node, 0));
if (!first_letter || first_letter == remaining_text)
return false;
return first_letter->StyleRef().Visibility() != EVisibility::kVisible;
}
} // namespace
template <typename Strategy>
PositionTemplate<Strategy> MostForwardCaretPosition(
const PositionTemplate<Strategy>& position,
......@@ -903,7 +919,8 @@ PositionTemplate<Strategy> MostForwardCaretPosition(
continue;
const unsigned text_start_offset = text_layout_object->TextStartOffset();
if (current_node != start_node) {
DCHECK(current_pos.AtStartOfNode());
DCHECK(current_pos.AtStartOfNode() ||
HasInvisibleFirstLetter(current_node));
return PositionTemplate<Strategy>(
current_node, layout_object->CaretMinOffset() + text_start_offset);
}
......
......@@ -761,5 +761,13 @@ TEST_F(VisibleUnitsTest,
EXPECT_EQ(Position(text, 2), start);
}
TEST_F(VisibleUnitsTest, MostForwardCaretPositionWithInvisibleFirstLetter) {
InsertStyleElement("div::first-letter{visibility:hidden}");
// Use special syntax to set input position DIV@0
const Position position = SetCaretTextToBody("<div><!--|-->foo</div>");
const Node* foo = GetDocument().QuerySelector("div")->firstChild();
EXPECT_EQ(Position(foo, 1), MostForwardCaretPosition(position));
}
} // namespace visible_units_test
} // namespace blink
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