Partially revert 104427, change WebWidgetClient::didHandleGestureEvent semantics.
[WebKit-https.git] / Source / WebKit / chromium / tests / WebViewTest.cpp
1 /*
2  * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32 #include "WebView.h"
33
34 #include "Document.h"
35 #include "Element.h"
36 #include "FrameTestHelpers.h"
37 #include "FrameView.h"
38 #include "HTMLDocument.h"
39 #include "URLTestHelpers.h"
40 #include "WebContentDetectionResult.h"
41 #include "WebDocument.h"
42 #include "WebElement.h"
43 #include "WebFrame.h"
44 #include "WebFrameClient.h"
45 #include "WebFrameImpl.h"
46 #include "WebInputEvent.h"
47 #include "WebViewClient.h"
48 #include "WebViewImpl.h"
49 #include <gtest/gtest.h>
50 #include <public/WebSize.h>
51 #include <webkit/support/webkit_support.h>
52
53 using namespace WebKit;
54 using WebKit::URLTestHelpers::toKURL;
55
56 namespace {
57
58 enum HorizontalScrollbarState {
59     NoHorizontalScrollbar,
60     VisibleHorizontalScrollbar,
61 };
62
63 enum VerticalScrollbarState {
64     NoVerticalScrollbar,
65     VisibleVerticalScrollbar,
66 };
67
68 class TestData {
69 public:
70     void setWebView(WebView* webView) { m_webView = static_cast<WebViewImpl*>(webView); }
71     void setSize(const WebSize& newSize) { m_size = newSize; }
72     HorizontalScrollbarState horizontalScrollbarState() const
73     {
74         return m_webView->hasHorizontalScrollbar() ? VisibleHorizontalScrollbar: NoHorizontalScrollbar;
75     }
76     VerticalScrollbarState verticalScrollbarState() const
77     {
78         return m_webView->hasVerticalScrollbar() ? VisibleVerticalScrollbar : NoVerticalScrollbar;
79     }
80     int width() const { return m_size.width; }
81     int height() const { return m_size.height; }
82
83 private:
84     WebSize m_size;
85     WebViewImpl* m_webView;
86 };
87
88 class AutoResizeWebViewClient : public WebViewClient {
89 public:
90     // WebViewClient methods
91     virtual void didAutoResize(const WebSize& newSize) { m_testData.setSize(newSize); }
92
93     // Local methods
94     TestData& testData() { return m_testData; }
95
96 private:
97     TestData m_testData;
98 };
99
100 class FormChangeWebViewClient : public WebViewClient {
101 public:
102     // WebViewClient methods
103     virtual void didChangeFormState(const WebNode& node)
104     {
105         m_focused = node.focused();
106         m_called = true;
107     }
108
109     // Local methods
110     void reset()
111     {
112         m_called = false;
113         m_focused = false;
114     }
115     bool called() { return m_called; }
116     bool focused() { return m_focused; }
117
118 private:
119     bool m_called;
120     bool m_focused;
121 };
122
123 class TapHandlingWebViewClient : public WebViewClient {
124 public:
125     // WebViewClient methods
126     virtual void didHandleGestureEvent(const WebGestureEvent& event, bool eventCancelled)
127     {
128         if (event.type == WebInputEvent::GestureTap) {
129             m_tapX = event.x;
130             m_tapY = event.y;
131         } else if (event.type == WebInputEvent::GestureLongPress) {
132             m_longpressX = event.x;
133             m_longpressY = event.y;
134         }
135     }
136
137     // Local methods
138     void reset()
139     {
140         m_tapX = -1;
141         m_tapY = -1;
142         m_longpressX = -1;
143         m_longpressY = -1;
144     }
145     int tapX() { return m_tapX; }
146     int tapY() { return m_tapY; }
147     int longpressX() { return m_longpressX; }
148     int longpressY() { return m_longpressY; }
149
150 private:
151     int m_tapX;
152     int m_tapY;
153     int m_longpressX;
154     int m_longpressY;
155 };
156
157 class WebViewTest : public testing::Test {
158 public:
159     WebViewTest()
160         : m_baseURL("http://www.test.com/")
161     {
162     }
163
164     virtual void TearDown()
165     {
166         webkit_support::UnregisterAllMockedURLs();
167     }
168
169 protected:
170     void testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize,
171                         const std::string& pageWidth, const std::string& pageHeight,
172                         int expectedWidth, int expectedHeight,
173                         HorizontalScrollbarState expectedHorizontalState, VerticalScrollbarState expectedVerticalState);
174
175     void testTextInputType(WebTextInputType expectedType, const std::string& htmlFile);
176
177     std::string m_baseURL;
178 };
179
180 TEST_F(WebViewTest, FocusIsInactive)
181 {
182     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "visible_iframe.html");
183     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "visible_iframe.html");
184
185     webView->setFocus(true);
186     webView->setIsActive(true);
187     WebFrameImpl* frame = static_cast<WebFrameImpl*>(webView->mainFrame());
188     EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
189
190     WebCore::HTMLDocument* document = static_cast<WebCore::HTMLDocument*>(frame->frame()->document());
191     EXPECT_TRUE(document->hasFocus());
192     webView->setFocus(false);
193     webView->setIsActive(false);
194     EXPECT_FALSE(document->hasFocus());
195     webView->setFocus(true);
196     webView->setIsActive(true);
197     EXPECT_TRUE(document->hasFocus());
198     webView->setFocus(true);
199     webView->setIsActive(false);
200     EXPECT_FALSE(document->hasFocus());
201     webView->setFocus(false);
202     webView->setIsActive(true);
203     EXPECT_TRUE(document->hasFocus());
204
205     webView->close();
206 }
207
208 TEST_F(WebViewTest, ActiveState)
209 {
210     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "visible_iframe.html");
211     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "visible_iframe.html");
212
213     ASSERT_TRUE(webView);
214
215     webView->setIsActive(true);
216     EXPECT_TRUE(webView->isActive());
217
218     webView->setIsActive(false);
219     EXPECT_FALSE(webView->isActive());
220
221     webView->setIsActive(true);
222     EXPECT_TRUE(webView->isActive());
223
224     webView->close();
225 }
226
227 void WebViewTest::testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize,
228                                  const std::string& pageWidth, const std::string& pageHeight,
229                                  int expectedWidth, int expectedHeight,
230                                  HorizontalScrollbarState expectedHorizontalState, VerticalScrollbarState expectedVerticalState)
231 {
232     AutoResizeWebViewClient client;
233     std::string url = m_baseURL + "specify_size.html?" + pageWidth + ":" + pageHeight;
234     URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html");
235     WebView* webView = FrameTestHelpers::createWebViewAndLoad(url, true, 0, &client);
236     client.testData().setWebView(webView);
237
238     WebFrameImpl* frame = static_cast<WebFrameImpl*>(webView->mainFrame());
239     WebCore::FrameView* frameView = frame->frame()->view();
240     frameView->layout();
241     EXPECT_FALSE(frameView->layoutPending());
242     EXPECT_FALSE(frameView->needsLayout());
243
244     webView->enableAutoResizeMode(minAutoResize, maxAutoResize);
245     EXPECT_TRUE(frameView->layoutPending());
246     EXPECT_TRUE(frameView->needsLayout());
247     frameView->layout();
248
249     EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
250
251     EXPECT_EQ(expectedWidth, client.testData().width());
252     EXPECT_EQ(expectedHeight, client.testData().height());
253     EXPECT_EQ(expectedHorizontalState, client.testData().horizontalScrollbarState());
254     EXPECT_EQ(expectedVerticalState, client.testData().verticalScrollbarState());
255
256     webView->close();
257 }
258
259 TEST_F(WebViewTest, DISABLED_AutoResizeMinimumSize)
260 {
261     WebSize minAutoResize(91, 56);
262     WebSize maxAutoResize(403, 302);
263     std::string pageWidth = "91px";
264     std::string pageHeight = "56px";
265     int expectedWidth = 91;
266     int expectedHeight = 56;
267     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
268                    expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
269 }
270
271 TEST_F(WebViewTest, AutoResizeHeightOverflowAndFixedWidth)
272 {
273     WebSize minAutoResize(90, 95);
274     WebSize maxAutoResize(90, 100);
275     std::string pageWidth = "60px";
276     std::string pageHeight = "200px";
277     int expectedWidth = 90;
278     int expectedHeight = 100;
279     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
280                    expectedWidth, expectedHeight, NoHorizontalScrollbar, VisibleVerticalScrollbar);
281 }
282
283 TEST_F(WebViewTest, AutoResizeFixedHeightAndWidthOverflow)
284 {
285     WebSize minAutoResize(90, 100);
286     WebSize maxAutoResize(200, 100);
287     std::string pageWidth = "300px";
288     std::string pageHeight = "80px";
289     int expectedWidth = 200;
290     int expectedHeight = 100;
291     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
292                    expectedWidth, expectedHeight, VisibleHorizontalScrollbar, NoVerticalScrollbar);
293 }
294
295 // Next three tests disabled for https://bugs.webkit.org/show_bug.cgi?id=92318 .
296 // It seems we can run three AutoResize tests, then the next one breaks.
297 TEST_F(WebViewTest, DISABLED_AutoResizeInBetweenSizes)
298 {
299     WebSize minAutoResize(90, 95);
300     WebSize maxAutoResize(200, 300);
301     std::string pageWidth = "100px";
302     std::string pageHeight = "200px";
303     int expectedWidth = 100;
304     int expectedHeight = 200;
305     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
306                    expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
307 }
308
309 TEST_F(WebViewTest, DISABLED_AutoResizeOverflowSizes)
310 {
311     WebSize minAutoResize(90, 95);
312     WebSize maxAutoResize(200, 300);
313     std::string pageWidth = "300px";
314     std::string pageHeight = "400px";
315     int expectedWidth = 200;
316     int expectedHeight = 300;
317     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
318                    expectedWidth, expectedHeight, VisibleHorizontalScrollbar, VisibleVerticalScrollbar);
319 }
320
321 TEST_F(WebViewTest, DISABLED_AutoResizeMaxSize)
322 {
323     WebSize minAutoResize(90, 95);
324     WebSize maxAutoResize(200, 300);
325     std::string pageWidth = "200px";
326     std::string pageHeight = "300px";
327     int expectedWidth = 200;
328     int expectedHeight = 300;
329     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
330                    expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
331 }
332
333 void WebViewTest::testTextInputType(WebTextInputType expectedType, const std::string& htmlFile)
334 {
335     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(htmlFile.c_str()));
336     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + htmlFile);
337     webView->setInitialFocus(false);
338     EXPECT_EQ(expectedType, webView->textInputType());
339     webView->close();
340 }
341
342 // Disabled for https://bugs.webkit.org/show_bug.cgi?id=78746#c29
343 TEST_F(WebViewTest, DISABLED_TextInputType)
344 {
345     testTextInputType(WebTextInputTypeText, "input_field_default.html");
346     testTextInputType(WebTextInputTypePassword, "input_field_password.html");
347     testTextInputType(WebTextInputTypeEmail, "input_field_email.html");
348     testTextInputType(WebTextInputTypeSearch, "input_field_search.html");
349     testTextInputType(WebTextInputTypeNumber, "input_field_number.html");
350     testTextInputType(WebTextInputTypeTelephone, "input_field_tel.html");
351     testTextInputType(WebTextInputTypeURL, "input_field_url.html");
352 #if ENABLE(INPUT_TYPE_DATE)
353     testTextInputType(WebTextInputTypeDate, "input_field_date.html");
354 #endif
355 #if ENABLE(INPUT_TYPE_DATETIME)
356     testTextInputType(WebTextInputTypeDateTime, "input_field_datetime.html");
357 #endif
358 #if ENABLE(INPUT_TYPE_DATETIMELOCAL)
359     testTextInputType(WebTextInputTypeDateTimeLocal, "input_field_datetimelocal.html");
360 #endif
361 #if ENABLE(INPUT_TYPE_MONTH)
362     testTextInputType(WebTextInputTypeMonth, "input_field_month.html");
363 #endif
364 #if ENABLE(INPUT_TYPE_TIME)
365     testTextInputType(WebTextInputTypeTime, "input_field_time.html");
366 #endif
367 #if ENABLE(INPUT_TYPE_WEEK)
368     testTextInputType(WebTextInputTypeWeek, "input_field_week.html");
369 #endif
370
371 }
372
373 TEST_F(WebViewTest, SetEditableSelectionOffsetsAndTextInputInfo)
374 {
375     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
376     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_populated.html");
377     webView->setInitialFocus(false);
378     webView->setEditableSelectionOffsets(5, 13);
379     WebFrameImpl* frame = static_cast<WebFrameImpl*>(webView->mainFrame());
380     EXPECT_EQ("56789abc", frame->selectionAsText());
381     WebTextInputInfo info = webView->textInputInfo();
382     EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value);
383     EXPECT_EQ(5, info.selectionStart);
384     EXPECT_EQ(13, info.selectionEnd);
385     EXPECT_EQ(-1, info.compositionStart);
386     EXPECT_EQ(-1, info.compositionEnd);
387     webView->close();
388
389     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_editable_populated.html"));
390     webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "content_editable_populated.html");
391     webView->setInitialFocus(false);
392     webView->setEditableSelectionOffsets(8, 19);
393     frame = static_cast<WebFrameImpl*>(webView->mainFrame());
394     EXPECT_EQ("89abcdefghi", frame->selectionAsText());
395     info = webView->textInputInfo();
396     EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value);
397     EXPECT_EQ(8, info.selectionStart);
398     EXPECT_EQ(19, info.selectionEnd);
399     EXPECT_EQ(-1, info.compositionStart);
400     EXPECT_EQ(-1, info.compositionEnd);
401     webView->close();
402 }
403
404 TEST_F(WebViewTest, FormChange)
405 {
406     FormChangeWebViewClient client;
407     client.reset();
408     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_set_value_while_focused.html"));
409     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_set_value_while_focused.html", true, 0, &client);
410     EXPECT_TRUE(client.called());
411     EXPECT_TRUE(client.focused());
412     client.reset();
413     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_set_value_while_not_focused.html"));
414     webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_set_value_while_not_focused.html", true, 0, &client);
415     EXPECT_TRUE(client.called());
416     EXPECT_FALSE(client.focused());
417     webView->close();
418 }
419
420 TEST_F(WebViewTest, ExtendSelectionAndDelete)
421 {
422     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
423     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_populated.html");
424     webView->setInitialFocus(false);
425     webView->setEditableSelectionOffsets(10, 10);
426     webView->extendSelectionAndDelete(5, 8);
427     WebTextInputInfo info = webView->textInputInfo();
428     EXPECT_EQ("01234ijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
429     EXPECT_EQ(5, info.selectionStart);
430     EXPECT_EQ(5, info.selectionEnd);
431     webView->extendSelectionAndDelete(10, 0);
432     info = webView->textInputInfo();
433     EXPECT_EQ("ijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
434     webView->close();
435 }
436
437 TEST_F(WebViewTest, SetCompositionFromExistingText)
438 {
439     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
440     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_populated.html");
441     webView->setInitialFocus(false);
442     WebVector<WebCompositionUnderline> emptyUnderlines;
443     webView->setEditableSelectionOffsets(4, 10);
444     webView->setCompositionFromExistingText(8, 12, emptyUnderlines);
445     WebTextInputInfo info = webView->textInputInfo();
446     EXPECT_EQ(4, info.selectionStart);
447     EXPECT_EQ(10, info.selectionEnd);
448     EXPECT_EQ(8, info.compositionStart);
449     EXPECT_EQ(12, info.compositionEnd);
450     webView->setCompositionFromExistingText(0, 0, emptyUnderlines);
451     info = webView->textInputInfo();
452     EXPECT_EQ(4, info.selectionStart);
453     EXPECT_EQ(10, info.selectionEnd);
454     EXPECT_EQ(-1, info.compositionStart);
455     EXPECT_EQ(-1, info.compositionEnd);
456     webView->close();
457 }
458
459 TEST_F(WebViewTest, ResetScrollAndScaleState)
460 {
461     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("hello_world.html"));
462     WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(FrameTestHelpers::createWebViewAndLoad(m_baseURL + "hello_world.html"));
463     webViewImpl->resize(WebSize(640, 480));
464     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
465     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
466
467     // Make the page scale and scroll with the given paremeters.
468     webViewImpl->setPageScaleFactor(2.0f, WebPoint(116, 84));
469     EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
470     EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
471     EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
472     webViewImpl->page()->mainFrame()->loader()->history()->saveDocumentAndScrollState();
473
474     // Confirm that restoring the page state restores the parameters.
475     webViewImpl->setPageScaleFactor(1.5f, WebPoint(16, 24));
476     EXPECT_EQ(1.5f, webViewImpl->pageScaleFactor());
477     EXPECT_EQ(16, webViewImpl->mainFrame()->scrollOffset().width);
478     EXPECT_EQ(24, webViewImpl->mainFrame()->scrollOffset().height);
479     webViewImpl->page()->mainFrame()->loader()->history()->restoreScrollPositionAndViewState();
480     EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
481     EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
482     EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
483     webViewImpl->page()->mainFrame()->loader()->history()->saveDocumentAndScrollState();
484
485     // Confirm that resetting the page state resets the saved scroll position.
486     // The HistoryController treats a page scale factor of 0.0f as special and avoids
487     // restoring it to the WebView.
488     webViewImpl->resetScrollAndScaleState();
489     EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
490     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
491     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
492     webViewImpl->page()->mainFrame()->loader()->history()->restoreScrollPositionAndViewState();
493     EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
494     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
495     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
496     webViewImpl->close();
497 }
498
499 class ContentDetectorClient : public WebViewClient {
500 public:
501     ContentDetectorClient() { reset(); }
502
503     virtual WebContentDetectionResult detectContentAround(const WebHitTestResult& hitTest) OVERRIDE
504     {
505         m_contentDetectionRequested = true;
506         return m_contentDetectionResult;
507     }
508
509     virtual void scheduleContentIntent(const WebURL& url) OVERRIDE
510     {
511         m_scheduledIntentURL = url;
512     }
513
514     virtual void cancelScheduledContentIntents() OVERRIDE
515     {
516         m_pendingIntentsCancelled = true;
517     }
518
519     void reset()
520     {
521         m_contentDetectionRequested = false;
522         m_pendingIntentsCancelled = false;
523         m_scheduledIntentURL = WebURL();
524         m_contentDetectionResult = WebContentDetectionResult();
525     }
526
527     bool contentDetectionRequested() const { return m_contentDetectionRequested; }
528     bool pendingIntentsCancelled() const { return m_pendingIntentsCancelled; }
529     const WebURL& scheduledIntentURL() const { return m_scheduledIntentURL; }
530     void setContentDetectionResult(const WebContentDetectionResult& result) { m_contentDetectionResult = result; }
531
532 private:
533     bool m_contentDetectionRequested;
534     bool m_pendingIntentsCancelled;
535     WebURL m_scheduledIntentURL;
536     WebContentDetectionResult m_contentDetectionResult;
537 };
538
539 static bool tapElementById(WebView* webView, WebInputEvent::Type type, const WebString& id)
540 {
541     ASSERT(webView);
542     RefPtr<WebCore::Element> element = static_cast<PassRefPtr<WebCore::Element> >(webView->mainFrame()->document().getElementById(id));
543     if (!element)
544         return false;
545
546     element->scrollIntoViewIfNeeded();
547     WebCore::IntPoint center = element->screenRect().center();
548
549     WebGestureEvent event;
550     event.type = type;
551     event.x = center.x();
552     event.y = center.y();
553
554     webView->handleInputEvent(event);
555     webkit_support::RunAllPendingMessages();
556     return true;
557 }
558
559 TEST_F(WebViewTest, DetectContentAroundPosition)
560 {
561     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_listeners.html"));
562
563     ContentDetectorClient client;
564     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "content_listeners.html", true, 0, &client);
565     webView->resize(WebSize(500, 300));
566     webView->layout();
567     webkit_support::RunAllPendingMessages();
568
569     WebString clickListener = WebString::fromUTF8("clickListener");
570     WebString touchstartListener = WebString::fromUTF8("touchstartListener");
571     WebString mousedownListener = WebString::fromUTF8("mousedownListener");
572     WebString noListener = WebString::fromUTF8("noListener");
573     WebString link = WebString::fromUTF8("link");
574
575     // Ensure content detection is not requested for nodes listening to click,
576     // mouse or touch events when we do simple taps.
577     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, clickListener));
578     EXPECT_FALSE(client.contentDetectionRequested());
579     client.reset();
580
581     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, touchstartListener));
582     EXPECT_FALSE(client.contentDetectionRequested());
583     client.reset();
584
585     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, mousedownListener));
586     EXPECT_FALSE(client.contentDetectionRequested());
587     client.reset();
588
589     // Content detection should work normally without these event listeners.
590     // The click listener in the body should be ignored as a special case.
591     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, noListener));
592     EXPECT_TRUE(client.contentDetectionRequested());
593     EXPECT_FALSE(client.scheduledIntentURL().isValid());
594
595     WebURL intentURL = toKURL(m_baseURL);
596     client.setContentDetectionResult(WebContentDetectionResult(WebRange(), WebString(), intentURL));
597     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, noListener));
598     EXPECT_TRUE(client.scheduledIntentURL() == intentURL);
599
600     // Tapping elsewhere should cancel the scheduled intent.
601     WebGestureEvent event;
602     event.type = WebInputEvent::GestureTap;
603     webView->handleInputEvent(event);
604     webkit_support::RunAllPendingMessages();
605     EXPECT_TRUE(client.pendingIntentsCancelled());
606     webView->close();
607 }
608
609 TEST_F(WebViewTest, ClientTapHandling)
610 {
611     TapHandlingWebViewClient client;
612     client.reset();
613     WebView* webView = FrameTestHelpers::createWebViewAndLoad("about:blank", true, 0, &client);
614     WebGestureEvent event;
615     event.type = WebInputEvent::GestureTap;
616     event.x = 3;
617     event.y = 8;
618     webView->handleInputEvent(event);
619     webkit_support::RunAllPendingMessages();
620     EXPECT_EQ(3, client.tapX());
621     EXPECT_EQ(8, client.tapY());
622     client.reset();
623     event.type = WebInputEvent::GestureLongPress;
624     event.x = 25;
625     event.y = 7;
626     webView->handleInputEvent(event);
627     webkit_support::RunAllPendingMessages();
628     EXPECT_EQ(25, client.longpressX());
629     EXPECT_EQ(7, client.longpressY());
630     webView->close();
631 }
632
633 #if OS(ANDROID)
634 TEST_F(WebViewTest, LongPressSelection)
635 {
636     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html"));
637
638     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "longpress_selection.html", true);
639     webView->resize(WebSize(500, 300));
640     webView->layout();
641     webkit_support::RunAllPendingMessages();
642
643     WebString target = WebString::fromUTF8("target");
644     WebString onselectstartfalse = WebString::fromUTF8("onselectstartfalse");
645     WebFrameImpl* frame = static_cast<WebFrameImpl*>(webView->mainFrame());
646
647     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, onselectstartfalse));
648     EXPECT_EQ("", std::string(frame->selectionAsText().utf8().data()));
649     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, target));
650     EXPECT_EQ("testword", std::string(frame->selectionAsText().utf8().data()));
651     webView->close();
652 }
653 #endif
654
655 }