OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/editing/FrameSelection.h" | 5 #include "core/editing/FrameSelection.h" |
6 | 6 |
7 #include "bindings/core/v8/ExceptionStatePlaceholder.h" | 7 #include "bindings/core/v8/ExceptionStatePlaceholder.h" |
8 #include "core/dom/Document.h" | 8 #include "core/dom/Document.h" |
9 #include "core/dom/Element.h" | 9 #include "core/dom/Element.h" |
10 #include "core/dom/Text.h" | 10 #include "core/dom/Text.h" |
11 #include "core/editing/EditingTestBase.h" | 11 #include "core/editing/EditingTestBase.h" |
12 #include "core/frame/FrameView.h" | 12 #include "core/frame/FrameView.h" |
13 #include "core/html/HTMLBodyElement.h" | 13 #include "core/html/HTMLBodyElement.h" |
14 #include "core/html/HTMLDocument.h" | 14 #include "core/html/HTMLDocument.h" |
15 #include "core/layout/LayoutView.h" | 15 #include "core/layout/LayoutView.h" |
16 #include "core/paint/PaintInfo.h" | 16 #include "core/paint/PaintInfo.h" |
| 17 #include "core/paint/PaintLayer.h" |
17 #include "core/testing/DummyPageHolder.h" | 18 #include "core/testing/DummyPageHolder.h" |
18 #include "platform/graphics/paint/DrawingRecorder.h" | 19 #include "platform/graphics/paint/DrawingRecorder.h" |
19 #include "platform/graphics/paint/PaintController.h" | 20 #include "platform/graphics/paint/PaintController.h" |
20 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
21 #include "wtf/OwnPtr.h" | 22 #include "wtf/OwnPtr.h" |
22 #include "wtf/PassRefPtr.h" | 23 #include "wtf/PassRefPtr.h" |
23 #include "wtf/RefPtr.h" | 24 #include "wtf/RefPtr.h" |
24 #include "wtf/StdLibExtras.h" | 25 #include "wtf/StdLibExtras.h" |
25 | 26 |
26 namespace blink { | 27 namespace blink { |
27 | 28 |
28 class FrameSelectionTest : public EditingTestBase { | 29 class FrameSelectionTest : public EditingTestBase { |
29 protected: | 30 protected: |
30 void setSelection(const VisibleSelection&); | 31 void setSelection(const VisibleSelection&); |
31 FrameSelection& selection() const; | 32 FrameSelection& selection() const; |
32 const VisibleSelection& visibleSelectionInDOMTree() const { return selection
().selection(); } | 33 const VisibleSelection& visibleSelectionInDOMTree() const { return selection
().selection(); } |
33 const VisibleSelectionInFlatTree& visibleSelectionInFlatTree() const { retur
n selection().selectionInFlatTree(); } | 34 const VisibleSelectionInFlatTree& visibleSelectionInFlatTree() const { retur
n selection().selectionInFlatTree(); } |
34 | 35 |
35 PassRefPtrWillBeRawPtr<Text> appendTextNode(const String& data); | 36 PassRefPtrWillBeRawPtr<Text> appendTextNode(const String& data); |
36 int layoutCount() const { return dummyPageHolder().frameView().layoutCount()
; } | 37 int layoutCount() const { return dummyPageHolder().frameView().layoutCount()
; } |
37 | 38 |
| 39 bool shouldPaintCaretForTesting() const { return selection().shouldPaintCare
tForTesting(); } |
| 40 bool isPreviousCaretDirtyForTesting() const { return selection().isPreviousC
aretDirtyForTesting(); } |
| 41 |
38 private: | 42 private: |
39 RefPtrWillBePersistent<Text> m_textNode; | 43 RefPtrWillBePersistent<Text> m_textNode; |
40 }; | 44 }; |
41 | 45 |
42 void FrameSelectionTest::setSelection(const VisibleSelection& newSelection) | 46 void FrameSelectionTest::setSelection(const VisibleSelection& newSelection) |
43 { | 47 { |
44 dummyPageHolder().frame().selection().setSelection(newSelection); | 48 dummyPageHolder().frame().selection().setSelection(newSelection); |
45 } | 49 } |
46 | 50 |
47 FrameSelection& FrameSelectionTest::selection() const | 51 FrameSelection& FrameSelectionTest::selection() const |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 document().view()->updateAllLifecyclePhases(); | 114 document().view()->updateAllLifecyclePhases(); |
111 | 115 |
112 document().body()->setContentEditable("true", ASSERT_NO_EXCEPTION); | 116 document().body()->setContentEditable("true", ASSERT_NO_EXCEPTION); |
113 document().body()->focus(); | 117 document().body()->focus(); |
114 EXPECT_TRUE(document().body()->focused()); | 118 EXPECT_TRUE(document().body()->focused()); |
115 | 119 |
116 VisibleSelection validSelection(Position(text, 0), Position(text, 0)); | 120 VisibleSelection validSelection(Position(text, 0), Position(text, 0)); |
117 selection().setCaretVisible(true); | 121 selection().setCaretVisible(true); |
118 setSelection(validSelection); | 122 setSelection(validSelection); |
119 EXPECT_TRUE(selection().isCaret()); | 123 EXPECT_TRUE(selection().isCaret()); |
120 EXPECT_TRUE(selection().ShouldPaintCaretForTesting()); | 124 EXPECT_TRUE(shouldPaintCaretForTesting()); |
121 | 125 |
122 int startCount = layoutCount(); | 126 int startCount = layoutCount(); |
123 { | 127 { |
124 // To force layout in next updateLayout calling, widen view. | 128 // To force layout in next updateLayout calling, widen view. |
125 FrameView& frameView = dummyPageHolder().frameView(); | 129 FrameView& frameView = dummyPageHolder().frameView(); |
126 IntRect frameRect = frameView.frameRect(); | 130 IntRect frameRect = frameView.frameRect(); |
127 frameRect.setWidth(frameRect.width() + 1); | 131 frameRect.setWidth(frameRect.width() + 1); |
128 frameRect.setHeight(frameRect.height() + 1); | 132 frameRect.setHeight(frameRect.height() + 1); |
129 dummyPageHolder().frameView().setFrameRect(frameRect); | 133 dummyPageHolder().frameView().setFrameRect(frameRect); |
130 } | 134 } |
131 OwnPtr<PaintController> paintController = PaintController::create(); | 135 OwnPtr<PaintController> paintController = PaintController::create(); |
132 GraphicsContext context(*paintController); | 136 GraphicsContext context(*paintController); |
133 DrawingRecorder drawingRecorder(context, *dummyPageHolder().frameView().layo
utView(), DisplayItem::Caret, LayoutRect::infiniteIntRect()); | 137 DrawingRecorder drawingRecorder(context, *dummyPageHolder().frameView().layo
utView(), DisplayItem::Caret, LayoutRect::infiniteIntRect()); |
134 selection().paintCaret(context, LayoutPoint()); | 138 selection().paintCaret(context, LayoutPoint()); |
135 EXPECT_EQ(startCount, layoutCount()); | 139 EXPECT_EQ(startCount, layoutCount()); |
136 } | 140 } |
137 | 141 |
| 142 TEST_F(FrameSelectionTest, InvalidatePreviousCaretAfterRemovingLastCharacter) |
| 143 { |
| 144 RefPtrWillBeRawPtr<Text> text = appendTextNode("Hello, World!"); |
| 145 document().view()->updateAllLifecyclePhases(); |
| 146 |
| 147 document().body()->setContentEditable("true", ASSERT_NO_EXCEPTION); |
| 148 document().body()->focus(); |
| 149 EXPECT_TRUE(document().body()->focused()); |
| 150 |
| 151 selection().setCaretVisible(true); |
| 152 EXPECT_TRUE(selection().isCaret()); |
| 153 EXPECT_TRUE(shouldPaintCaretForTesting()); |
| 154 |
| 155 // Simulate to type "Hello, World!". |
| 156 DisableCompositingQueryAsserts disabler; |
| 157 selection().moveTo(createVisiblePosition(selection().end(), selection().affi
nity()), NotUserTriggered); |
| 158 selection().setCaretRectNeedsUpdate(); |
| 159 EXPECT_TRUE(selection().isCaretBoundsDirty()); |
| 160 EXPECT_FALSE(isPreviousCaretDirtyForTesting()); |
| 161 selection().invalidateCaretRect(); |
| 162 EXPECT_FALSE(selection().isCaretBoundsDirty()); |
| 163 EXPECT_TRUE(isPreviousCaretDirtyForTesting()); |
| 164 |
| 165 // Simulate to remove all except for "H". |
| 166 text->replaceWholeText("H"); |
| 167 selection().moveTo(createVisiblePosition(selection().end(), selection().affi
nity()), NotUserTriggered); |
| 168 selection().setCaretRectNeedsUpdate(); |
| 169 EXPECT_TRUE(selection().isCaretBoundsDirty()); |
| 170 // "H" remains so early previousCaret invalidation isn't needed. |
| 171 EXPECT_TRUE(isPreviousCaretDirtyForTesting()); |
| 172 selection().invalidateCaretRect(); |
| 173 EXPECT_FALSE(selection().isCaretBoundsDirty()); |
| 174 EXPECT_TRUE(isPreviousCaretDirtyForTesting()); |
| 175 |
| 176 // Simulate to remove the last character. |
| 177 document().body()->removeChild(text); |
| 178 // This line is the objective of this test. |
| 179 // As removing the last character, early previousCaret invalidation is execu
ted. |
| 180 EXPECT_FALSE(isPreviousCaretDirtyForTesting()); |
| 181 document().updateLayoutIgnorePendingStylesheets(); |
| 182 selection().setCaretRectNeedsUpdate(); |
| 183 EXPECT_TRUE(selection().isCaretBoundsDirty()); |
| 184 EXPECT_FALSE(isPreviousCaretDirtyForTesting()); |
| 185 selection().invalidateCaretRect(); |
| 186 EXPECT_FALSE(selection().isCaretBoundsDirty()); |
| 187 EXPECT_TRUE(isPreviousCaretDirtyForTesting()); |
| 188 } |
| 189 |
138 #define EXPECT_EQ_SELECTED_TEXT(text) \ | 190 #define EXPECT_EQ_SELECTED_TEXT(text) \ |
139 EXPECT_EQ(text, WebString(selection().selectedText()).utf8()) | 191 EXPECT_EQ(text, WebString(selection().selectedText()).utf8()) |
140 | 192 |
141 TEST_F(FrameSelectionTest, SelectWordAroundPosition) | 193 TEST_F(FrameSelectionTest, SelectWordAroundPosition) |
142 { | 194 { |
143 // "Foo Bar Baz," | 195 // "Foo Bar Baz," |
144 RefPtrWillBeRawPtr<Text> text = appendTextNode("Foo Bar Baz,"); | 196 RefPtrWillBeRawPtr<Text> text = appendTextNode("Foo Bar Baz,"); |
145 // "Fo|o Bar Baz," | 197 // "Fo|o Bar Baz," |
146 EXPECT_TRUE(selection().selectWordAroundPosition(createVisiblePosition(Posit
ion(text, 2)))); | 198 EXPECT_TRUE(selection().selectWordAroundPosition(createVisiblePosition(Posit
ion(text, 2)))); |
147 EXPECT_EQ_SELECTED_TEXT("Foo"); | 199 EXPECT_EQ_SELECTED_TEXT("Foo"); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 | 285 |
234 TEST_F(FrameSelectionTest, SelectAllWithUnselectableRoot) | 286 TEST_F(FrameSelectionTest, SelectAllWithUnselectableRoot) |
235 { | 287 { |
236 RefPtrWillBeRawPtr<Element> select = document().createElement("select", ASSE
RT_NO_EXCEPTION); | 288 RefPtrWillBeRawPtr<Element> select = document().createElement("select", ASSE
RT_NO_EXCEPTION); |
237 document().replaceChild(select.get(), document().documentElement()); | 289 document().replaceChild(select.get(), document().documentElement()); |
238 selection().selectAll(); | 290 selection().selectAll(); |
239 EXPECT_TRUE(selection().isNone()) << "Nothing should be selected if the cont
ent of the documentElement is not selctable."; | 291 EXPECT_TRUE(selection().isNone()) << "Nothing should be selected if the cont
ent of the documentElement is not selctable."; |
240 } | 292 } |
241 | 293 |
242 } // namespace blink | 294 } // namespace blink |
OLD | NEW |