Commit 1324be86 authored by Yoshifumi Inoue's avatar Yoshifumi Inoue Committed by Commit Bot

Make NextWordPosition() to utilize TextOffsetMapping

This patch changes |NextWordPosition()| to utilize |TextOffsetMapping| to make
|NextWordPosition()| to work with LayoutNG.

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

[1] http://crrev.com/c/737981 Simplify word granularity handling

Bug: 778507, 810579

Change-Id: I7e196b0ee390d68b93f2494333554279d6fbd42d
Reviewed-on: https://chromium-review.googlesource.com/1004536
Commit-Queue: Yoshifumi Inoue <yosin@chromium.org>
Reviewed-by: default avatarYoichi Osato <yoichio@chromium.org>
Reviewed-by: default avatarXiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#550106}
parent 47b4ea74
......@@ -31,7 +31,10 @@
#include "third_party/blink/renderer/core/editing/visible_units.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
#include "third_party/blink/renderer/core/editing/text_offset_mapping.h"
#include "third_party/blink/renderer/core/editing/visible_position.h"
#include "third_party/blink/renderer/core/layout/layout_block.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/text/text_boundaries.h"
......@@ -76,20 +79,25 @@ PositionTemplate<Strategy> EndOfWordAlgorithm(
return NextBoundary(p, EndWordBoundary);
}
unsigned NextWordPositionBoundary(
const UChar* characters,
unsigned length,
unsigned offset,
BoundarySearchContextAvailability may_have_more_context,
bool& need_more_context) {
if (may_have_more_context &&
EndOfFirstWordBoundaryContext(characters + offset, length - offset) ==
static_cast<int>(length - offset)) {
need_more_context = true;
return length;
PositionInFlatTree NextWordPositionInternal(
const PositionInFlatTree& position) {
PositionInFlatTree block_end_position;
for (const LayoutBlock* block =
&TextOffsetMapping::ComputeContainigBlock(position);
block; block = TextOffsetMapping::NextBlockFor(*block)) {
const TextOffsetMapping mapping(*block);
const String text = mapping.GetText();
const int offset =
block_end_position.IsNull() ? mapping.ComputeTextOffset(position) : 0;
const int word_end =
FindNextWordForward(text.Characters16(), text.length(), offset);
if (offset < word_end)
return mapping.GetPositionAfter(word_end);
block_end_position = mapping.GetRange().EndPosition();
}
need_more_context = false;
return FindNextWordForward(characters, length, offset);
// TODO(yosin): Once we have a case, we should remove following |DCHECK()|.
DCHECK(block_end_position.IsNotNull()) << block_end_position;
return block_end_position;
}
unsigned PreviousWordPositionBoundary(
......@@ -167,13 +175,32 @@ VisiblePositionInFlatTree EndOfWord(const VisiblePositionInFlatTree& position,
TextAffinity::kUpstreamIfPossible);
}
// ----
// TODO(editing-dev): Because of word boundary can not be an upstream position,
// we should make this function to return |PositionInFlatTree|.
PositionInFlatTreeWithAffinity NextWordPosition(
const PositionInFlatTree& start) {
const PositionInFlatTree next = NextWordPositionInternal(start);
// Note: The word boundary can not be upstream position.
const PositionInFlatTreeWithAffinity adjusted =
AdjustForwardPositionToAvoidCrossingEditingBoundaries(
PositionInFlatTreeWithAffinity(next), start);
DCHECK_EQ(adjusted.Affinity(), TextAffinity::kDownstream);
return adjusted;
}
PositionWithAffinity NextWordPosition(const Position& start) {
const PositionInFlatTreeWithAffinity& next =
NextWordPosition(ToPositionInFlatTree(start));
return PositionWithAffinity(ToPositionInDOMTree(next.GetPosition()),
next.Affinity());
}
// TODO(yosin): This function will be removed by replacing call sites to use
// |Position| version. since there are only two call sites, one is in test.
VisiblePosition NextWordPosition(const VisiblePosition& c) {
DCHECK(c.IsValid()) << c;
VisiblePosition next =
CreateVisiblePosition(NextBoundary(c, NextWordPositionBoundary),
TextAffinity::kUpstreamIfPossible);
return AdjustForwardPositionToAvoidCrossingEditingBoundaries(
next, c.DeepEquivalent());
return CreateVisiblePosition(NextWordPosition(c.DeepEquivalent()));
}
VisiblePosition PreviousWordPosition(const VisiblePosition& c) {
......
......@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
#include "third_party/blink/renderer/core/editing/visible_position.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
namespace blink {
......@@ -60,6 +61,20 @@ class VisibleUnitsWordTest : public EditingTestBase {
}
};
class ParameterizedVisibleUnitsWordTest
: public ::testing::WithParamInterface<bool>,
private ScopedLayoutNGForTest,
public VisibleUnitsWordTest {
protected:
ParameterizedVisibleUnitsWordTest() : ScopedLayoutNGForTest(GetParam()) {}
bool LayoutNGEnabled() const { return GetParam(); }
};
INSTANTIATE_TEST_CASE_P(All,
ParameterizedVisibleUnitsWordTest,
::testing::Bool());
TEST_F(VisibleUnitsWordTest, StartOfWordBasic) {
EXPECT_EQ("<p> |(1) abc def</p>", DoStartOfWord("<p>| (1) abc def</p>"));
EXPECT_EQ("<p> |(1) abc def</p>", DoStartOfWord("<p> |(1) abc def</p>"));
......@@ -367,7 +382,7 @@ TEST_F(VisibleUnitsWordTest, EndOfWordTextSecurity) {
EXPECT_EQ("abc<s>foo bar</s>baz|", DoEndOfWord("abc<s>foo bar</s>b|az"));
}
TEST_F(VisibleUnitsWordTest, NextWordBasic) {
TEST_P(ParameterizedVisibleUnitsWordTest, NextWordBasic) {
EXPECT_EQ("<p> (1|) abc def</p>", DoNextWord("<p>| (1) abc def</p>"));
EXPECT_EQ("<p> (1|) abc def</p>", DoNextWord("<p> |(1) abc def</p>"));
EXPECT_EQ("<p> (1|) abc def</p>", DoNextWord("<p> (|1) abc def</p>"));
......@@ -384,12 +399,12 @@ TEST_F(VisibleUnitsWordTest, NextWordBasic) {
EXPECT_EQ("<p> (1) abc def|</p>", DoNextWord("<p> (1) abc def</p>|"));
}
TEST_F(VisibleUnitsWordTest, NextWordCrossingBlock) {
TEST_P(ParameterizedVisibleUnitsWordTest, NextWordCrossingBlock) {
EXPECT_EQ("<p>abc|</p><p>def</p>", DoNextWord("<p>|abc</p><p>def</p>"));
EXPECT_EQ("<p>abc</p><p>def|</p>", DoNextWord("<p>abc|</p><p>def</p>"));
}
TEST_F(VisibleUnitsWordTest, NextWordMixedEditability) {
TEST_P(ParameterizedVisibleUnitsWordTest, NextWordMixedEditability) {
EXPECT_EQ(
"<p contenteditable>"
"abc<b contenteditable=\"false\">def ghi</b>|jkl mno</p>",
......@@ -412,7 +427,7 @@ TEST_F(VisibleUnitsWordTest, NextWordMixedEditability) {
"abc<b contenteditable=false>def ghi|</b>jkl mno</p>"));
}
TEST_F(VisibleUnitsWordTest, NextWordPunctuation) {
TEST_P(ParameterizedVisibleUnitsWordTest, NextWordPunctuation) {
EXPECT_EQ("abc|.def", DoNextWord("|abc.def"));
EXPECT_EQ("abc|.def", DoNextWord("a|bc.def"));
EXPECT_EQ("abc|.def", DoNextWord("ab|c.def"));
......@@ -428,7 +443,7 @@ TEST_F(VisibleUnitsWordTest, NextWordPunctuation) {
EXPECT_EQ("abc...def|", DoNextWord("abc...|def"));
}
TEST_F(VisibleUnitsWordTest, NextWordSkipTab) {
TEST_P(ParameterizedVisibleUnitsWordTest, NextWordSkipTab) {
InsertStyleElement("s { white-space: pre }");
EXPECT_EQ("<p><s>\t</s>foo|</p>", DoNextWord("<p><s>\t|</s>foo</p>"));
}
......
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