Commit 9e98ffbc authored by Yoshifumi Inoue's avatar Yoshifumi Inoue Committed by Commit Bot

Make TextOffsetMapping::FindBackwardInlineContents() to skip ancestors

This patch changes |TextOffsetMapping::FindBackwardInlineContents()| to skip
ancestors when current position is first child for avoiding looping by backward
word caret movement.

IN below example (assume we are in "div3"), before this patch we attempt to find
inline contents for "div2" and "div1", after this patch we use previous sibling
of "div1".
<div id=div1><div id=div2><div id=div3>|abc</div></div></div>

Bug: 1039829
Change-Id: I04a79bcb07c74658927a8eec40b4dead2cdf2fd4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2037303
Auto-Submit: Yoshifumi Inoue <yosin@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#738786}
parent 67aaaa5a
......@@ -52,6 +52,17 @@ bool CanBeInlineContentsContainer(const LayoutObject& layout_object) {
return HasNonPsuedoNode(*block_flow);
}
Node* PreviousNodeSkippingAncestors(const Node& node) {
ContainerNode* parent = FlatTreeTraversal::Parent(node);
for (Node* runner = FlatTreeTraversal::Previous(node); runner;
runner = FlatTreeTraversal::Previous(*runner)) {
if (runner != parent)
return runner;
parent = FlatTreeTraversal::Parent(*runner);
}
return nullptr;
}
// Returns outer most nested inline formatting context.
const LayoutBlockFlow& RootInlineContentsContainerOf(
const LayoutBlockFlow& block_flow) {
......@@ -118,6 +129,7 @@ const LayoutBlockFlow* ComputeInlineContentsAsBlockFlow(
TextOffsetMapping::InlineContents CreateInlineContentsFromBlockFlow(
const LayoutBlockFlow& block_flow) {
DCHECK(block_flow.ChildrenInline()) << block_flow;
const LayoutObject* first = nullptr;
for (const LayoutObject* runner = block_flow.FirstChild(); runner;
runner = runner->NextInPreOrder(&block_flow)) {
......@@ -270,7 +282,7 @@ TextOffsetMapping::InlineContents TextOffsetMapping::FindBackwardInlineContents(
auto previous_skipping_text_control = [](const Node& node) -> const Node* {
DCHECK(!EnclosingTextControl(&node));
const Node* previous = FlatTreeTraversal::Previous(node);
const Node* previous = PreviousNodeSkippingAncestors(node);
const TextControlElement* previous_text_control =
EnclosingTextControl(previous);
if (!previous_text_control)
......
......@@ -652,6 +652,108 @@ TEST_P(ParameterizedVisibleUnitsWordTest, PreviousWordCrossingPlaceholderBR) {
EXPECT_EQ("<p>|<br></p><p>abc</p>", DoPreviousWord("<p><br></p><p>|abc</p>"));
}
TEST_P(ParameterizedVisibleUnitsWordTest, PreviousWordInFloat) {
InsertStyleElement(
"c { display: block; float: right; }"
"e { display: block; }");
// To "|abc"
EXPECT_EQ("<c><e>|abc def ghi</e></c>",
DoPreviousWord("<c><e>|abc def ghi</e></c>"));
EXPECT_EQ("<c><e>|abc def ghi</e></c>",
DoPreviousWord("<c><e>a|bc def ghi</e></c>"));
EXPECT_EQ("<c><e>|abc def ghi</e></c>",
DoPreviousWord("<c><e>ab|c def ghi</e></c>"));
EXPECT_EQ("<c><e>|abc def ghi</e></c>",
DoPreviousWord("<c><e>abc| def ghi</e></c>"));
EXPECT_EQ("<c><e>|abc def ghi</e></c>",
DoPreviousWord("<c><e>abc |def ghi</e></c>"));
// To "|def"
EXPECT_EQ("<c><e>abc |def ghi</e></c>",
DoPreviousWord("<c><e>abc d|ef ghi</e></c>"));
EXPECT_EQ("<c><e>abc |def ghi</e></c>",
DoPreviousWord("<c><e>abc de|f ghi</e></c>"));
EXPECT_EQ("<c><e>abc |def ghi</e></c>",
DoPreviousWord("<c><e>abc def| ghi</e></c>"));
EXPECT_EQ("<c><e>abc |def ghi</e></c>",
DoPreviousWord("<c><e>abc def |ghi</e></c>"));
// To "|ghi"
EXPECT_EQ("<c><e>abc def |ghi</e></c>",
DoPreviousWord("<c><e>abc def g|hi</e></c>"));
EXPECT_EQ("<c><e>abc def |ghi</e></c>",
DoPreviousWord("<c><e>abc def gh|i</e></c>"));
EXPECT_EQ("<c><e>abc def |ghi</e></c>",
DoPreviousWord("<c><e>abc def ghi|</e></c>"));
}
TEST_P(ParameterizedVisibleUnitsWordTest, PreviousWordInInlineBlock) {
InsertStyleElement(
"c { display: inline-block; }"
"e { display: block; }");
// To "|abc"
EXPECT_EQ("<c><e>|abc def ghi</e></c>",
DoPreviousWord("<c><e>|abc def ghi</e></c>"));
EXPECT_EQ("<c><e>|abc def ghi</e></c>",
DoPreviousWord("<c><e>a|bc def ghi</e></c>"));
EXPECT_EQ("<c><e>|abc def ghi</e></c>",
DoPreviousWord("<c><e>ab|c def ghi</e></c>"));
EXPECT_EQ("<c><e>|abc def ghi</e></c>",
DoPreviousWord("<c><e>abc| def ghi</e></c>"));
EXPECT_EQ("<c><e>|abc def ghi</e></c>",
DoPreviousWord("<c><e>abc |def ghi</e></c>"));
// To "|def"
EXPECT_EQ("<c><e>abc |def ghi</e></c>",
DoPreviousWord("<c><e>abc d|ef ghi</e></c>"));
EXPECT_EQ("<c><e>abc |def ghi</e></c>",
DoPreviousWord("<c><e>abc de|f ghi</e></c>"));
EXPECT_EQ("<c><e>abc |def ghi</e></c>",
DoPreviousWord("<c><e>abc def| ghi</e></c>"));
EXPECT_EQ("<c><e>abc |def ghi</e></c>",
DoPreviousWord("<c><e>abc def |ghi</e></c>"));
// To "|ghi"
EXPECT_EQ("<c><e>abc def |ghi</e></c>",
DoPreviousWord("<c><e>abc def g|hi</e></c>"));
EXPECT_EQ("<c><e>abc def |ghi</e></c>",
DoPreviousWord("<c><e>abc def gh|i</e></c>"));
EXPECT_EQ("<c><e>abc def |ghi</e></c>",
DoPreviousWord("<c><e>abc def ghi|</e></c>"));
}
TEST_P(ParameterizedVisibleUnitsWordTest, PreviousWordInPositionAbsolute) {
InsertStyleElement(
"c { display: block; position: absolute; }"
"e { display: block; }");
// To "|abc"
EXPECT_EQ("<c><e>|abc def ghi</e></c>",
DoPreviousWord("<c><e>|abc def ghi</e></c>"));
EXPECT_EQ("<c><e>|abc def ghi</e></c>",
DoPreviousWord("<c><e>a|bc def ghi</e></c>"));
EXPECT_EQ("<c><e>|abc def ghi</e></c>",
DoPreviousWord("<c><e>ab|c def ghi</e></c>"));
EXPECT_EQ("<c><e>|abc def ghi</e></c>",
DoPreviousWord("<c><e>abc| def ghi</e></c>"));
EXPECT_EQ("<c><e>|abc def ghi</e></c>",
DoPreviousWord("<c><e>abc |def ghi</e></c>"));
// To "|def"
EXPECT_EQ("<c><e>abc |def ghi</e></c>",
DoPreviousWord("<c><e>abc d|ef ghi</e></c>"));
EXPECT_EQ("<c><e>abc |def ghi</e></c>",
DoPreviousWord("<c><e>abc de|f ghi</e></c>"));
EXPECT_EQ("<c><e>abc |def ghi</e></c>",
DoPreviousWord("<c><e>abc def| ghi</e></c>"));
EXPECT_EQ("<c><e>abc |def ghi</e></c>",
DoPreviousWord("<c><e>abc def |ghi</e></c>"));
// To "|ghi"
EXPECT_EQ("<c><e>abc def |ghi</e></c>",
DoPreviousWord("<c><e>abc def g|hi</e></c>"));
EXPECT_EQ("<c><e>abc def |ghi</e></c>",
DoPreviousWord("<c><e>abc def gh|i</e></c>"));
EXPECT_EQ("<c><e>abc def |ghi</e></c>",
DoPreviousWord("<c><e>abc def ghi|</e></c>"));
}
TEST_P(ParameterizedVisibleUnitsWordTest, PreviousWordSkipTextControl) {
EXPECT_EQ("|foo<input value=\"bla\">bar",
DoPreviousWord("|foo<input value=\"bla\">bar"));
......
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