| Index: third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker_test.cc
|
| diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker_test.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e3d8a982f847947108d80cf29b6ceb81364755b5
|
| --- /dev/null
|
| +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker_test.cc
|
| @@ -0,0 +1,252 @@
|
| +// Copyright 2017 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "core/layout/ng/ng_base_layout_algorithm_test.h"
|
| +
|
| +#include "core/layout/ng/inline/ng_inline_layout_algorithm.h"
|
| +#include "core/layout/ng/inline/ng_inline_node.h"
|
| +#include "core/layout/ng/inline/ng_line_breaker.h"
|
| +#include "core/layout/ng/layout_ng_block_flow.h"
|
| +#include "core/layout/ng/ng_constraint_space_builder.h"
|
| +#include "platform/wtf/text/StringBuilder.h"
|
| +
|
| +namespace blink {
|
| +
|
| +class NGLineBreakerTest : public NGBaseLayoutAlgorithmTest {
|
| + protected:
|
| + NGInlineNode* CreateInlineNode(const String& html_content) {
|
| + SetBodyInnerHTML(html_content);
|
| +
|
| + LayoutNGBlockFlow* block_flow =
|
| + ToLayoutNGBlockFlow(GetLayoutObjectByElementId("container"));
|
| + NGInlineNode* inline_node =
|
| + new NGInlineNode(block_flow->FirstChild(), block_flow);
|
| +
|
| + return inline_node;
|
| + }
|
| +
|
| + // Break lines using the specified available width.
|
| + Vector<NGInlineItemResults> BreakLines(NGInlineNode* node,
|
| + LayoutUnit available_width) {
|
| + if (!node->IsPrepareLayoutFinished())
|
| + node->PrepareLayout();
|
| +
|
| + RefPtr<NGConstraintSpace> space =
|
| + NGConstraintSpaceBuilder(NGWritingMode::kHorizontalTopBottom)
|
| + .SetAvailableSize({available_width, NGSizeIndefinite})
|
| + .ToConstraintSpace(NGWritingMode::kHorizontalTopBottom);
|
| + NGLineBreaker line_breaker(node, space.Get());
|
| + NGInlineLayoutAlgorithm algorithm(node, space.Get());
|
| + Vector<NGInlineItemResults> lines;
|
| + while (true) {
|
| + NGInlineItemResults item_results;
|
| + line_breaker.NextLine(&item_results, &algorithm);
|
| + if (item_results.IsEmpty())
|
| + break;
|
| + lines.push_back(item_results);
|
| + }
|
| + return lines;
|
| + }
|
| +};
|
| +
|
| +namespace {
|
| +
|
| +String ToString(NGInlineItemResults line, NGInlineNode* node) {
|
| + StringBuilder builder;
|
| + for (const auto& item_result : line) {
|
| + builder.Append(
|
| + node->Text(item_result.start_offset, item_result.end_offset));
|
| + }
|
| + return builder.ToString();
|
| +}
|
| +
|
| +TEST_F(NGLineBreakerTest, SingleNode) {
|
| + LoadAhem();
|
| + NGInlineNode* node = CreateInlineNode(R"HTML(
|
| + <!DOCTYPE html>
|
| + <style>
|
| + #container {
|
| + font: 10px/1 Ahem;
|
| + }
|
| + </style>
|
| + <div id=container>123 456 789</div>
|
| + )HTML");
|
| +
|
| + Vector<NGInlineItemResults> lines;
|
| + lines = BreakLines(node, LayoutUnit(80));
|
| + EXPECT_EQ(2u, lines.size());
|
| + EXPECT_EQ("123 456", ToString(lines[0], node));
|
| + EXPECT_EQ("789", ToString(lines[1], node));
|
| +
|
| + lines = BreakLines(node, LayoutUnit(60));
|
| + EXPECT_EQ(3u, lines.size());
|
| + EXPECT_EQ("123", ToString(lines[0], node));
|
| + EXPECT_EQ("456", ToString(lines[1], node));
|
| + EXPECT_EQ("789", ToString(lines[2], node));
|
| +}
|
| +
|
| +TEST_F(NGLineBreakerTest, OverflowWord) {
|
| + LoadAhem();
|
| + NGInlineNode* node = CreateInlineNode(R"HTML(
|
| + <!DOCTYPE html>
|
| + <style>
|
| + #container {
|
| + font: 10px/1 Ahem;
|
| + }
|
| + </style>
|
| + <div id=container>12345 678</div>
|
| + )HTML");
|
| +
|
| + // The first line overflows, but the last line does not.
|
| + Vector<NGInlineItemResults> lines;
|
| + lines = BreakLines(node, LayoutUnit(40));
|
| + EXPECT_EQ(2u, lines.size());
|
| + EXPECT_EQ("12345", ToString(lines[0], node));
|
| + EXPECT_EQ("678", ToString(lines[1], node));
|
| +
|
| + // Both lines overflow.
|
| + lines = BreakLines(node, LayoutUnit(20));
|
| + EXPECT_EQ(2u, lines.size());
|
| + EXPECT_EQ("12345", ToString(lines[0], node));
|
| + EXPECT_EQ("678", ToString(lines[1], node));
|
| +}
|
| +
|
| +TEST_F(NGLineBreakerTest, OverflowAtomicInline) {
|
| + LoadAhem();
|
| + NGInlineNode* node = CreateInlineNode(R"HTML(
|
| + <!DOCTYPE html>
|
| + <style>
|
| + #container {
|
| + font: 10px/1 Ahem;
|
| + }
|
| + span {
|
| + display: inline-block;
|
| + width: 30px;
|
| + height: 10px;
|
| + }
|
| + </style>
|
| + <div id=container>12345<span></span>678</div>
|
| + )HTML");
|
| +
|
| + Vector<NGInlineItemResults> lines;
|
| + lines = BreakLines(node, LayoutUnit(80));
|
| + EXPECT_EQ(2u, lines.size());
|
| + EXPECT_EQ(String(u"12345\uFFFC"), ToString(lines[0], node));
|
| + EXPECT_EQ("678", ToString(lines[1], node));
|
| +
|
| + lines = BreakLines(node, LayoutUnit(70));
|
| + EXPECT_EQ(2u, lines.size());
|
| + EXPECT_EQ("12345", ToString(lines[0], node));
|
| + EXPECT_EQ(String(u"\uFFFC678"), ToString(lines[1], node));
|
| +
|
| + lines = BreakLines(node, LayoutUnit(40));
|
| + EXPECT_EQ(3u, lines.size());
|
| + EXPECT_EQ("12345", ToString(lines[0], node));
|
| + EXPECT_EQ(String(u"\uFFFC"), ToString(lines[1], node));
|
| + EXPECT_EQ("678", ToString(lines[2], node));
|
| +
|
| + lines = BreakLines(node, LayoutUnit(20));
|
| + EXPECT_EQ(3u, lines.size());
|
| + EXPECT_EQ("12345", ToString(lines[0], node));
|
| + EXPECT_EQ(String(u"\uFFFC"), ToString(lines[1], node));
|
| + EXPECT_EQ("678", ToString(lines[2], node));
|
| +}
|
| +
|
| +TEST_F(NGLineBreakerTest, OverflowMargin) {
|
| + LoadAhem();
|
| + NGInlineNode* node = CreateInlineNode(R"HTML(
|
| + <!DOCTYPE html>
|
| + <style>
|
| + #container {
|
| + font: 10px/1 Ahem;
|
| + }
|
| + span {
|
| + margin-right: 4em;
|
| + }
|
| + </style>
|
| + <div id=container><span>123 456</span> 789</div>
|
| + )HTML");
|
| + const Vector<NGInlineItem>& items = node->Items();
|
| +
|
| + // While "123 456" can fit in a line, "456" has a right margin that cannot
|
| + // fit. Since "456" and its right margin is not breakable, "456" should be on
|
| + // the next line.
|
| + Vector<NGInlineItemResults> lines;
|
| + lines = BreakLines(node, LayoutUnit(80));
|
| + EXPECT_EQ(3u, lines.size());
|
| + EXPECT_EQ("123", ToString(lines[0], node));
|
| + EXPECT_EQ("456", ToString(lines[1], node));
|
| + DCHECK_EQ(NGInlineItem::kCloseTag, items[lines[1].back().item_index].Type());
|
| + EXPECT_EQ("789", ToString(lines[2], node));
|
| +
|
| + // Same as above, but this time "456" overflows the line because it is 70px.
|
| + lines = BreakLines(node, LayoutUnit(60));
|
| + EXPECT_EQ(3u, lines.size());
|
| + EXPECT_EQ("123", ToString(lines[0], node));
|
| + EXPECT_EQ("456", ToString(lines[1], node));
|
| + DCHECK_EQ(NGInlineItem::kCloseTag, items[lines[1].back().item_index].Type());
|
| + EXPECT_EQ("789", ToString(lines[2], node));
|
| +}
|
| +
|
| +TEST_F(NGLineBreakerTest, BoundaryInWord) {
|
| + LoadAhem();
|
| + NGInlineNode* node = CreateInlineNode(R"HTML(
|
| + <!DOCTYPE html>
|
| + <style>
|
| + #container {
|
| + font: 10px/1 Ahem;
|
| + }
|
| + </style>
|
| + <div id=container><span>123 456</span>789 abc</div>
|
| + )HTML");
|
| +
|
| + // The element boundary within "456789" should not cause a break.
|
| + // Since "789" does not fit, it should go to the next line along with "456".
|
| + Vector<NGInlineItemResults> lines;
|
| + lines = BreakLines(node, LayoutUnit(80));
|
| + EXPECT_EQ(3u, lines.size());
|
| + EXPECT_EQ("123", ToString(lines[0], node));
|
| + EXPECT_EQ("456789", ToString(lines[1], node));
|
| + EXPECT_EQ("abc", ToString(lines[2], node));
|
| +
|
| + // Same as above, but this time "456789" overflows the line because it is
|
| + // 60px.
|
| + lines = BreakLines(node, LayoutUnit(50));
|
| + EXPECT_EQ(3u, lines.size());
|
| + EXPECT_EQ("123", ToString(lines[0], node));
|
| + EXPECT_EQ("456789", ToString(lines[1], node));
|
| + EXPECT_EQ("abc", ToString(lines[2], node));
|
| +}
|
| +
|
| +TEST_F(NGLineBreakerTest, BoundaryInFirstWord) {
|
| + LoadAhem();
|
| + NGInlineNode* node = CreateInlineNode(R"HTML(
|
| + <!DOCTYPE html>
|
| + <style>
|
| + #container {
|
| + font: 10px/1 Ahem;
|
| + }
|
| + </style>
|
| + <div id=container><span>123</span>456 789</div>
|
| + )HTML");
|
| +
|
| + Vector<NGInlineItemResults> lines;
|
| + lines = BreakLines(node, LayoutUnit(80));
|
| + EXPECT_EQ(2u, lines.size());
|
| + EXPECT_EQ("123456", ToString(lines[0], node));
|
| + EXPECT_EQ("789", ToString(lines[1], node));
|
| +
|
| + lines = BreakLines(node, LayoutUnit(50));
|
| + EXPECT_EQ(2u, lines.size());
|
| + EXPECT_EQ("123456", ToString(lines[0], node));
|
| + EXPECT_EQ("789", ToString(lines[1], node));
|
| +
|
| + lines = BreakLines(node, LayoutUnit(20));
|
| + EXPECT_EQ(2u, lines.size());
|
| + EXPECT_EQ("123456", ToString(lines[0], node));
|
| + EXPECT_EQ("789", ToString(lines[1], node));
|
| +}
|
| +
|
| +} // namespace
|
| +} // namespace blink
|
|
|