Commit 8262c5be authored by Yoshifumi Inoue's avatar Yoshifumi Inoue Committed by Commit Bot

Introduce NGPhysicalTextFragment::IsGeneratedText()

This patch introduces |NGPhysicalTextFragment::IsGeneratedText()| with
|NGTextType::kGeneratedText| to distinguish between normal text and generated
text, e.g. hyphen and ellipsis, for sorting fragments with |StartOffset()|.

This patch is a preparation of the patch[1].

[1] http://crrev.com/c/1114673 Make Element#innerText specification compliant

Bug: 859410
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_layout_ng
Change-Id: Ic9879985d1b5dd4cab921ce042ebc393043e3166
Reviewed-on: https://chromium-review.googlesource.com/1122061
Commit-Queue: Yoshifumi Inoue <yosin@chromium.org>
Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#572478}
parent d144879f
......@@ -41,12 +41,18 @@ enum class NGLineOrientation {
class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment {
public:
enum NGTextType {
// |text_| holds |NGNodeInlineData::text_content_|.
kNormalText,
kForcedLineBreak,
// Flow controls are not to be painted. In particular, a tabulation
// character and a soft-wrap opportunity.
kFlowControl,
kSymbolMarker
kSymbolMarker,
// |text_| holds generated contents instead of |text_content_| in
// |NGNodeInlineData|, e.g. hyphen, and ellipsis.
// Note: Contents generated by CSS pseudo element, e.g. ::before, ::after,
// are not classified to this. See IsAnonymousText() for them.
kGeneratedText,
// When adding new values, make sure the bit size of |sub_type_| is large
// enough to store.
};
......@@ -78,6 +84,8 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment {
}
NGTextType TextType() const { return static_cast<NGTextType>(sub_type_); }
// True if this is a generated text.
bool IsGeneratedText() const { return TextType() == kGeneratedText; }
// True if this is a forced line break.
bool IsLineBreak() const { return TextType() == kForcedLineBreak; }
// True if this is not for painting; i.e., a forced line break, a tabulation,
......
......@@ -35,6 +35,10 @@ class NGPhysicalTextFragmentTest : public NGLayoutTest {
}
return result;
}
static std::string GetText(const NGPhysicalTextFragment& fragment) {
return fragment.Text().ToString().Utf8().data();
}
};
TEST_F(NGPhysicalTextFragmentTest, LocalRect) {
......@@ -155,6 +159,32 @@ TEST_F(NGPhysicalTextFragmentTest, BeforeAndAfterAreAnonymousText) {
EXPECT_TRUE(after.IsAnonymousText());
}
TEST_F(NGPhysicalTextFragmentTest, Ellipsis) {
LoadAhem();
SetBodyInnerHTML(R"HTML(
<style>
#sample {
font: 10px/1 Ahem;
overflow: hidden;
text-overflow: ellipsis;
width: 4ch;
}
</style>
<p id="sample">abcdef</p>
)HTML");
auto text_fragments = CollectTextFragmentsInContainer("sample");
ASSERT_EQ(2u, text_fragments.size());
const NGPhysicalTextFragment& abcdef = *text_fragments[0];
const NGPhysicalTextFragment& ellipsis = *text_fragments[1];
EXPECT_EQ(NGPhysicalTextFragment::kNormalText, abcdef.TextType());
EXPECT_FALSE(abcdef.IsGeneratedText());
EXPECT_EQ(u8"abc", GetText(abcdef));
EXPECT_EQ(NGPhysicalTextFragment::kGeneratedText, ellipsis.TextType());
EXPECT_TRUE(ellipsis.IsGeneratedText());
EXPECT_EQ(u8"\u2026", GetText(ellipsis));
}
TEST_F(NGPhysicalTextFragmentTest, ListMarkerIsAnonymousText) {
SetBodyInnerHTML(
"<ol style='list-style-position:inside'>"
......@@ -170,6 +200,37 @@ TEST_F(NGPhysicalTextFragmentTest, ListMarkerIsAnonymousText) {
EXPECT_FALSE(text.IsAnonymousText());
}
TEST_F(NGPhysicalTextFragmentTest, SoftHyphen) {
LoadAhem();
SetBodyInnerHTML(R"HTML(
<style>
#sample {
font: 10px/1 Ahem;
width: 3ch;
}
</style>
<p id="sample">abc&shy;def</p>
)HTML");
auto text_fragments = CollectTextFragmentsInContainer("sample");
ASSERT_EQ(3u, text_fragments.size());
const NGPhysicalTextFragment& abc = *text_fragments[0];
const NGPhysicalTextFragment& shy = *text_fragments[1];
const NGPhysicalTextFragment& def = *text_fragments[2];
EXPECT_EQ(NGPhysicalTextFragment::kNormalText, abc.TextType());
EXPECT_FALSE(abc.IsGeneratedText());
// Note: ShapeResult::RunInfo.width_ == 0 for U+00AD
EXPECT_EQ(u8"abc\u00AD", GetText(abc));
EXPECT_EQ(NGPhysicalTextFragment::kGeneratedText, shy.TextType());
EXPECT_TRUE(shy.IsGeneratedText());
// Note: |ComputedStyle::HypenString()| returns "-" or U+2010 based on
// glyph availability.
if (GetText(shy) != "-")
EXPECT_EQ(u8"\u2010", GetText(shy));
EXPECT_EQ(NGPhysicalTextFragment::kNormalText, def.TextType());
EXPECT_FALSE(def.IsGeneratedText());
}
TEST_F(NGPhysicalTextFragmentTest, QuotationMarksAreAnonymousText) {
SetBodyInnerHTML("<div id=div><q>text</q></div>");
......
......@@ -40,6 +40,8 @@ void NGTextFragmentBuilder::SetItem(
const NGInlineItemsData& items_data,
NGInlineItemResult* item_result,
LayoutUnit line_height) {
DCHECK_NE(text_type, NGPhysicalTextFragment::kGeneratedText)
<< "Please use SetText() instead.";
DCHECK(item_result);
DCHECK(item_result->item->Style());
......@@ -65,7 +67,7 @@ void NGTextFragmentBuilder::SetText(
DCHECK(style);
DCHECK(shape_result);
text_type_ = NGPhysicalTextFragment::kNormalText;
text_type_ = NGPhysicalTextFragment::kGeneratedText;
text_ = text;
item_index_ = std::numeric_limits<unsigned>::max();
start_offset_ = shape_result->StartIndexForResult();
......
......@@ -29,6 +29,8 @@ class CORE_EXPORT NGTextFragmentBuilder final : public NGBaseFragmentBuilder {
const NGInlineItemsData&,
NGInlineItemResult*,
LayoutUnit line_height);
// Set text for generated text, e.g. hyphen and ellipsis.
void SetText(LayoutObject*,
const String& text,
scoped_refptr<const ComputedStyle>,
......
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