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

Side by Side Diff: third_party/WebKit/Source/web/tests/LinkSelectionTest.cpp

Issue 1774123006: Implement link selection on alt+mouse drag. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove static and rename function. Created 4 years, 9 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 unified diff | Download patch
OLDNEW
(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>
tkent 2016/03/25 03:33:03 Please include it with "", not <>. Please specify
20 #include <gtest/gtest.h>
21
22 using ::testing::_;
23
24 namespace blink {
25
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 const char* const 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);
tkent 2016/03/25 03:33:02 Blink's ASSERT() is deprecated. Use glog's DCHECK
51 auto* linkToSelect = document->getElementById("link")->firstChild();
52 ASSERT(linkToSelect);
tkent 2016/03/25 03:33:02 ASSERT() is deprecated.
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, SendDownEvent);
87 m_mainFrame->frame()->localFrameRoot()->eventHandler().scheduleCursorUpdate( );
88 testing::runDelayedTasks(50);
89 const auto& cursor = m_mainFrame->frame()->chromeClient().lastSetCursorForTe sting();
90 EXPECT_EQ(Cursor::Hand, cursor.getType());
91 }
92
93 TEST_F(LinkSelectionTest, CaretCursorOverLinkDuringSelection)
94 {
95 emulateMouseDrag(m_rightPointInLink, m_leftPointInLink, WebInputEvent::AltKe y, SendDownEvent);
96 m_mainFrame->frame()->localFrameRoot()->eventHandler().scheduleCursorUpdate( );
97 testing::runDelayedTasks(50);
98 const auto& cursor = m_mainFrame->frame()->chromeClient().lastSetCursorForTe sting();
99 EXPECT_EQ(Cursor::IBeam, cursor.getType());
100 }
101
102 TEST_F(LinkSelectionTest, HandCursorOverLinkAfterContextMenu)
103 {
104 // Move mouse.
105 emulateMouseDrag(m_rightPointInLink, m_leftPointInLink, 0, 0);
106
107 // Show context menu. We don't send mouseup event here since in browser it d oesn't reach
108 // blink because of shown context menu.
109 emulateMouseDown(m_leftPointInLink, WebMouseEvent::ButtonRight, 0, 1);
110
111 LocalFrame* frame = m_mainFrame->frame();
112 // Hide context menu.
113 frame->page()->contextMenuController().clearContextMenu();
114
115 frame->localFrameRoot()->eventHandler().scheduleCursorUpdate();
116 testing::runDelayedTasks(50);
117 const auto& cursor = m_mainFrame->frame()->chromeClient().lastSetCursorForTe sting();
118 EXPECT_EQ(Cursor::Hand, cursor.getType());
119 }
120
121 TEST_F(LinkSelectionTest, SingleClickWithAltStartsDownload)
122 {
123 EXPECT_CALL(m_testFrameClient, loadURLExternally(_, WebNavigationPolicy::Web NavigationPolicyDownload, WebString(), _));
124 emulateMouseClick(m_leftPointInLink, WebMouseEvent::ButtonLeft, WebInputEven t::AltKey);
125 }
126
127 TEST_F(LinkSelectionTest, SingleClickWithAltStartsDownloadWhenTextSelected)
128 {
129 auto* document = m_mainFrame->frame()->document();
130 auto* textToSelect = document->getElementById("page_text")->firstChild();
131 ASSERT(textToSelect);
tkent 2016/03/25 03:33:03 ASSERT() is deprecated.
132
133 // Select some page text outside the link element.
134 const RefPtrWillBeRawPtr<Range> rangeToSelect = Range::create(*document, tex tToSelect, 1, textToSelect, 20);
135 const auto& selectionRect = rangeToSelect->boundingBox();
136 m_mainFrame->moveRangeSelection(selectionRect.minXMinYCorner(), selectionRec t.maxXMaxYCorner());
137 EXPECT_FALSE(getSelectionText().empty());
138
139 EXPECT_CALL(m_testFrameClient, loadURLExternally(_, WebNavigationPolicy::Web NavigationPolicyDownload, WebString(), _));
140 emulateMouseClick(m_leftPointInLink, WebMouseEvent::ButtonLeft, WebInputEven t::AltKey);
141 }
142
143 class LinkSelectionClickEvents : public SelectionTestBase {
tkent 2016/03/25 03:33:03 Please use "Test" suffix for test fixture class na
144 protected:
145 class MockEventListener final : public EventListener {
146 public:
147 static PassRefPtrWillBeRawPtr<MockEventListener> create()
148 {
149 return adoptRefWillBeNoop(new MockEventListener());
150 }
151
152 bool operator==(const EventListener& other) const final
153 {
154 return this == &other;
155 }
156
157 MOCK_METHOD2(handleEvent, void(ExecutionContext* executionContext, Event *));
158
159 private:
160 MockEventListener() : EventListener(CPPEventListenerType)
161 {
162 }
163 };
164
165 void SetUp() override
166 {
167 const char* const kHTMLString =
168 "<div id='empty_div' style='width: 100px; height: 100px;'></div>"
169 "<span id='text_div'>Sometexttoshow</span>";
170
171 m_webView = m_helper.initialize(false);
172 m_mainFrame = m_webView->mainFrameImpl();
173 FrameTestHelpers::loadHTMLString(m_mainFrame, kHTMLString, URLTestHelper s::toKURL("http://foobar.com"));
174 m_webView->resize(WebSize(800, 600));
175 m_webView->page()->focusController().setActive(true);
176
177 auto* document = m_mainFrame->frame()->document();
178 ASSERT(document);
tkent 2016/03/25 03:33:03 ASSERT() is deprecated.
179
180 auto* emptyDiv = document->getElementById("empty_div");
181 auto* textDiv = document->getElementById("text_div");
182 ASSERT_TRUE(emptyDiv);
tkent 2016/03/25 03:33:03 ASSERT_NE(nullptr, emptyDiv), or DCHECK_NE(emptyDi
183 ASSERT_TRUE(textDiv);
tkent 2016/03/25 03:33:03 Ditto.
184 }
185
186 void checkMouseClicks(Element& element, bool doubleClickEvent)
187 {
188 struct ScopedListenersCleaner {
189 ScopedListenersCleaner(Element* element) : m_element(element) {}
190
191 ~ScopedListenersCleaner()
192 {
193 m_element->removeAllEventListeners();
194 }
195
196 RawPtrWillBePersistent<Element> m_element;
197 } const listenersCleaner(&element);
198
199 RefPtrWillBeRawPtr<MockEventListener> eventHandler = MockEventListener:: create();
200 element.addEventListener(
201 doubleClickEvent ? EventTypeNames::dblclick : EventTypeNames::click,
202 eventHandler);
203
204 ::testing::InSequence s;
205 EXPECT_CALL(*eventHandler, handleEvent(_, _)).Times(1);
206
207 const auto& elemBounds = element.boundsInViewport();
208 const int clickCount = doubleClickEvent ? 2 : 1;
209 emulateMouseClick(elemBounds.center(), WebMouseEvent::ButtonLeft, 0, cli ckCount);
210
211 if (doubleClickEvent) {
212 EXPECT_EQ(element.innerText().isEmpty(), getSelectionText().empty()) ;
213 }
214 }
215 };
216
217 TEST_F(LinkSelectionClickEvents, SingleAndDoubleClickWillBeHandled)
218 {
219 auto* document = m_mainFrame->frame()->document();
220 auto* element = document->getElementById("empty_div");
221
222 {
223 SCOPED_TRACE("Empty div, single click");
224 checkMouseClicks(*element, false);
225 }
226
227 {
228 SCOPED_TRACE("Empty div, double click");
229 checkMouseClicks(*element, true);
230 }
231
232 element = document->getElementById("text_div");
233
234 {
235 SCOPED_TRACE("Text div, single click");
236 checkMouseClicks(*element, false);
237 }
238
239 {
240 SCOPED_TRACE("Text div, double click");
241 checkMouseClicks(*element, true);
242 }
243 }
244
245 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698