[LayoutNG] Add IsAfterNonCollapsedCharacter(node, offset) API
This patch adds a new API to LayoutNG offset mapping, so that we can
easily check if a given DOM offset is right after a non-collapsed
character.
This patch is a preparation for adding an NG version of
LayoutText::ContainsCaretOffset().
Bug: 771398
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_layout_ng
Change-Id: I93e8a89089661c6f17da6a7a847f75914cb36f75
Reviewed-on: https://chromium-review.googlesource.com/724230
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Reviewed-by: Emil A Eklund <eae@chromium.org>
Cr-Commit-Position: refs/heads/master@{#509915}diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_offset_mapping_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_offset_mapping_test.cc
index 4f99cb50..a13dd85 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_offset_mapping_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_offset_mapping_test.cc
@@ -13,6 +13,8 @@
namespace blink {
+// TODO(xiaochengh): Rename this test to NGOffsetMappingTest.
+
class NGInlineNodeOffsetMappingTest : public RenderingTest {
protected:
void SetUp() override {
@@ -70,6 +72,10 @@
return GetOffsetMapping().IsNonCollapsedCharacter(node, offset);
}
+ bool IsAfterNonCollapsedCharacter(const Node& node, unsigned offset) const {
+ return GetOffsetMapping().IsAfterNonCollapsedCharacter(node, offset);
+ }
+
RefPtr<const ComputedStyle> style_;
LayoutNGBlockFlow* layout_block_flow_ = nullptr;
LayoutObject* layout_object_ = nullptr;
@@ -151,6 +157,12 @@
EXPECT_TRUE(IsNonCollapsedCharacter(*foo_node, 1));
EXPECT_TRUE(IsNonCollapsedCharacter(*foo_node, 2));
EXPECT_FALSE(IsNonCollapsedCharacter(*foo_node, 3)); // false at node end
+
+ // false at node start
+ EXPECT_FALSE(IsAfterNonCollapsedCharacter(*foo_node, 0));
+ EXPECT_TRUE(IsAfterNonCollapsedCharacter(*foo_node, 1));
+ EXPECT_TRUE(IsAfterNonCollapsedCharacter(*foo_node, 2));
+ EXPECT_TRUE(IsAfterNonCollapsedCharacter(*foo_node, 3));
}
TEST_F(NGInlineNodeOffsetMappingTest, TwoTextNodes) {
@@ -198,6 +210,18 @@
EXPECT_TRUE(IsNonCollapsedCharacter(*bar_node, 1));
EXPECT_TRUE(IsNonCollapsedCharacter(*bar_node, 2));
EXPECT_FALSE(IsNonCollapsedCharacter(*bar_node, 3)); // false at node end
+
+ // false at node start
+ EXPECT_FALSE(IsAfterNonCollapsedCharacter(*foo_node, 0));
+ EXPECT_TRUE(IsAfterNonCollapsedCharacter(*foo_node, 1));
+ EXPECT_TRUE(IsAfterNonCollapsedCharacter(*foo_node, 2));
+ EXPECT_TRUE(IsAfterNonCollapsedCharacter(*foo_node, 3));
+
+ // false at node start
+ EXPECT_FALSE(IsAfterNonCollapsedCharacter(*bar_node, 0));
+ EXPECT_TRUE(IsAfterNonCollapsedCharacter(*bar_node, 1));
+ EXPECT_TRUE(IsAfterNonCollapsedCharacter(*bar_node, 2));
+ EXPECT_TRUE(IsAfterNonCollapsedCharacter(*bar_node, 3));
}
TEST_F(NGInlineNodeOffsetMappingTest, BRBetweenTextNodes) {
@@ -295,6 +319,16 @@
EXPECT_TRUE(IsNonCollapsedCharacter(*node, 6));
EXPECT_TRUE(IsNonCollapsedCharacter(*node, 7));
EXPECT_FALSE(IsNonCollapsedCharacter(*node, 8));
+
+ EXPECT_FALSE(IsAfterNonCollapsedCharacter(*node, 0));
+ EXPECT_TRUE(IsAfterNonCollapsedCharacter(*node, 1));
+ EXPECT_TRUE(IsAfterNonCollapsedCharacter(*node, 2));
+ EXPECT_TRUE(IsAfterNonCollapsedCharacter(*node, 3));
+ EXPECT_TRUE(IsAfterNonCollapsedCharacter(*node, 4));
+ EXPECT_FALSE(IsAfterNonCollapsedCharacter(*node, 5));
+ EXPECT_TRUE(IsAfterNonCollapsedCharacter(*node, 6));
+ EXPECT_TRUE(IsAfterNonCollapsedCharacter(*node, 7));
+ EXPECT_TRUE(IsAfterNonCollapsedCharacter(*node, 8));
}
TEST_F(NGInlineNodeOffsetMappingTest, FullyCollapsedWhiteSpaceNode) {
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_result.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_result.cc
index 90b6fa8..ea1b7dd 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_result.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_result.cc
@@ -170,4 +170,17 @@
unit->GetType() != NGOffsetMappingUnitType::kCollapsed;
}
+bool NGOffsetMappingResult::IsAfterNonCollapsedCharacter(
+ const Node& node,
+ unsigned offset) const {
+ if (!offset)
+ return false;
+ // In case we have one unit ending at |offset| and another starting at
+ // |offset|, we need to find the former. Hence, search with |offset - 1|.
+ const NGOffsetMappingUnit* unit =
+ GetMappingUnitForDOMOffset(node, offset - 1);
+ return unit && offset > unit->DOMStart() &&
+ unit->GetType() != NGOffsetMappingUnitType::kCollapsed;
+}
+
} // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_result.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_result.h
index 44fffb8..7738871 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_result.h
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_result.h
@@ -122,8 +122,13 @@
// Returns true if the character at the position is non-collapsed. If the
// offset is at the end of the node, returns false.
+ // TODO(xiaochengh): Rename to IsBeforeNonCollapsedCharacter().
bool IsNonCollapsedCharacter(const Node&, unsigned offset) const;
+ // Returns true if the offset is right after a non-collapsed character. If the
+ // offset is at the beginning of the node, returns false.
+ bool IsAfterNonCollapsedCharacter(const Node&, unsigned offset) const;
+
// TODO(xiaochengh): Add APIs for reverse mapping.
private: