OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2016 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 "core/dom/Range.h" | |
6 #include "core/frame/FrameView.h" | |
7 #include "core/input/EventHandler.h" | |
8 #include "core/page/ChromeClient.h" | |
9 #include "core/page/ContextMenuController.h" | |
10 #include "core/page/FocusController.h" | |
11 #include "core/page/Page.h" | |
12 #include "platform/Cursor.h" | |
13 #include "platform/testing/URLTestHelpers.h" | |
14 #include "platform/testing/UnitTestHelpers.h" | |
15 #include "public/web/WebSettings.h" | |
16 #include "web/WebLocalFrameImpl.h" | |
17 #include "web/tests/SelectionTestBase.h" | |
18 | |
19 #include <gmock/gmock.h> | |
20 #include <gtest/gtest.h> | |
21 | |
22 using ::testing::_; | |
23 | |
24 namespace blink { | |
25 namespace { | |
yosin_UTC9
2016/03/10 01:40:48
Note: We don't need to enclose test fixture class
| |
26 class TestFrameClient : public FrameTestHelpers::TestWebFrameClient { | |
27 public: | |
28 MOCK_METHOD4(loadURLExternally, | |
29 void(const WebURLRequest&, WebNavigationPolicy, const WebString& downloa dName, bool shouldReplaceCurrentEntry)); | |
30 }; | |
31 | |
32 class LinkSelectionTest : public SelectionTestBase { | |
33 protected: | |
34 void SetUp() override | |
35 { | |
36 static const char* kHTMLString = | |
37 "<a id='link' href='foo.com' style='font-size:20pt'>Text to select f oobar</a>" | |
38 "<div id='page_text'>Lorem ipsum dolor sit amet</div>"; | |
39 | |
40 // We need to set deviceSupportsMouse setting to true and page's focus c ontroller to active | |
41 // so that FrameView can set the mouse cursor. | |
42 m_webView = m_helper.initialize(false, &m_testFrameClient, nullptr, | |
43 [](WebSettings* settings) { settings->setDeviceSupportsMouse(true); }); | |
44 m_mainFrame = m_webView->mainFrameImpl(); | |
45 FrameTestHelpers::loadHTMLString(m_mainFrame, kHTMLString, URLTestHelper s::toKURL("http://foobar.com")); | |
46 m_webView->resize(WebSize(800, 600)); | |
47 m_webView->page()->focusController().setActive(true); | |
48 | |
49 auto* document = m_mainFrame->frame()->document(); | |
50 ASSERT(document); | |
51 auto* linkToSelect = document->getElementById("link")->firstChild(); | |
52 ASSERT(linkToSelect); | |
53 // We get larger range that we actually want to select, because we need a slightly larger | |
54 // rect to include the last character to the selection. | |
55 const auto rangeToSelect = Range::create(*document, linkToSelect, 5, lin kToSelect, 16); | |
56 | |
57 const auto& selectionRect = rangeToSelect->boundingBox(); | |
58 const auto& selectionRectCenterY = selectionRect.center().y(); | |
59 m_leftPointInLink = selectionRect.minXMinYCorner(); | |
60 m_leftPointInLink.setY(selectionRectCenterY); | |
61 | |
62 m_rightPointInLink = selectionRect.maxXMinYCorner(); | |
63 m_rightPointInLink.setY(selectionRectCenterY); | |
64 m_rightPointInLink.move(-2, 0); | |
65 } | |
66 | |
67 TestFrameClient m_testFrameClient; | |
68 IntPoint m_leftPointInLink; | |
69 IntPoint m_rightPointInLink; | |
70 }; | |
71 | |
72 TEST_F(LinkSelectionTest, MouseDragWithoutAltAllowNoLinkSelection) | |
73 { | |
74 emulateMouseDrag(m_leftPointInLink, m_rightPointInLink, 0); | |
75 EXPECT_EQ(std::string(), getSelectionText()); | |
76 } | |
77 | |
78 TEST_F(LinkSelectionTest, MouseDragWithAltAllowSelection) | |
79 { | |
80 emulateMouseDrag(m_leftPointInLink, m_rightPointInLink, WebInputEvent::AltKe y); | |
81 EXPECT_EQ("to select", getSelectionText()); | |
82 } | |
83 | |
84 TEST_F(LinkSelectionTest, HandCursorDuringLinkDrag) | |
85 { | |
86 emulateMouseDrag(m_rightPointInLink, m_leftPointInLink, 0, | |
87 true /* sendDownEvent */, false /* sendUpEvent */); | |
yosin_UTC9
2016/03/10 01:40:48
How about writing this as:
const bool sendDownEve
| |
88 m_mainFrame->frame()->localFrameRoot()->eventHandler().scheduleCursorUpdate( ); | |
89 testing::waitForDeferredTasks(0.05); | |
90 const auto& cursor = m_mainFrame->frame()->chromeClient().lastSetCursorForTe sting(); | |
91 EXPECT_EQ(Cursor::Hand, cursor.getType()); | |
92 } | |
93 | |
94 TEST_F(LinkSelectionTest, CaretCursorOverLinkDuringSelection) | |
95 { | |
96 emulateMouseDrag(m_rightPointInLink, m_leftPointInLink, WebInputEvent::AltKe y, | |
97 true /* sendDownEvent */, false /* sendUpEvent */); | |
98 m_mainFrame->frame()->localFrameRoot()->eventHandler().scheduleCursorUpdate( ); | |
99 testing::waitForDeferredTasks(0.05); | |
100 const auto& cursor = m_mainFrame->frame()->chromeClient().lastSetCursorForTe sting(); | |
101 EXPECT_EQ(Cursor::IBeam, cursor.getType()); | |
102 } | |
103 | |
104 TEST_F(LinkSelectionTest, HandCursorOverLinkAfterContextMenu) | |
105 { | |
106 // Move mouse. | |
107 emulateMouseDrag(m_rightPointInLink, m_leftPointInLink, 0, | |
108 false /* sendDownEvent */, false /* sendUpEvent */); | |
109 | |
110 // Show context menu. We don't send mouseup event here since in browser it d oesn't reach | |
111 // blink because of shown context menu. | |
112 emulateMouseDown(m_leftPointInLink, WebMouseEvent::ButtonRight, 0, 1); | |
113 | |
114 LocalFrame* frame = m_mainFrame->frame(); | |
115 // Hide context menu. | |
116 frame->page()->contextMenuController().clearContextMenu(); | |
117 | |
118 frame->localFrameRoot()->eventHandler().scheduleCursorUpdate(); | |
119 testing::waitForDeferredTasks(0.05); | |
120 const auto& cursor = m_mainFrame->frame()->chromeClient().lastSetCursorForTe sting(); | |
121 EXPECT_EQ(Cursor::Hand, cursor.getType()); | |
122 } | |
123 | |
124 TEST_F(LinkSelectionTest, SingleClickWithAltStartsDownload) | |
125 { | |
126 EXPECT_CALL(m_testFrameClient, loadURLExternally(_, WebNavigationPolicy::Web NavigationPolicyDownload, WebString(), _)); | |
127 emulateMouseClick(m_leftPointInLink, WebMouseEvent::ButtonLeft, WebInputEven t::AltKey); | |
128 } | |
129 | |
130 TEST_F(LinkSelectionTest, SingleClickWithAltStartsDownloadWhenTextSelected) | |
131 { | |
132 auto* document = m_mainFrame->frame()->document(); | |
133 auto* textToSelect = document->getElementById("page_text")->firstChild(); | |
134 ASSERT(textToSelect); | |
135 | |
136 // Select some page text outside the link element. | |
137 const RefPtrWillBeRawPtr<Range> rangeToSelect = Range::create(*document, tex tToSelect, 1, textToSelect, 20); | |
138 const auto& selectionRect = rangeToSelect->boundingBox(); | |
139 m_mainFrame->moveRangeSelection(selectionRect.minXMinYCorner(), selectionRec t.maxXMaxYCorner()); | |
140 EXPECT_FALSE(getSelectionText().empty()); | |
141 | |
142 EXPECT_CALL(m_testFrameClient, loadURLExternally(_, WebNavigationPolicy::Web NavigationPolicyDownload, WebString(), _)); | |
143 emulateMouseClick(m_leftPointInLink, WebMouseEvent::ButtonLeft, WebInputEven t::AltKey); | |
144 } | |
145 | |
146 class ClickEventsBugTest : public SelectionTestBase { | |
147 protected: | |
148 class MockEventListener final : public EventListener { | |
149 public: | |
150 static PassRefPtrWillBeRawPtr<MockEventListener> create() | |
151 { | |
152 return adoptRefWillBeNoop(new MockEventListener()); | |
153 } | |
154 | |
155 bool operator==(const EventListener& other) const final | |
156 { | |
157 return this == &other; | |
158 } | |
159 | |
160 MOCK_METHOD2(handleEvent, void(ExecutionContext* executionContext, Event *)); | |
161 | |
162 private: | |
163 MockEventListener() : EventListener(CPPEventListenerType) | |
164 { | |
165 } | |
166 }; | |
167 | |
168 void SetUp() override | |
169 { | |
170 static const char* kHTMLString = | |
171 "<div id='empty_div' style='width: 100px; height: 100px;'></div>" | |
172 "<span id='text_div'>Sometexttoshow</span>"; | |
173 | |
174 m_webView = m_helper.initialize(false); | |
175 m_mainFrame = m_webView->mainFrameImpl(); | |
176 FrameTestHelpers::loadHTMLString(m_mainFrame, kHTMLString, URLTestHelper s::toKURL("http://foobar.com")); | |
177 m_webView->resize(WebSize(800, 600)); | |
178 m_webView->page()->focusController().setActive(true); | |
179 | |
180 auto* document = m_mainFrame->frame()->document(); | |
181 ASSERT(document); | |
182 | |
183 auto* emptyDiv = document->getElementById("empty_div"); | |
184 auto* textDiv = document->getElementById("text_div"); | |
185 ASSERT_TRUE(emptyDiv); | |
186 ASSERT_TRUE(textDiv); | |
187 } | |
188 | |
189 void checkMouseClicks(Element& element, bool doubleClickEvent) | |
190 { | |
191 struct ScopedListenersCleaner { | |
192 ScopedListenersCleaner(Element* element) : m_element(element) {} | |
193 | |
194 ~ScopedListenersCleaner() | |
195 { | |
196 m_element->removeAllEventListeners(); | |
197 } | |
198 | |
199 RawPtrWillBePersistent<Element> m_element; | |
200 } const listenersCleaner(&element); | |
201 | |
202 RefPtrWillBeRawPtr<MockEventListener> eventHandler = MockEventListener:: create(); | |
203 element.addEventListener( | |
204 doubleClickEvent ? EventTypeNames::dblclick : EventTypeNames::click, | |
205 eventHandler); | |
206 | |
207 ::testing::InSequence s; | |
208 EXPECT_CALL(*eventHandler, handleEvent(_, _)).Times(1); | |
209 | |
210 const auto& elemBounds = element.boundsInViewport(); | |
211 const int clickCount = doubleClickEvent ? 2 : 1; | |
212 emulateMouseClick(elemBounds.center(), WebMouseEvent::ButtonLeft, 0, cli ckCount); | |
213 | |
214 if (doubleClickEvent) { | |
215 EXPECT_EQ(element.innerText().isEmpty(), getSelectionText().empty()) ; | |
216 } | |
217 } | |
218 }; | |
219 | |
220 TEST_F(ClickEventsBugTest, SingleAndDoubleClickWillBeHandled) | |
221 { | |
222 auto* document = m_mainFrame->frame()->document(); | |
223 auto* element = document->getElementById("empty_div"); | |
224 | |
225 { | |
226 SCOPED_TRACE("Empty div, single click"); | |
227 checkMouseClicks(*element, false); | |
228 } | |
229 | |
230 { | |
231 SCOPED_TRACE("Empty div, double click"); | |
232 checkMouseClicks(*element, true); | |
233 } | |
234 | |
235 element = document->getElementById("text_div"); | |
236 | |
237 { | |
238 SCOPED_TRACE("Text div, single click"); | |
239 checkMouseClicks(*element, false); | |
240 } | |
241 | |
242 { | |
243 SCOPED_TRACE("Text div, double click"); | |
244 checkMouseClicks(*element, true); | |
245 } | |
246 } | |
247 } // namespace | |
248 } // namespace blink | |
OLD | NEW |