Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1502)

Unified Diff: third_party/WebKit/Source/core/editing/LayoutPositionTest.cpp

Issue 1756763002: 2016-03-02T18:53:01 LayoutPosition Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 2016-04-25T19:02:18 Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/editing/LayoutPositionTest.cpp
diff --git a/third_party/WebKit/Source/core/editing/LayoutPositionTest.cpp b/third_party/WebKit/Source/core/editing/LayoutPositionTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..495132fabc23ce0edc67807f51a873e3baab4c45
--- /dev/null
+++ b/third_party/WebKit/Source/core/editing/LayoutPositionTest.cpp
@@ -0,0 +1,307 @@
+// Copyright 2016 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/editing/LayoutPosition.h"
+
+#include "core/dom/Element.h"
+#include "core/dom/NodeTraversal.h"
+#include "core/dom/Text.h"
+#include "core/editing/EditingTestBase.h"
+#include "core/editing/VisibleUnits.h"
+#include "core/layout/LayoutView.h"
+#include "core/layout/line/InlineTextBox.h"
+#include "wtf/Noncopyable.h"
+
+namespace blink {
+
+class LayoutPositionTest : public EditingTestBase {
+ WTF_MAKE_NONCOPYABLE(LayoutPositionTest);
+
+public:
+ // |LayoutPosition| constructors
+ LayoutPosition afterAnchorOf(LayoutObject*);
+ LayoutPosition beforeAnchorOf(LayoutObject*);
+ LayoutPosition beforeChildrenOf(LayoutObject*);
+ LayoutPosition textPositionOf(InlineBox*, int offsetInBox);
+
+ // |LayoutPosition| member variable getters
+ static PositionAnchorType anchorTypeOf(const LayoutPosition&);
+ static InlineBox* inlineBoxOf(const LayoutPosition&);
+ static LayoutObject* layoutObjectOf(const LayoutPosition&);
+ static int textOffsetOf(const LayoutPosition&);
+
+protected:
+ LayoutPositionTest() = default;
+
+ FloatQuad caretQuadOf(const LayoutPosition& position)
+ {
+ return position.computeCaretQuad();
+ }
+
+ // Shortcuts
+ LayoutPosition layoutPositionAfter(Node* node)
+ {
+ return LayoutPosition::create(Position::afterNode(node));
+ }
+
+ LayoutPosition layoutPositionBefore(Node* node)
+ {
+ return LayoutPosition::create(Position::beforeNode(node));
+ }
+
+ LayoutPosition layoutPositionOf(Node* node, int offset)
+ {
+ return LayoutPosition::create(Position(node, offset));
+ }
+};
+
+// static
+LayoutPosition LayoutPositionTest::afterAnchorOf(LayoutObject* layoutObject)
+{
+ return LayoutPosition::afterAnchorOf(layoutObject);
+}
+
+// static
+LayoutPosition LayoutPositionTest::beforeAnchorOf(LayoutObject* layoutObject)
+{
+ return LayoutPosition::beforeAnchorOf(layoutObject);
+}
+
+// static
+LayoutPosition LayoutPositionTest::beforeChildrenOf(LayoutObject* layoutObject)
+{
+ return LayoutPosition::beforeChildrenOf(layoutObject);
+}
+
+LayoutPosition LayoutPositionTest::textPositionOf(InlineBox* box, int offsetInBox)
+{
+ return LayoutPosition(InlineBoxPosition(box, offsetInBox));
+}
+
+// static
+PositionAnchorType LayoutPositionTest::anchorTypeOf(const LayoutPosition& position)
+{
+ return position.m_anchorType;
+}
+
+// static
+InlineBox* LayoutPositionTest::inlineBoxOf(const LayoutPosition& position)
+{
+ return position.m_inlineBox;
+}
+
+// static
+LayoutObject* LayoutPositionTest::layoutObjectOf(const LayoutPosition& position)
+{
+ return position.m_layoutObject;
+}
+
+// static
+int LayoutPositionTest::textOffsetOf(const LayoutPosition& position)
+{
+ ASSERT(position.isOffsetInAnchor());
+ return position.m_offsetInBox;
+}
+
+TEST_F(LayoutPositionTest, canPlaceCaret)
+{
+ setBodyContent("<div> 234 <br> </div>");
+ updateAllLifecyclePhases();
+
+ // Layout Tree of this test:
+ // +LayoutView {#document} (0,0)+800x600
+ // | +LayoutBlockFlow {HTML} (0,0)+800x600
+ // | | +LayoutBlockFlow {BODY} (8,8)+784x584
+ // | | | +LayoutBlockFlow {DIV} (0,0)+784x2
+ // | | | | | | +-RootInlineBox DIV frameRect=(0,0)+4x2 bidiLevel=0
+ // | | | | | | | +InlineTextBox "234 " start=2 end=5 bidiLevel=0
+ // | | | | +LayoutText {" 234 "}
+ // ------------>LayoutBR {BR}
+ Element* const body = document().body();
+ Node* const div = body->firstChild();
+ Node* const text = div->firstChild();
+ Node* const br = text->nextSibling();
+ Node* const lastText = div->lastChild();
+
+ EXPECT_TRUE(layoutPositionOf(body, 0).canPlaceCaret());
+ EXPECT_TRUE(layoutPositionBefore(div).canPlaceCaret());
+
+ EXPECT_TRUE(layoutPositionOf(div, 0).canPlaceCaret());
+ EXPECT_TRUE(layoutPositionBefore(text).canPlaceCaret());
+ EXPECT_TRUE(layoutPositionAfter(text).canPlaceCaret());
+ EXPECT_TRUE(layoutPositionOf(text, 0).canPlaceCaret());
+ EXPECT_TRUE(layoutPositionOf(text, 1).canPlaceCaret());
+ EXPECT_TRUE(layoutPositionOf(text, 2).canPlaceCaret());
+ EXPECT_TRUE(layoutPositionOf(text, 3).canPlaceCaret());
+ EXPECT_TRUE(layoutPositionOf(text, 4).canPlaceCaret());
+ EXPECT_TRUE(layoutPositionOf(text, 5).canPlaceCaret());
+ EXPECT_TRUE(layoutPositionOf(text, 6).canPlaceCaret());
+ EXPECT_TRUE(layoutPositionOf(text, 6).canPlaceCaret());
+
+ EXPECT_FALSE(layoutPositionBefore(br).canPlaceCaret());
+ EXPECT_FALSE(layoutPositionOf(div, 1).canPlaceCaret());
+ EXPECT_FALSE(layoutPositionAfter(br).canPlaceCaret())
+ << "Since it is hard to compute caret quad for after BR, we don't allow to place caret after BR.";
+
+ EXPECT_FALSE(layoutPositionBefore(lastText).canPlaceCaret())
+ << "We can't place caret before collapsed whitespace.";
+ EXPECT_FALSE(layoutPositionOf(div, 2).canPlaceCaret())
+ << "We can't place caret before collapsed whitespace.";
+ EXPECT_FALSE(layoutPositionAfter(lastText).canPlaceCaret())
+ << "We can't place caret before collapsed whitespace.";
+ EXPECT_FALSE(layoutPositionOf(div, 3).canPlaceCaret())
+ << "We can't place caret before collapsed whitespace.";
+
+ EXPECT_TRUE(layoutPositionAfter(div).canPlaceCaret());
+ EXPECT_TRUE(layoutPositionOf(body, 1).canPlaceCaret());
+}
+
+TEST_F(LayoutPositionTest, ctorLeftToRightSimple)
+{
+ setBodyContent("<div id=one>222</div>");
+ updateAllLifecyclePhases();
+
+ Element* const body = document().body();
+ Element* const one = body->querySelector("#one", ASSERT_NO_EXCEPTION);
+ InlineTextBox* const textBox = toLayoutText(one->firstChild()->layoutObject())->firstTextBox();
+
+ EXPECT_EQ(beforeAnchorOf(one->layoutObject()), layoutPositionOf(body, 0));
+ EXPECT_EQ(afterAnchorOf(one->layoutObject()), layoutPositionOf(body, 1));
+
+ EXPECT_EQ(beforeAnchorOf(one->layoutObject()), layoutPositionBefore(one))
+ << "beforeAnchor(one) is a valid position";
+ EXPECT_EQ(textPositionOf(textBox, 0), LayoutPosition::create(Position::firstPositionInNode(one)))
+ << "beforeChildren(one) should be text box position";
+ EXPECT_EQ(textPositionOf(textBox, 1), layoutPositionOf(one->firstChild(), 1))
+ << "offsetInAnchor('222') should be text box position";
+ EXPECT_EQ(textPositionOf(textBox, 3), LayoutPosition::create(Position::lastPositionInNode(one)))
+ << "afterChildren(one) should be end of text box";
+ EXPECT_EQ(afterAnchorOf(one->layoutObject()), layoutPositionAfter(one))
+ << "afterAnchor(one) is a valid position";
+
+ EXPECT_EQ(layoutPositionOf(body, 0), layoutPositionBefore(one))
+ << "(body, 0) and before(one) should be same.";
+ EXPECT_EQ(layoutPositionOf(body, 1), layoutPositionAfter(one))
+ << "(body, 0) and after(one) should be same.";
+
+ EXPECT_EQ(layoutPositionOf(one, 0), layoutPositionOf(one->firstChild(), 0))
+ << "(one, 0) and (text, 0) should be same.";
+ EXPECT_EQ(layoutPositionOf(one, 1), layoutPositionOf(one->firstChild(), 3))
+ << "(one, 1) and (text, 3) should be same.";
+}
+
+// See http://unicode.org/cldr/utility/bidi.jsp for BiDi level and ordering.
+TEST_F(LayoutPositionTest, ctorRightToLeftMixed)
+{
+ setBodyContent("<div id=one>mark 3.1% &#x0645;&#x0627;&#x0631;&#x0652;&#x0643 2.0.</div>");
+ updateAllLifecyclePhases();
+
+ Element* body = document().body();
+ Element* one = body->querySelector("#one", ASSERT_NO_EXCEPTION);
+ Node* text = one->firstChild();
+ // |text| node has four inline boxes based on BiIDi level.
+ // Node: "mark 3.1% "(L0) "ARABIC"(L1) "2.0"(L2) "."(L0)
+ // Layout: "mark 3.1% " "2.0" "ARABIC" "."
+ InlineTextBox* const textBox0 = toLayoutText(text->layoutObject())->firstTextBox();
+ InlineTextBox* const textBox1 = textBox0->nextTextBox();
+ InlineTextBox* const textBox2 = textBox1->nextTextBox();
+ InlineTextBox* const textBox3 = textBox2->nextTextBox();
+ ASSERT(textBox3 == toLayoutText(text->layoutObject())->lastTextBox());
+
+ EXPECT_EQ(textPositionOf(textBox0, 0), layoutPositionOf(text, 0));
+ EXPECT_EQ(textPositionOf(textBox0, 1), layoutPositionOf(text, 1));
+ EXPECT_EQ(textPositionOf(textBox0, 9), layoutPositionOf(text, 9));
+
+ EXPECT_EQ(textPositionOf(textBox2, 10), layoutPositionOf(text, 10));
+ EXPECT_EQ(textPositionOf(textBox2, 11), layoutPositionOf(text, 11));
+ EXPECT_EQ(textPositionOf(textBox2, 14), layoutPositionOf(text, 14));
+ EXPECT_EQ(textPositionOf(textBox2, 15), layoutPositionOf(text, 15));
+
+ EXPECT_EQ(textPositionOf(textBox1, 16), layoutPositionOf(text, 16));
+ EXPECT_EQ(textPositionOf(textBox1, 17), layoutPositionOf(text, 17));
+ EXPECT_EQ(textPositionOf(textBox1, 18), layoutPositionOf(text, 18));
+
+ EXPECT_EQ(textPositionOf(textBox3, 19), layoutPositionOf(text, 19));
+}
+
+TEST_F(LayoutPositionTest, ctorRightToLeftWithBidiOverride)
+{
+ setBodyContent("<span id=one dir=rtl>abc <bdo id=two dir=rtl>def</bdo> ghi</span>");
+ updateAllLifecyclePhases();
+
+ Element* body = document().body();
+ Element* one = body->querySelector("#one", ASSERT_NO_EXCEPTION);
+ Element* two = body->querySelector("#two", ASSERT_NO_EXCEPTION);
+
+ Node* firstText = one->firstChild();
+ Node* rtlText = two->firstChild();
+ Node* lastText = one->lastChild();
+
+ InlineTextBox* firstTextBox = toLayoutText(firstText->layoutObject())->lastTextBox();
+ InlineTextBox* rtlTextBox = toLayoutText(rtlText->layoutObject())->firstTextBox();
+ InlineTextBox* lastTextBox = toLayoutText(lastText->layoutObject())->firstTextBox();
+
+ EXPECT_EQ(textPositionOf(firstTextBox, 0), layoutPositionOf(firstText, 0));
+ EXPECT_EQ(textPositionOf(firstTextBox, 1), layoutPositionOf(firstText, 1));
+ EXPECT_EQ(textPositionOf(firstTextBox, 2), layoutPositionOf(firstText, 2));
+
+ EXPECT_EQ(textPositionOf(rtlTextBox, 0), layoutPositionOf(rtlText, 0));
+ EXPECT_EQ(textPositionOf(rtlTextBox, 1), layoutPositionOf(rtlText, 1));
+ EXPECT_EQ(textPositionOf(rtlTextBox, 2), layoutPositionOf(rtlText, 2));
+
+ EXPECT_EQ(textPositionOf(lastTextBox->nextTextBox(), 0), layoutPositionOf(lastText, 0));
+ EXPECT_EQ(textPositionOf(lastTextBox, 1), layoutPositionOf(lastText, 1));
+ EXPECT_EQ(textPositionOf(lastTextBox, 2), layoutPositionOf(lastText, 2));
+ EXPECT_EQ(textPositionOf(lastTextBox, 3), layoutPositionOf(lastText, 3));
+}
+
+TEST_F(LayoutPositionTest, isCaretEquivalentWithBr)
+{
+ setBodyContent("<div>one<br>two</div>");
+ updateAllLifecyclePhases();
+ Element* div = document().querySelector("div", ASSERT_NO_EXCEPTION);
+ Node* one = div->firstChild();
+ Node* two = div->lastChild();
+ Element* br = document().querySelector("br", ASSERT_NO_EXCEPTION);
+
+ const LayoutPosition& beforeBr = layoutPositionBefore(br);
+ const LayoutPosition& afterBr = layoutPositionAfter(br);
+ const LayoutPosition& one3 = layoutPositionOf(one, 3);
+ const LayoutPosition& two0 = layoutPositionOf(two, 0);
+
+ EXPECT_FALSE(beforeBr.isCaretEquivalent(afterBr));
+ EXPECT_TRUE(one3.isCaretEquivalent(beforeBr))
+ << "End of text and before BR should be equivalent.";
+ EXPECT_FALSE(two0.isCaretEquivalent(afterBr))
+ << "Since we can't place caret after BR, after BR and first position of next line aren't equivalent.";
+}
+
+TEST_F(LayoutPositionTest, isCaretEquivalentWithCollapsedWhitespace)
+{
+ setBodyContent("<div> 234 </div>");
+ updateAllLifecyclePhases();
+ Element* div = document().querySelector("div", ASSERT_NO_EXCEPTION);
+ Node* text = div->firstChild();
+
+ const LayoutPosition& before2 = layoutPositionOf(text, 2);
+ EXPECT_TRUE(before2.isCaretEquivalent(layoutPositionOf(text, 0)));
+ EXPECT_TRUE(before2.isCaretEquivalent(layoutPositionOf(text, 1)));
+ EXPECT_FALSE(before2.isCaretEquivalent(layoutPositionBefore(div)));
+ EXPECT_EQ(Position(div, 0), mostBackwardCaretPosition(Position(text, 2)));
+
+ const LayoutPosition& before5 = layoutPositionOf(text, 5);
+ EXPECT_TRUE(before5.isCaretEquivalent(layoutPositionOf(text, 6)));
+ EXPECT_TRUE(before5.isCaretEquivalent(layoutPositionOf(text, 7)));
+ EXPECT_FALSE(before2.isCaretEquivalent(layoutPositionAfter(div)));
+}
+
+TEST_F(LayoutPositionTest, null)
+{
+ EXPECT_TRUE(LayoutPosition().isNull());
+ EXPECT_FALSE(LayoutPosition().isNotNull());
+ EXPECT_TRUE(LayoutPosition() == LayoutPosition());
+ EXPECT_FALSE(LayoutPosition() != LayoutPosition());
+}
+
+} // namespace blink
« no previous file with comments | « third_party/WebKit/Source/core/editing/LayoutPosition.cpp ('k') | third_party/WebKit/Source/core/editing/LayoutTreePrinter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698