Commit 872b5e32 authored by Xiaocheng Hu's avatar Xiaocheng Hu Committed by Commit Bot

[LayoutNG] Fix caret position resolution when dealing with floats

The current caret position resolution algorithm assumes that all
descendants of an inline formatting context fragments are inline, and
hence contained in a line box. This is not the case with floats and
out-of-flow positioned fragments.

This patch makes the algorithm handle them correctly.

Bug: 808914
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_layout_ng
Change-Id: If238323a9b9694fb4a9d1668254a89eea8d6756e
Reviewed-on: https://chromium-review.googlesource.com/902685Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Reviewed-by: default avatarYoichi Osato <yoichio@chromium.org>
Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#534629}
parent 2f443737
......@@ -656,4 +656,35 @@ TEST_P(ParameterizedLocalCaretRectTest, TextAndImageMixedHeight) {
{Position(text2, 1), TextAffinity::kDownstream}));
}
TEST_P(ParameterizedLocalCaretRectTest, FloatFirstLetter) {
LoadAhem();
InsertStyleElement("#container::first-letter{float:right}");
SetBodyContent(
"<div id=container style='font: 10px/10px Ahem; width: 40px'>foo</div>");
const Node* foo = GetElementById("container")->firstChild();
const LayoutObject* first_letter = AssociatedLayoutObjectOf(*foo, 0);
const LayoutObject* remaining_text = AssociatedLayoutObjectOf(*foo, 1);
// TODO(editing-dev): Legacy LocalCaretRectOfPosition() is not aware of the
// first-letter LayoutObject. Fix it.
EXPECT_EQ(
LocalCaretRect(LayoutNGEnabled() ? first_letter : remaining_text,
LayoutRect(0, 0, 1, 10)),
LocalCaretRectOfPosition({Position(foo, 0), TextAffinity::kDownstream}));
EXPECT_EQ(
LocalCaretRect(remaining_text,
LayoutRect(LayoutNGEnabled() ? 0 : 10, 0, 1, 10)),
LocalCaretRectOfPosition({Position(foo, 1), TextAffinity::kDownstream}));
EXPECT_EQ(
LocalCaretRect(remaining_text,
LayoutRect(LayoutNGEnabled() ? 10 : 20, 0, 1, 10)),
LocalCaretRectOfPosition({Position(foo, 2), TextAffinity::kDownstream}));
EXPECT_EQ(
LocalCaretRect(remaining_text, LayoutNGEnabled()
? LayoutRect(20, 0, 1, 10)
: LayoutRect()),
LocalCaretRectOfPosition({Position(foo, 3), TextAffinity::kDownstream}));
}
} // namespace blink
......@@ -415,8 +415,11 @@ NGCaretPosition ComputeNGCaretPosition(const LayoutBlockFlow& context,
current_line = ToNGPhysicalLineBoxFragment(child.fragment.get());
}
// Every inline fragment should have a line box (inclusive) ancestor.
DCHECK(current_line);
if (!current_line) {
// Floats and out-of-flow positioned children are not in any line box;
// they don't have caret positions by their sides, either.
continue;
}
const CaretPositionResolution resolution =
TryResolveCaretPositionWithFragment(*child.fragment, *current_line,
......
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