24fecf557f438ad49371f3f2cfe6da5fbd64fff2
[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/Platform.h>
51 #include <public/WebSize.h>
52 #include <public/WebThread.h>
53 #include <public/WebUnitTestSupport.h>
54
55 using namespace WebKit;
56 using WebKit::FrameTestHelpers::runPendingTasks;
57 using WebKit::URLTestHelpers::toKURL;
58
59 namespace {
60
61 enum HorizontalScrollbarState {
62     NoHorizontalScrollbar,
63     VisibleHorizontalScrollbar,
64 };
65
66 enum VerticalScrollbarState {
67     NoVerticalScrollbar,
68     VisibleVerticalScrollbar,
69 };
70
71 class TestData {
72 public:
73     void setWebView(WebView* webView) { m_webView = static_cast<WebViewImpl*>(webView); }
74     void setSize(const WebSize& newSize) { m_size = newSize; }
75     HorizontalScrollbarState horizontalScrollbarState() const
76     {
77         return m_webView->hasHorizontalScrollbar() ? VisibleHorizontalScrollbar: NoHorizontalScrollbar;
78     }
79     VerticalScrollbarState verticalScrollbarState() const
80     {
81         return m_webView->hasVerticalScrollbar() ? VisibleVerticalScrollbar : NoVerticalScrollbar;
82     }
83     int width() const { return m_size.width; }
84     int height() const { return m_size.height; }
85
86 private:
87     WebSize m_size;
88     WebViewImpl* m_webView;
89 };
90
91 class AutoResizeWebViewClient : public WebViewClient {
92 public:
93     // WebViewClient methods
94     virtual void didAutoResize(const WebSize& newSize) { m_testData.setSize(newSize); }
95
96     // Local methods
97     TestData& testData() { return m_testData; }
98
99 private:
100     TestData m_testData;
101 };
102
103 class FormChangeWebViewClient : public WebViewClient {
104 public:
105     // WebViewClient methods
106     virtual void didChangeFormState(const WebNode& node)
107     {
108         m_focused = node.focused();
109         m_called = true;
110     }
111
112     // Local methods
113     void reset()
114     {
115         m_called = false;
116         m_focused = false;
117     }
118     bool called() { return m_called; }
119     bool focused() { return m_focused; }
120
121 private:
122     bool m_called;
123     bool m_focused;
124 };
125
126 class TapHandlingWebViewClient : public WebViewClient {
127 public:
128     // WebViewClient methods
129     virtual void didHandleGestureEvent(const WebGestureEvent& event, bool eventCancelled)
130     {
131         if (event.type == WebInputEvent::GestureTap) {
132             m_tapX = event.x;
133             m_tapY = event.y;
134         } else if (event.type == WebInputEvent::GestureLongPress) {
135             m_longpressX = event.x;
136             m_longpressY = event.y;
137         }
138     }
139
140     // Local methods
141     void reset()
142     {
143         m_tapX = -1;
144         m_tapY = -1;
145         m_longpressX = -1;
146         m_longpressY = -1;
147     }
148     int tapX() { return m_tapX; }
149     int tapY() { return m_tapY; }
150     int longpressX() { return m_longpressX; }
151     int longpressY() { return m_longpressY; }
152
153 private:
154     int m_tapX;
155     int m_tapY;
156     int m_longpressX;
157     int m_longpressY;
158 };
159
160 class WebViewTest : public testing::Test {
161 public:
162     WebViewTest()
163         : m_baseURL("http://www.test.com/")
164     {
165     }
166
167     virtual void TearDown()
168     {
169         Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
170     }
171
172 protected:
173     void testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize,
174                         const std::string& pageWidth, const std::string& pageHeight,
175                         int expectedWidth, int expectedHeight,
176                         HorizontalScrollbarState expectedHorizontalState, VerticalScrollbarState expectedVerticalState);
177
178     void testTextInputType(WebTextInputType expectedType, const std::string& htmlFile);
179
180     std::string m_baseURL;
181 };
182
183 TEST_F(WebViewTest, FocusIsInactive)
184 {
185     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "visible_iframe.html");
186     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "visible_iframe.html");
187
188     webView->setFocus(true);
189     webView->setIsActive(true);
190     WebFrameImpl* frame = static_cast<WebFrameImpl*>(webView->mainFrame());
191     EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
192
193     WebCore::HTMLDocument* document = static_cast<WebCore::HTMLDocument*>(frame->frame()->document());
194     EXPECT_TRUE(document->hasFocus());
195     webView->setFocus(false);
196     webView->setIsActive(false);
197     EXPECT_FALSE(document->hasFocus());
198     webView->setFocus(true);
199     webView->setIsActive(true);
200     EXPECT_TRUE(document->hasFocus());
201     webView->setFocus(true);
202     webView->setIsActive(false);
203     EXPECT_FALSE(document->hasFocus());
204     webView->setFocus(false);
205     webView->setIsActive(true);
206     EXPECT_TRUE(document->hasFocus());
207
208     webView->close();
209 }
210
211 TEST_F(WebViewTest, ActiveState)
212 {
213     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "visible_iframe.html");
214     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "visible_iframe.html");
215
216     ASSERT_TRUE(webView);
217
218     webView->setIsActive(true);
219     EXPECT_TRUE(webView->isActive());
220
221     webView->setIsActive(false);
222     EXPECT_FALSE(webView->isActive());
223
224     webView->setIsActive(true);
225     EXPECT_TRUE(webView->isActive());
226
227     webView->close();
228 }
229
230 void WebViewTest::testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize,
231                                  const std::string& pageWidth, const std::string& pageHeight,
232                                  int expectedWidth, int expectedHeight,
233                                  HorizontalScrollbarState expectedHorizontalState, VerticalScrollbarState expectedVerticalState)
234 {
235     AutoResizeWebViewClient client;
236     std::string url = m_baseURL + "specify_size.html?" + pageWidth + ":" + pageHeight;
237     URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html");
238     WebView* webView = FrameTestHelpers::createWebViewAndLoad(url, true, 0, &client);
239     client.testData().setWebView(webView);
240
241     WebFrameImpl* frame = static_cast<WebFrameImpl*>(webView->mainFrame());
242     WebCore::FrameView* frameView = frame->frame()->view();
243     frameView->layout();
244     EXPECT_FALSE(frameView->layoutPending());
245     EXPECT_FALSE(frameView->needsLayout());
246
247     webView->enableAutoResizeMode(minAutoResize, maxAutoResize);
248     EXPECT_TRUE(frameView->layoutPending());
249     EXPECT_TRUE(frameView->needsLayout());
250     frameView->layout();
251
252     EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
253
254     EXPECT_EQ(expectedWidth, client.testData().width());
255     EXPECT_EQ(expectedHeight, client.testData().height());
256     EXPECT_EQ(expectedHorizontalState, client.testData().horizontalScrollbarState());
257     EXPECT_EQ(expectedVerticalState, client.testData().verticalScrollbarState());
258
259     webView->close();
260 }
261
262 TEST_F(WebViewTest, DISABLED_AutoResizeMinimumSize)
263 {
264     WebSize minAutoResize(91, 56);
265     WebSize maxAutoResize(403, 302);
266     std::string pageWidth = "91px";
267     std::string pageHeight = "56px";
268     int expectedWidth = 91;
269     int expectedHeight = 56;
270     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
271                    expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
272 }
273
274 TEST_F(WebViewTest, AutoResizeHeightOverflowAndFixedWidth)
275 {
276     WebSize minAutoResize(90, 95);
277     WebSize maxAutoResize(90, 100);
278     std::string pageWidth = "60px";
279     std::string pageHeight = "200px";
280     int expectedWidth = 90;
281     int expectedHeight = 100;
282     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
283                    expectedWidth, expectedHeight, NoHorizontalScrollbar, VisibleVerticalScrollbar);
284 }
285
286 TEST_F(WebViewTest, AutoResizeFixedHeightAndWidthOverflow)
287 {
288     WebSize minAutoResize(90, 100);
289     WebSize maxAutoResize(200, 100);
290     std::string pageWidth = "300px";
291     std::string pageHeight = "80px";
292     int expectedWidth = 200;
293     int expectedHeight = 100;
294     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
295                    expectedWidth, expectedHeight, VisibleHorizontalScrollbar, NoVerticalScrollbar);
296 }
297
298 // Next three tests disabled for https://bugs.webkit.org/show_bug.cgi?id=92318 .
299 // It seems we can run three AutoResize tests, then the next one breaks.
300 TEST_F(WebViewTest, DISABLED_AutoResizeInBetweenSizes)
301 {
302     WebSize minAutoResize(90, 95);
303     WebSize maxAutoResize(200, 300);
304     std::string pageWidth = "100px";
305     std::string pageHeight = "200px";
306     int expectedWidth = 100;
307     int expectedHeight = 200;
308     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
309                    expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
310 }
311
312 TEST_F(WebViewTest, DISABLED_AutoResizeOverflowSizes)
313 {
314     WebSize minAutoResize(90, 95);
315     WebSize maxAutoResize(200, 300);
316     std::string pageWidth = "300px";
317     std::string pageHeight = "400px";
318     int expectedWidth = 200;
319     int expectedHeight = 300;
320     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
321                    expectedWidth, expectedHeight, VisibleHorizontalScrollbar, VisibleVerticalScrollbar);
322 }
323
324 TEST_F(WebViewTest, DISABLED_AutoResizeMaxSize)
325 {
326     WebSize minAutoResize(90, 95);
327     WebSize maxAutoResize(200, 300);
328     std::string pageWidth = "200px";
329     std::string pageHeight = "300px";
330     int expectedWidth = 200;
331     int expectedHeight = 300;
332     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
333                    expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
334 }
335
336 void WebViewTest::testTextInputType(WebTextInputType expectedType, const std::string& htmlFile)
337 {
338     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(htmlFile.c_str()));
339     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + htmlFile);
340     webView->setInitialFocus(false);
341     EXPECT_EQ(expectedType, webView->textInputType());
342     webView->close();
343 }
344
345 // Disabled for https://bugs.webkit.org/show_bug.cgi?id=78746#c29
346 TEST_F(WebViewTest, DISABLED_TextInputType)
347 {
348     testTextInputType(WebTextInputTypeText, "input_field_default.html");
349     testTextInputType(WebTextInputTypePassword, "input_field_password.html");
350     testTextInputType(WebTextInputTypeEmail, "input_field_email.html");
351     testTextInputType(WebTextInputTypeSearch, "input_field_search.html");
352     testTextInputType(WebTextInputTypeNumber, "input_field_number.html");
353     testTextInputType(WebTextInputTypeTelephone, "input_field_tel.html");
354     testTextInputType(WebTextInputTypeURL, "input_field_url.html");
355 #if ENABLE(INPUT_TYPE_DATE)
356     testTextInputType(WebTextInputTypeDate, "input_field_date.html");
357 #endif
358 #if ENABLE(INPUT_TYPE_DATETIME)
359     testTextInputType(WebTextInputTypeDateTime, "input_field_datetime.html");
360 #endif
361 #if ENABLE(INPUT_TYPE_DATETIMELOCAL)
362     testTextInputType(WebTextInputTypeDateTimeLocal, "input_field_datetimelocal.html");
363 #endif
364 #if ENABLE(INPUT_TYPE_MONTH)
365     testTextInputType(WebTextInputTypeMonth, "input_field_month.html");
366 #endif
367 #if ENABLE(INPUT_TYPE_TIME)
368     testTextInputType(WebTextInputTypeTime, "input_field_time.html");
369 #endif
370 #if ENABLE(INPUT_TYPE_WEEK)
371     testTextInputType(WebTextInputTypeWeek, "input_field_week.html");
372 #endif
373
374 }
375
376 TEST_F(WebViewTest, SetEditableSelectionOffsetsAndTextInputInfo)
377 {
378     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
379     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_populated.html");
380     webView->setInitialFocus(false);
381     webView->setEditableSelectionOffsets(5, 13);
382     WebFrameImpl* frame = static_cast<WebFrameImpl*>(webView->mainFrame());
383     EXPECT_EQ("56789abc", frame->selectionAsText());
384     WebTextInputInfo info = webView->textInputInfo();
385     EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value);
386     EXPECT_EQ(5, info.selectionStart);
387     EXPECT_EQ(13, info.selectionEnd);
388     EXPECT_EQ(-1, info.compositionStart);
389     EXPECT_EQ(-1, info.compositionEnd);
390     webView->close();
391
392     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_editable_populated.html"));
393     webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "content_editable_populated.html");
394     webView->setInitialFocus(false);
395     webView->setEditableSelectionOffsets(8, 19);
396     frame = static_cast<WebFrameImpl*>(webView->mainFrame());
397     EXPECT_EQ("89abcdefghi", frame->selectionAsText());
398     info = webView->textInputInfo();
399     EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value);
400     EXPECT_EQ(8, info.selectionStart);
401     EXPECT_EQ(19, info.selectionEnd);
402     EXPECT_EQ(-1, info.compositionStart);
403     EXPECT_EQ(-1, info.compositionEnd);
404     webView->close();
405 }
406
407 TEST_F(WebViewTest, FormChange)
408 {
409     FormChangeWebViewClient client;
410     client.reset();
411     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_set_value_while_focused.html"));
412     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_set_value_while_focused.html", true, 0, &client);
413     EXPECT_TRUE(client.called());
414     EXPECT_TRUE(client.focused());
415     client.reset();
416     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_set_value_while_not_focused.html"));
417     webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_set_value_while_not_focused.html", true, 0, &client);
418     EXPECT_TRUE(client.called());
419     EXPECT_FALSE(client.focused());
420     webView->close();
421 }
422
423 TEST_F(WebViewTest, ExtendSelectionAndDelete)
424 {
425     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
426     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_populated.html");
427     webView->setInitialFocus(false);
428     webView->setEditableSelectionOffsets(10, 10);
429     webView->extendSelectionAndDelete(5, 8);
430     WebTextInputInfo info = webView->textInputInfo();
431     EXPECT_EQ("01234ijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
432     EXPECT_EQ(5, info.selectionStart);
433     EXPECT_EQ(5, info.selectionEnd);
434     webView->extendSelectionAndDelete(10, 0);
435     info = webView->textInputInfo();
436     EXPECT_EQ("ijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
437     webView->close();
438 }
439
440 TEST_F(WebViewTest, SetCompositionFromExistingText)
441 {
442     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
443     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_populated.html");
444     webView->setInitialFocus(false);
445     WebVector<WebCompositionUnderline> emptyUnderlines;
446     webView->setEditableSelectionOffsets(4, 10);
447     webView->setCompositionFromExistingText(8, 12, emptyUnderlines);
448     WebTextInputInfo info = webView->textInputInfo();
449     EXPECT_EQ(4, info.selectionStart);
450     EXPECT_EQ(10, info.selectionEnd);
451     EXPECT_EQ(8, info.compositionStart);
452     EXPECT_EQ(12, info.compositionEnd);
453     webView->setCompositionFromExistingText(0, 0, emptyUnderlines);
454     info = webView->textInputInfo();
455     EXPECT_EQ(4, info.selectionStart);
456     EXPECT_EQ(10, info.selectionEnd);
457     EXPECT_EQ(-1, info.compositionStart);
458     EXPECT_EQ(-1, info.compositionEnd);
459     webView->close();
460 }
461
462 TEST_F(WebViewTest, IsSelectionAnchorFirst)
463 {
464     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
465     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_populated.html");
466     WebFrame* frame = webView->mainFrame();
467
468     webView->setInitialFocus(false);
469     webView->setEditableSelectionOffsets(4, 10);
470     EXPECT_TRUE(webView->isSelectionAnchorFirst());
471     WebRect anchor;
472     WebRect focus;
473     webView->selectionBounds(anchor, focus);
474     frame->selectRange(WebPoint(focus.x, focus.y), WebPoint(anchor.x, anchor.y));
475     EXPECT_FALSE(webView->isSelectionAnchorFirst());
476     webView->close();
477 }
478
479 TEST_F(WebViewTest, ResetScrollAndScaleState)
480 {
481     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("hello_world.html"));
482     WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(FrameTestHelpers::createWebViewAndLoad(m_baseURL + "hello_world.html"));
483     webViewImpl->resize(WebSize(640, 480));
484     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
485     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
486
487     // Make the page scale and scroll with the given paremeters.
488     webViewImpl->setPageScaleFactor(2.0f, WebPoint(116, 84));
489     EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
490     EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
491     EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
492     webViewImpl->page()->mainFrame()->loader()->history()->saveDocumentAndScrollState();
493
494     // Confirm that restoring the page state restores the parameters.
495     webViewImpl->setPageScaleFactor(1.5f, WebPoint(16, 24));
496     EXPECT_EQ(1.5f, webViewImpl->pageScaleFactor());
497     EXPECT_EQ(16, webViewImpl->mainFrame()->scrollOffset().width);
498     EXPECT_EQ(24, webViewImpl->mainFrame()->scrollOffset().height);
499     webViewImpl->page()->mainFrame()->loader()->history()->restoreScrollPositionAndViewState();
500     EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
501     EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
502     EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
503     webViewImpl->page()->mainFrame()->loader()->history()->saveDocumentAndScrollState();
504
505     // Confirm that resetting the page state resets the saved scroll position.
506     // The HistoryController treats a page scale factor of 0.0f as special and avoids
507     // restoring it to the WebView.
508     webViewImpl->resetScrollAndScaleState();
509     EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
510     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
511     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
512     webViewImpl->page()->mainFrame()->loader()->history()->restoreScrollPositionAndViewState();
513     EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
514     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
515     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
516     webViewImpl->close();
517 }
518
519 class ContentDetectorClient : public WebViewClient {
520 public:
521     ContentDetectorClient() { reset(); }
522
523     virtual WebContentDetectionResult detectContentAround(const WebHitTestResult& hitTest) OVERRIDE
524     {
525         m_contentDetectionRequested = true;
526         return m_contentDetectionResult;
527     }
528
529     virtual void scheduleContentIntent(const WebURL& url) OVERRIDE
530     {
531         m_scheduledIntentURL = url;
532     }
533
534     virtual void cancelScheduledContentIntents() OVERRIDE
535     {
536         m_pendingIntentsCancelled = true;
537     }
538
539     void reset()
540     {
541         m_contentDetectionRequested = false;
542         m_pendingIntentsCancelled = false;
543         m_scheduledIntentURL = WebURL();
544         m_contentDetectionResult = WebContentDetectionResult();
545     }
546
547     bool contentDetectionRequested() const { return m_contentDetectionRequested; }
548     bool pendingIntentsCancelled() const { return m_pendingIntentsCancelled; }
549     const WebURL& scheduledIntentURL() const { return m_scheduledIntentURL; }
550     void setContentDetectionResult(const WebContentDetectionResult& result) { m_contentDetectionResult = result; }
551
552 private:
553     bool m_contentDetectionRequested;
554     bool m_pendingIntentsCancelled;
555     WebURL m_scheduledIntentURL;
556     WebContentDetectionResult m_contentDetectionResult;
557 };
558
559 static bool tapElementById(WebView* webView, WebInputEvent::Type type, const WebString& id)
560 {
561     ASSERT(webView);
562     RefPtr<WebCore::Element> element = static_cast<PassRefPtr<WebCore::Element> >(webView->mainFrame()->document().getElementById(id));
563     if (!element)
564         return false;
565
566     element->scrollIntoViewIfNeeded();
567     WebCore::IntPoint center = element->screenRect().center();
568
569     WebGestureEvent event;
570     event.type = type;
571     event.x = center.x();
572     event.y = center.y();
573
574     webView->handleInputEvent(event);
575     runPendingTasks();
576     return true;
577 }
578
579 TEST_F(WebViewTest, DetectContentAroundPosition)
580 {
581     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_listeners.html"));
582
583     ContentDetectorClient client;
584     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "content_listeners.html", true, 0, &client);
585     webView->resize(WebSize(500, 300));
586     webView->layout();
587     runPendingTasks();
588
589     WebString clickListener = WebString::fromUTF8("clickListener");
590     WebString touchstartListener = WebString::fromUTF8("touchstartListener");
591     WebString mousedownListener = WebString::fromUTF8("mousedownListener");
592     WebString noListener = WebString::fromUTF8("noListener");
593     WebString link = WebString::fromUTF8("link");
594
595     // Ensure content detection is not requested for nodes listening to click,
596     // mouse or touch events when we do simple taps.
597     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, clickListener));
598     EXPECT_FALSE(client.contentDetectionRequested());
599     client.reset();
600
601     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, touchstartListener));
602     EXPECT_FALSE(client.contentDetectionRequested());
603     client.reset();
604
605     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, mousedownListener));
606     EXPECT_FALSE(client.contentDetectionRequested());
607     client.reset();
608
609     // Content detection should work normally without these event listeners.
610     // The click listener in the body should be ignored as a special case.
611     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, noListener));
612     EXPECT_TRUE(client.contentDetectionRequested());
613     EXPECT_FALSE(client.scheduledIntentURL().isValid());
614
615     WebURL intentURL = toKURL(m_baseURL);
616     client.setContentDetectionResult(WebContentDetectionResult(WebRange(), WebString(), intentURL));
617     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, noListener));
618     EXPECT_TRUE(client.scheduledIntentURL() == intentURL);
619
620     // Tapping elsewhere should cancel the scheduled intent.
621     WebGestureEvent event;
622     event.type = WebInputEvent::GestureTap;
623     webView->handleInputEvent(event);
624     runPendingTasks();
625     EXPECT_TRUE(client.pendingIntentsCancelled());
626     webView->close();
627 }
628
629 TEST_F(WebViewTest, ClientTapHandling)
630 {
631     TapHandlingWebViewClient client;
632     client.reset();
633     WebView* webView = FrameTestHelpers::createWebViewAndLoad("about:blank", true, 0, &client);
634     WebGestureEvent event;
635     event.type = WebInputEvent::GestureTap;
636     event.x = 3;
637     event.y = 8;
638     webView->handleInputEvent(event);
639     runPendingTasks();
640     EXPECT_EQ(3, client.tapX());
641     EXPECT_EQ(8, client.tapY());
642     client.reset();
643     event.type = WebInputEvent::GestureLongPress;
644     event.x = 25;
645     event.y = 7;
646     webView->handleInputEvent(event);
647     runPendingTasks();
648     EXPECT_EQ(25, client.longpressX());
649     EXPECT_EQ(7, client.longpressY());
650     webView->close();
651 }
652
653 #if OS(ANDROID)
654 TEST_F(WebViewTest, LongPressSelection)
655 {
656     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html"));
657
658     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "longpress_selection.html", true);
659     webView->resize(WebSize(500, 300));
660     webView->layout();
661     runPendingTasks();
662
663     WebString target = WebString::fromUTF8("target");
664     WebString onselectstartfalse = WebString::fromUTF8("onselectstartfalse");
665     WebFrameImpl* frame = static_cast<WebFrameImpl*>(webView->mainFrame());
666
667     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, onselectstartfalse));
668     EXPECT_EQ("", std::string(frame->selectionAsText().utf8().data()));
669     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, target));
670     EXPECT_EQ("testword", std::string(frame->selectionAsText().utf8().data()));
671     webView->close();
672 }
673 #endif
674
675 TEST_F(WebViewTest, SelectionOnDisabledInput)
676 {
677     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("selection_disabled.html"));
678     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "selection_disabled.html", true);
679     webView->resize(WebSize(640, 480));
680     webView->layout();
681     runPendingTasks();
682
683     std::string testWord = "This text should be selected.";
684
685     WebFrameImpl* frame = static_cast<WebFrameImpl*>(webView->mainFrame());
686     EXPECT_EQ(testWord, std::string(frame->selectionAsText().utf8().data()));
687
688     size_t location;
689     size_t length;
690     WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(webView);
691
692     EXPECT_TRUE(webViewImpl->caretOrSelectionRange(&location, &length));
693     EXPECT_EQ(location, 0UL);
694     EXPECT_EQ(length, testWord.length());
695
696     webView->close();
697 }
698
699 TEST_F(WebViewTest, SelectionOnReadOnlyInput)
700 {
701     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("selection_readonly.html"));
702     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "selection_readonly.html", true);
703     webView->resize(WebSize(640, 480));
704     webView->layout();
705     runPendingTasks();
706
707     std::string testWord = "This text should be selected.";
708
709     WebFrameImpl* frame = static_cast<WebFrameImpl*>(webView->mainFrame());
710     EXPECT_EQ(testWord, std::string(frame->selectionAsText().utf8().data()));
711
712     size_t location;
713     size_t length;
714     WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(webView);
715
716     EXPECT_TRUE(webViewImpl->caretOrSelectionRange(&location, &length));
717     EXPECT_EQ(location, 0UL);
718     EXPECT_EQ(length, testWord.length());
719
720     webView->close();
721 }
722
723 }