Commit 686b93c6 authored by Yoshifumi Inoue's avatar Yoshifumi Inoue Committed by Chromium LUCI CQ

Do not find first=letter text outside first-letter parent

This patch changes |FirstLetterTextLayoutObject()| in
|FirstLetterPseudoElement| not to find first-letter text out side first-
letter parent as follow-up of [1], which makes finding first-letter text
outside parent.

In below example, before this patch changing "contenteditable" attribute
of <div> causing rebuilding layout tree for <p>, then we have unexpected
<::first-letter> element for <p> with first-letter text "abc". Then we
have invalid layout tree with invalid |NGOffsetMapping| to crash painting
selection.

<style>p::first-letter { ... }</style>
<div contenteditable><p><b></b></p>abc</div>


[1] http://crrev.com/c/2560522 [CSS] Skip empty span when finding the
first-letter text

Bug: 1159762
Change-Id: I41f5d9e75080633f34c68b328945e1c92721e60b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2622362
Commit-Queue: Koji Ishii <kojii@chromium.org>
Auto-Submit: Yoshifumi Inoue <yosin@chromium.org>
Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#842418}
parent 3eaf0a3e
......@@ -182,12 +182,17 @@ LayoutText* FirstLetterPseudoElement::FirstLetterTextLayoutObject(
return nullptr;
} else if (first_letter_text_layout_object->IsInline() &&
!first_letter_text_layout_object->SlowFirstChild()) {
LayoutObject* next_sibling =
first_letter_text_layout_object->NextSibling();
first_letter_text_layout_object =
next_sibling
? next_sibling
: first_letter_text_layout_object->Parent()->NextSibling();
if (LayoutObject* next_sibling =
first_letter_text_layout_object->NextSibling()) {
first_letter_text_layout_object = next_sibling;
continue;
}
LayoutObject* parent = first_letter_text_layout_object->Parent();
if (parent && parent != parent_layout_object) {
first_letter_text_layout_object = parent->NextSibling();
continue;
}
return nullptr;
} else {
first_letter_text_layout_object =
first_letter_text_layout_object->SlowFirstChild();
......
......@@ -4,17 +4,32 @@
#include "third_party/blink/renderer/core/dom/first_letter_pseudo_element.h"
#include <gtest/gtest.h>
#include "third_party/blink/renderer/core/testing/page_test_base.h"
namespace blink {
class FirstLetterPseudoElementTest : public testing::Test {};
class FirstLetterPseudoElementTest : public PageTestBase {};
TEST_F(FirstLetterPseudoElementTest, DoesNotBreakEmoji) {
const UChar emoji[] = {0xD83D, 0xDE31, 0};
EXPECT_EQ(2u, FirstLetterPseudoElement::FirstLetterLength(emoji));
}
// http://crbug.com/1161370
TEST_F(FirstLetterPseudoElementTest, EmptySpanOnly) {
InsertStyleElement("p::first-letter { color: red; }");
SetBodyContent("<div><p id=sample><b></b></p>abc</div>");
Element& sample = *GetElementById("sample");
// Call Element::RebuildFirstLetterLayoutTree()
sample.setAttribute(html_names::kContenteditableAttr, "true");
const PseudoElement* const first_letter =
sample.GetPseudoElement(kPseudoIdFirstLetter);
// We should not have ::first-letter pseudo element because <p> has no text.
// See |FirstLetterPseudoElement::FirstLetterTextLayoutObject()| should
// return nullptr during rebuilding layout tree.
EXPECT_FALSE(first_letter);
}
TEST_F(FirstLetterPseudoElementTest, UnicodePairBreaking) {
const UChar test_string[] = {0xD800, 0xDD00, 'A', 0xD800, 0xDD00,
0xD800, 0xDD00, 'B', 0};
......
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