1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "core/editing/FrameSelection.h"
8 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
9 #include "core/dom/Document.h"
10 #include "core/dom/Element.h"
11 #include "core/dom/Text.h"
12 #include "core/frame/FrameView.h"
13 #include "core/html/HTMLBodyElement.h"
14 #include "core/html/HTMLDocument.h"
15 #include "core/testing/DummyPageHolder.h"
16 #include "wtf/OwnPtr.h"
17 #include "wtf/PassRefPtr.h"
18 #include "wtf/RefPtr.h"
19 #include "wtf/StdLibExtras.h"
20 #include "wtf/testing/WTFTestHelpers.h"
21 #include <gtest/gtest.h>
23 using namespace blink;
27 class FrameSelectionTest : public ::testing::Test {
29 virtual void SetUp() OVERRIDE;
31 DummyPageHolder& dummyPageHolder() const { return *m_dummyPageHolder; }
32 HTMLDocument& document() const;
33 void setSelection(const VisibleSelection&);
34 FrameSelection& selection() const;
35 Text* textNode() { return m_textNode.get(); }
36 int layoutCount() const { return m_dummyPageHolder->frameView().layoutCount(); }
39 OwnPtr<DummyPageHolder> m_dummyPageHolder;
40 RawPtr<HTMLDocument> m_document;
41 RefPtrWillBePersistent<Text> m_textNode;
44 void FrameSelectionTest::SetUp()
46 m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600));
47 m_document = toHTMLDocument(&m_dummyPageHolder->document());
49 m_textNode = m_document->createTextNode("Hello, World!");
50 m_document->body()->appendChild(m_textNode.get());
53 HTMLDocument& FrameSelectionTest::document() const
58 void FrameSelectionTest::setSelection(const VisibleSelection& newSelection)
60 m_dummyPageHolder->frame().selection().setSelection(newSelection);
63 FrameSelection& FrameSelectionTest::selection() const
65 return m_dummyPageHolder->frame().selection();
68 TEST_F(FrameSelectionTest, SetValidSelection)
70 VisibleSelection validSelection(Position(textNode(), 0), Position(textNode(), 5));
71 EXPECT_FALSE(validSelection.isNone());
72 setSelection(validSelection);
73 EXPECT_FALSE(selection().isNone());
76 TEST_F(FrameSelectionTest, SetInvalidSelection)
78 // Create a new document without frame by using DOMImplementation.
80 RefPtrWillBeRawPtr<Document> documentWithoutFrame = Document::create();
81 RefPtrWillBeRawPtr<Element> body = documentWithoutFrame->createElement(HTMLNames::bodyTag, false);
82 documentWithoutFrame->appendChild(body);
83 RefPtrWillBeRawPtr<Text> anotherText = documentWithoutFrame->createTextNode("Hello, another world");
84 body->appendChild(anotherText);
86 // Create a new VisibleSelection for the new document without frame and
87 // update FrameSelection with the selection.
88 VisibleSelection invalidSelection;
89 invalidSelection.setWithoutValidation(Position(anotherText, 0), Position(anotherText, 5));
90 setSelection(invalidSelection);
92 EXPECT_TRUE(selection().isNone());
95 TEST_F(FrameSelectionTest, InvalidateCaretRect)
97 document().view()->updateLayoutAndStyleIfNeededRecursive();
99 VisibleSelection validSelection(Position(textNode(), 0), Position(textNode(), 0));
100 setSelection(validSelection);
101 selection().setCaretRectNeedsUpdate();
102 EXPECT_TRUE(selection().isCaretBoundsDirty());
103 selection().invalidateCaretRect();
104 EXPECT_FALSE(selection().isCaretBoundsDirty());
106 document().body()->removeChild(textNode());
107 document().updateLayoutIgnorePendingStylesheets();
108 selection().setCaretRectNeedsUpdate();
109 EXPECT_TRUE(selection().isCaretBoundsDirty());
110 selection().invalidateCaretRect();
111 EXPECT_FALSE(selection().isCaretBoundsDirty());
114 TEST_F(FrameSelectionTest, PaintCaretShouldNotLayout)
116 document().view()->updateLayoutAndStyleIfNeededRecursive();
118 document().body()->setContentEditable("true", ASSERT_NO_EXCEPTION);
119 document().body()->focus();
120 EXPECT_TRUE(document().body()->focused());
122 VisibleSelection validSelection(Position(textNode(), 0), Position(textNode(), 0));
123 selection().setCaretVisible(true);
124 setSelection(validSelection);
125 EXPECT_TRUE(selection().isCaret());
126 EXPECT_TRUE(selection().ShouldPaintCaretForTesting());
128 int startCount = layoutCount();
130 // To force layout in next updateLayout calling, widen view.
131 FrameView& frameView = dummyPageHolder().frameView();
132 IntRect frameRect = frameView.frameRect();
133 frameRect.setWidth(frameRect.width() + 1);
134 frameRect.setHeight(frameRect.height() + 1);
135 dummyPageHolder().frameView().setFrameRect(frameRect);
137 selection().paintCaret(nullptr, LayoutPoint(), LayoutRect());
138 EXPECT_EQ(startCount, layoutCount());