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. 4 5#include "config.h" 6#include "core/editing/FrameSelection.h" 7 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> 22 23using namespace blink; 24 25namespace { 26 27class FrameSelectionTest : public ::testing::Test { 28protected: 29 virtual void SetUp() OVERRIDE; 30 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(); } 37 38private: 39 OwnPtr<DummyPageHolder> m_dummyPageHolder; 40 RawPtr<HTMLDocument> m_document; 41 RefPtrWillBePersistent<Text> m_textNode; 42}; 43 44void FrameSelectionTest::SetUp() 45{ 46 m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600)); 47 m_document = toHTMLDocument(&m_dummyPageHolder->document()); 48 ASSERT(m_document); 49 m_textNode = m_document->createTextNode("Hello, World!"); 50 m_document->body()->appendChild(m_textNode.get()); 51} 52 53HTMLDocument& FrameSelectionTest::document() const 54{ 55 return *m_document; 56} 57 58void FrameSelectionTest::setSelection(const VisibleSelection& newSelection) 59{ 60 m_dummyPageHolder->frame().selection().setSelection(newSelection); 61} 62 63FrameSelection& FrameSelectionTest::selection() const 64{ 65 return m_dummyPageHolder->frame().selection(); 66} 67 68TEST_F(FrameSelectionTest, SetValidSelection) 69{ 70 VisibleSelection validSelection(Position(textNode(), 0), Position(textNode(), 5)); 71 EXPECT_FALSE(validSelection.isNone()); 72 setSelection(validSelection); 73 EXPECT_FALSE(selection().isNone()); 74} 75 76TEST_F(FrameSelectionTest, SetInvalidSelection) 77{ 78 // Create a new document without frame by using DOMImplementation. 79 DocumentInit dummy; 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); 85 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); 91 92 EXPECT_TRUE(selection().isNone()); 93} 94 95TEST_F(FrameSelectionTest, InvalidateCaretRect) 96{ 97 document().view()->updateLayoutAndStyleIfNeededRecursive(); 98 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()); 105 106 document().body()->removeChild(textNode()); 107 document().updateLayoutIgnorePendingStylesheets(); 108 selection().setCaretRectNeedsUpdate(); 109 EXPECT_TRUE(selection().isCaretBoundsDirty()); 110 selection().invalidateCaretRect(); 111 EXPECT_FALSE(selection().isCaretBoundsDirty()); 112} 113 114TEST_F(FrameSelectionTest, PaintCaretShouldNotLayout) 115{ 116 document().view()->updateLayoutAndStyleIfNeededRecursive(); 117 118 document().body()->setContentEditable("true", ASSERT_NO_EXCEPTION); 119 document().body()->focus(); 120 EXPECT_TRUE(document().body()->focused()); 121 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()); 127 128 int startCount = layoutCount(); 129 { 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); 136 } 137 selection().paintCaret(nullptr, LayoutPoint(), LayoutRect()); 138 EXPECT_EQ(startCount, layoutCount()); 139} 140 141} 142