Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / web / 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 "public/web/WebView.h"
33
34 #include "core/dom/Document.h"
35 #include "core/dom/Element.h"
36 #include "core/editing/FrameSelection.h"
37 #include "core/frame/EventHandlerRegistry.h"
38 #include "core/frame/FrameView.h"
39 #include "core/frame/LocalFrame.h"
40 #include "core/frame/Settings.h"
41 #include "core/html/HTMLDocument.h"
42 #include "core/html/HTMLIFrameElement.h"
43 #include "core/html/HTMLInputElement.h"
44 #include "core/html/HTMLTextAreaElement.h"
45 #include "core/loader/FrameLoadRequest.h"
46 #include "core/page/Chrome.h"
47 #include "core/page/Page.h"
48 #include "core/rendering/RenderLayer.h"
49 #include "core/rendering/RenderView.h"
50 #include "platform/KeyboardCodes.h"
51 #include "platform/geometry/IntSize.h"
52 #include "platform/graphics/Color.h"
53 #include "public/platform/Platform.h"
54 #include "public/platform/WebClipboard.h"
55 #include "public/platform/WebDragData.h"
56 #include "public/platform/WebSize.h"
57 #include "public/platform/WebThread.h"
58 #include "public/platform/WebUnitTestSupport.h"
59 #include "public/web/WebAutofillClient.h"
60 #include "public/web/WebContentDetectionResult.h"
61 #include "public/web/WebDateTimeChooserCompletion.h"
62 #include "public/web/WebDocument.h"
63 #include "public/web/WebDragOperation.h"
64 #include "public/web/WebElement.h"
65 #include "public/web/WebFrame.h"
66 #include "public/web/WebFrameClient.h"
67 #include "public/web/WebHitTestResult.h"
68 #include "public/web/WebInputEvent.h"
69 #include "public/web/WebScriptSource.h"
70 #include "public/web/WebSettings.h"
71 #include "public/web/WebViewClient.h"
72 #include "public/web/WebWidget.h"
73 #include "public/web/WebWidgetClient.h"
74 #include "third_party/skia/include/core/SkBitmap.h"
75 #include "third_party/skia/include/core/SkBitmapDevice.h"
76 #include "third_party/skia/include/core/SkCanvas.h"
77 #include "web/WebLocalFrameImpl.h"
78 #include "web/WebSettingsImpl.h"
79 #include "web/WebViewImpl.h"
80 #include "web/tests/FrameTestHelpers.h"
81 #include "web/tests/URLTestHelpers.h"
82 #include <gtest/gtest.h>
83
84 using namespace blink;
85 using blink::FrameTestHelpers::runPendingTasks;
86 using blink::URLTestHelpers::toKURL;
87
88 namespace {
89
90 enum HorizontalScrollbarState {
91     NoHorizontalScrollbar,
92     VisibleHorizontalScrollbar,
93 };
94
95 enum VerticalScrollbarState {
96     NoVerticalScrollbar,
97     VisibleVerticalScrollbar,
98 };
99
100 class TestData {
101 public:
102     void setWebView(WebView* webView) { m_webView = toWebViewImpl(webView); }
103     void setSize(const WebSize& newSize) { m_size = newSize; }
104     HorizontalScrollbarState horizontalScrollbarState() const
105     {
106         return m_webView->hasHorizontalScrollbar() ? VisibleHorizontalScrollbar: NoHorizontalScrollbar;
107     }
108     VerticalScrollbarState verticalScrollbarState() const
109     {
110         return m_webView->hasVerticalScrollbar() ? VisibleVerticalScrollbar : NoVerticalScrollbar;
111     }
112     int width() const { return m_size.width; }
113     int height() const { return m_size.height; }
114
115 private:
116     WebSize m_size;
117     WebViewImpl* m_webView;
118 };
119
120 class AutoResizeWebViewClient : public FrameTestHelpers::TestWebViewClient {
121 public:
122     // WebViewClient methods
123     virtual void didAutoResize(const WebSize& newSize) { m_testData.setSize(newSize); }
124
125     // Local methods
126     TestData& testData() { return m_testData; }
127
128 private:
129     TestData m_testData;
130 };
131
132 class TapHandlingWebViewClient : public FrameTestHelpers::TestWebViewClient {
133 public:
134     // WebViewClient methods
135     virtual void didHandleGestureEvent(const WebGestureEvent& event, bool eventCancelled)
136     {
137         if (event.type == WebInputEvent::GestureTap) {
138             m_tapX = event.x;
139             m_tapY = event.y;
140         } else if (event.type == WebInputEvent::GestureLongPress) {
141             m_longpressX = event.x;
142             m_longpressY = event.y;
143         }
144     }
145
146     // Local methods
147     void reset()
148     {
149         m_tapX = -1;
150         m_tapY = -1;
151         m_longpressX = -1;
152         m_longpressY = -1;
153     }
154     int tapX() { return m_tapX; }
155     int tapY() { return m_tapY; }
156     int longpressX() { return m_longpressX; }
157     int longpressY() { return m_longpressY; }
158
159 private:
160     int m_tapX;
161     int m_tapY;
162     int m_longpressX;
163     int m_longpressY;
164 };
165
166 class DateTimeChooserWebViewClient : public FrameTestHelpers::TestWebViewClient {
167 public:
168     WebDateTimeChooserCompletion* chooserCompletion()
169     {
170         return m_chooserCompletion;
171     }
172
173     void clearChooserCompletion()
174     {
175         m_chooserCompletion = 0;
176     }
177
178     // WebViewClient methods
179     virtual bool openDateTimeChooser(const WebDateTimeChooserParams&, WebDateTimeChooserCompletion* chooser_completion) OVERRIDE
180     {
181         m_chooserCompletion = chooser_completion;
182         return true;
183     }
184
185 private:
186     WebDateTimeChooserCompletion* m_chooserCompletion;
187
188 };
189
190 class WebViewTest : public testing::Test {
191 public:
192     WebViewTest()
193         : m_baseURL("http://www.test.com/")
194     {
195     }
196
197     virtual void TearDown()
198     {
199         Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
200     }
201
202 protected:
203     void registerMockedHttpURLLoad(const std::string& fileName)
204     {
205         URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(fileName.c_str()));
206     }
207
208     void testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize,
209                         const std::string& pageWidth, const std::string& pageHeight,
210                         int expectedWidth, int expectedHeight,
211                         HorizontalScrollbarState expectedHorizontalState, VerticalScrollbarState expectedVerticalState);
212
213     void testTextInputType(WebTextInputType expectedType, const std::string& htmlFile);
214     void testInputMode(const WebString& expectedInputMode, const std::string& htmlFile);
215     void testSelectionRootBounds(const char* htmlFile, float pageScaleFactor);
216
217     std::string m_baseURL;
218     FrameTestHelpers::WebViewHelper m_webViewHelper;
219 };
220
221 TEST_F(WebViewTest, CopyImageAt)
222 {
223     std::string url = m_baseURL + "canvas-copy-image.html";
224     URLTestHelpers::registerMockedURLLoad(toKURL(url), "canvas-copy-image.html");
225     WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0);
226     webView->resize(WebSize(400, 400));
227     webView->copyImageAt(WebPoint(50, 50));
228
229     blink::WebData data = blink::Platform::current()->clipboard()->readImage(blink::WebClipboard::Buffer());
230     blink::WebImage image = blink::WebImage::fromData(data, WebSize());
231
232     SkAutoLockPixels autoLock(image.getSkBitmap());
233     EXPECT_EQ(SkColorSetARGB(255, 255, 0, 0), image.getSkBitmap().getColor(0, 0));
234 };
235
236 TEST_F(WebViewTest, SetBaseBackgroundColor)
237 {
238     const WebColor kWhite    = 0xFFFFFFFF;
239     const WebColor kBlue     = 0xFF0000FF;
240     const WebColor kDarkCyan = 0xFF227788;
241     const WebColor kTranslucentPutty = 0x80BFB196;
242     const WebColor kTransparent = 0x00000000;
243
244     WebViewImpl* webView = m_webViewHelper.initialize();
245     EXPECT_EQ(kWhite, webView->backgroundColor());
246
247     webView->setBaseBackgroundColor(kBlue);
248     EXPECT_EQ(kBlue, webView->backgroundColor());
249
250     WebURL baseURL = URLTestHelpers::toKURL("http://example.com/");
251     FrameTestHelpers::loadHTMLString(webView->mainFrame(), "<html><head><style>body {background-color:#227788}</style></head></html>", baseURL);
252     EXPECT_EQ(kDarkCyan, webView->backgroundColor());
253
254     FrameTestHelpers::loadHTMLString(webView->mainFrame(), "<html><head><style>body {background-color:rgba(255,0,0,0.5)}</style></head></html>", baseURL);
255     // Expected: red (50% alpha) blended atop base of kBlue.
256     EXPECT_EQ(0xFF7F0080, webView->backgroundColor());
257
258     webView->setBaseBackgroundColor(kTranslucentPutty);
259     // Expected: red (50% alpha) blended atop kTranslucentPutty. Note the alpha.
260     EXPECT_EQ(0xBFE93B32, webView->backgroundColor());
261
262     webView->setBaseBackgroundColor(kTransparent);
263     FrameTestHelpers::loadHTMLString(webView->mainFrame(), "<html><head><style>body {background-color:transparent}</style></head></html>", baseURL);
264     // Expected: transparent on top of kTransparent will still be transparent.
265     EXPECT_EQ(kTransparent, webView->backgroundColor());
266
267     blink::LocalFrame* frame = webView->mainFrameImpl()->frame();
268
269     // Creating a new frame view with the background color having 0 alpha.
270     frame->createView(blink::IntSize(1024, 768), blink::Color::transparent, true);
271     EXPECT_EQ(kTransparent, frame->view()->baseBackgroundColor());
272
273     blink::Color kTransparentRed(100, 0, 0, 0);
274     frame->createView(blink::IntSize(1024, 768), kTransparentRed, true);
275     EXPECT_EQ(kTransparentRed, frame->view()->baseBackgroundColor());
276 }
277
278 TEST_F(WebViewTest, SetBaseBackgroundColorBeforeMainFrame)
279 {
280     const WebColor kBlue = 0xFF0000FF;
281     FrameTestHelpers::TestWebViewClient webViewClient;
282     WebView* webView = WebViewImpl::create(&webViewClient);
283     EXPECT_NE(kBlue, webView->backgroundColor());
284     // webView does not have a frame yet, but we should still be able to set the background color.
285     webView->setBaseBackgroundColor(kBlue);
286     EXPECT_EQ(kBlue, webView->backgroundColor());
287     webView->setMainFrame(WebLocalFrameImpl::create(0));
288     webView->close();
289 }
290
291 TEST_F(WebViewTest, SetBaseBackgroundColorAndBlendWithExistingContent)
292 {
293     const WebColor kAlphaRed = 0x80FF0000;
294     const WebColor kAlphaGreen = 0x8000FF00;
295     const int kWidth = 100;
296     const int kHeight = 100;
297
298     WebView* webView = m_webViewHelper.initialize();
299
300     // Set WebView background to green with alpha.
301     webView->setBaseBackgroundColor(kAlphaGreen);
302     webView->settings()->setShouldClearDocumentBackground(false);
303     webView->resize(WebSize(kWidth, kHeight));
304     webView->layout();
305
306     // Set canvas background to red with alpha.
307     SkBitmap bitmap;
308     ASSERT_TRUE(bitmap.allocN32Pixels(kWidth, kHeight));
309     SkCanvas canvas(bitmap);
310     canvas.clear(kAlphaRed);
311
312     blink::GraphicsContext context(&canvas);
313
314     // Paint the root of the main frame in the way that CompositedLayerMapping would.
315     blink::FrameView* view = m_webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
316     blink::RenderLayer* rootLayer = view->renderView()->layer();
317     blink::IntRect paintRect(0, 0, kWidth, kHeight);
318     blink::LayerPaintingInfo paintingInfo(rootLayer, paintRect, blink::PaintBehaviorNormal, blink::LayoutSize());
319     rootLayer->paintLayerContents(&context, paintingInfo, blink::PaintLayerPaintingCompositingAllPhases);
320
321     // The result should be a blend of red and green.
322     SkColor color = bitmap.getColor(kWidth / 2, kHeight / 2);
323     EXPECT_TRUE(blink::redChannel(color));
324     EXPECT_TRUE(blink::greenChannel(color));
325 }
326
327 TEST_F(WebViewTest, FocusIsInactive)
328 {
329     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "visible_iframe.html");
330     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "visible_iframe.html");
331
332     webView->setFocus(true);
333     webView->setIsActive(true);
334     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
335     EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
336
337     blink::HTMLDocument* document = blink::toHTMLDocument(frame->frame()->document());
338     EXPECT_TRUE(document->hasFocus());
339     webView->setFocus(false);
340     webView->setIsActive(false);
341     EXPECT_FALSE(document->hasFocus());
342     webView->setFocus(true);
343     webView->setIsActive(true);
344     EXPECT_TRUE(document->hasFocus());
345     webView->setFocus(true);
346     webView->setIsActive(false);
347     EXPECT_FALSE(document->hasFocus());
348     webView->setFocus(false);
349     webView->setIsActive(true);
350     EXPECT_FALSE(document->hasFocus());
351 }
352
353 TEST_F(WebViewTest, ActiveState)
354 {
355     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "visible_iframe.html");
356     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "visible_iframe.html");
357
358     ASSERT_TRUE(webView);
359
360     webView->setIsActive(true);
361     EXPECT_TRUE(webView->isActive());
362
363     webView->setIsActive(false);
364     EXPECT_FALSE(webView->isActive());
365
366     webView->setIsActive(true);
367     EXPECT_TRUE(webView->isActive());
368 }
369
370 TEST_F(WebViewTest, HitTestResultAtWithPageScale)
371 {
372     std::string url = m_baseURL + "specify_size.html?" + "50px" + ":" + "50px";
373     URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html");
374     WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0);
375     webView->resize(WebSize(100, 100));
376     WebPoint hitPoint(75, 75);
377
378     // Image is at top left quandrant, so should not hit it.
379     WebHitTestResult negativeResult = webView->hitTestResultAt(hitPoint);
380     ASSERT_EQ(WebNode::ElementNode, negativeResult.node().nodeType());
381     EXPECT_FALSE(negativeResult.node().to<WebElement>().hasHTMLTagName("img"));
382     negativeResult.reset();
383
384     // Scale page up 2x so image should occupy the whole viewport.
385     webView->setPageScaleFactor(2.0f);
386     WebHitTestResult positiveResult = webView->hitTestResultAt(hitPoint);
387     ASSERT_EQ(WebNode::ElementNode, positiveResult.node().nodeType());
388     EXPECT_TRUE(positiveResult.node().to<WebElement>().hasHTMLTagName("img"));
389     positiveResult.reset();
390 }
391
392 void WebViewTest::testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize,
393                                  const std::string& pageWidth, const std::string& pageHeight,
394                                  int expectedWidth, int expectedHeight,
395                                  HorizontalScrollbarState expectedHorizontalState, VerticalScrollbarState expectedVerticalState)
396 {
397     AutoResizeWebViewClient client;
398     std::string url = m_baseURL + "specify_size.html?" + pageWidth + ":" + pageHeight;
399     URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html");
400     WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
401     client.testData().setWebView(webView);
402
403     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
404     blink::FrameView* frameView = frame->frame()->view();
405     frameView->layout();
406     EXPECT_FALSE(frameView->layoutPending());
407     EXPECT_FALSE(frameView->needsLayout());
408
409     webView->enableAutoResizeMode(minAutoResize, maxAutoResize);
410     EXPECT_TRUE(frameView->layoutPending());
411     EXPECT_TRUE(frameView->needsLayout());
412     frameView->layout();
413
414     EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
415
416     EXPECT_EQ(expectedWidth, client.testData().width());
417     EXPECT_EQ(expectedHeight, client.testData().height());
418     EXPECT_EQ(expectedHorizontalState, client.testData().horizontalScrollbarState());
419     EXPECT_EQ(expectedVerticalState, client.testData().verticalScrollbarState());
420
421     m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
422 }
423
424 TEST_F(WebViewTest, DISABLED_AutoResizeMinimumSize)
425 {
426     WebSize minAutoResize(91, 56);
427     WebSize maxAutoResize(403, 302);
428     std::string pageWidth = "91px";
429     std::string pageHeight = "56px";
430     int expectedWidth = 91;
431     int expectedHeight = 56;
432     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
433                    expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
434 }
435
436 TEST_F(WebViewTest, AutoResizeHeightOverflowAndFixedWidth)
437 {
438     WebSize minAutoResize(90, 95);
439     WebSize maxAutoResize(90, 100);
440     std::string pageWidth = "60px";
441     std::string pageHeight = "200px";
442     int expectedWidth = 90;
443     int expectedHeight = 100;
444     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
445                    expectedWidth, expectedHeight, NoHorizontalScrollbar, VisibleVerticalScrollbar);
446 }
447
448 TEST_F(WebViewTest, AutoResizeFixedHeightAndWidthOverflow)
449 {
450     WebSize minAutoResize(90, 100);
451     WebSize maxAutoResize(200, 100);
452     std::string pageWidth = "300px";
453     std::string pageHeight = "80px";
454     int expectedWidth = 200;
455     int expectedHeight = 100;
456     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
457                    expectedWidth, expectedHeight, VisibleHorizontalScrollbar, NoVerticalScrollbar);
458 }
459
460 // Next three tests disabled for https://bugs.webkit.org/show_bug.cgi?id=92318 .
461 // It seems we can run three AutoResize tests, then the next one breaks.
462 TEST_F(WebViewTest, DISABLED_AutoResizeInBetweenSizes)
463 {
464     WebSize minAutoResize(90, 95);
465     WebSize maxAutoResize(200, 300);
466     std::string pageWidth = "100px";
467     std::string pageHeight = "200px";
468     int expectedWidth = 100;
469     int expectedHeight = 200;
470     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
471                    expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
472 }
473
474 TEST_F(WebViewTest, DISABLED_AutoResizeOverflowSizes)
475 {
476     WebSize minAutoResize(90, 95);
477     WebSize maxAutoResize(200, 300);
478     std::string pageWidth = "300px";
479     std::string pageHeight = "400px";
480     int expectedWidth = 200;
481     int expectedHeight = 300;
482     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
483                    expectedWidth, expectedHeight, VisibleHorizontalScrollbar, VisibleVerticalScrollbar);
484 }
485
486 TEST_F(WebViewTest, DISABLED_AutoResizeMaxSize)
487 {
488     WebSize minAutoResize(90, 95);
489     WebSize maxAutoResize(200, 300);
490     std::string pageWidth = "200px";
491     std::string pageHeight = "300px";
492     int expectedWidth = 200;
493     int expectedHeight = 300;
494     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
495                    expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
496 }
497
498 void WebViewTest::testTextInputType(WebTextInputType expectedType, const std::string& htmlFile)
499 {
500     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(htmlFile.c_str()));
501     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + htmlFile);
502     webView->setInitialFocus(false);
503     EXPECT_EQ(expectedType, webView->textInputInfo().type);
504 }
505
506 TEST_F(WebViewTest, TextInputType)
507 {
508     testTextInputType(WebTextInputTypeText, "input_field_default.html");
509     testTextInputType(WebTextInputTypePassword, "input_field_password.html");
510     testTextInputType(WebTextInputTypeEmail, "input_field_email.html");
511     testTextInputType(WebTextInputTypeSearch, "input_field_search.html");
512     testTextInputType(WebTextInputTypeNumber, "input_field_number.html");
513     testTextInputType(WebTextInputTypeTelephone, "input_field_tel.html");
514     testTextInputType(WebTextInputTypeURL, "input_field_url.html");
515 }
516
517 void WebViewTest::testInputMode(const WebString& expectedInputMode, const std::string& htmlFile)
518 {
519     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(htmlFile.c_str()));
520     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + htmlFile);
521     webView->setInitialFocus(false);
522     EXPECT_EQ(expectedInputMode, webView->textInputInfo().inputMode);
523 }
524
525 TEST_F(WebViewTest, InputMode)
526 {
527     testInputMode(WebString(), "input_mode_default.html");
528     testInputMode(WebString("unknown"), "input_mode_default_unknown.html");
529     testInputMode(WebString("verbatim"), "input_mode_default_verbatim.html");
530     testInputMode(WebString("verbatim"), "input_mode_type_text_verbatim.html");
531     testInputMode(WebString("verbatim"), "input_mode_type_search_verbatim.html");
532     testInputMode(WebString(), "input_mode_type_url_verbatim.html");
533     testInputMode(WebString("verbatim"), "input_mode_textarea_verbatim.html");
534 }
535
536 TEST_F(WebViewTest, TextInputInfoWithReplacedElements)
537 {
538     std::string url = m_baseURL + "div_with_image.html";
539     URLTestHelpers::registerMockedURLLoad(toKURL(url), "div_with_image.html");
540     WebView* webView = m_webViewHelper.initializeAndLoad(url);
541     webView->setInitialFocus(false);
542     WebTextInputInfo info = webView->textInputInfo();
543
544     EXPECT_EQ("foo\xef\xbf\xbc", info.value.utf8());
545 }
546
547 TEST_F(WebViewTest, SetEditableSelectionOffsetsAndTextInputInfo)
548 {
549     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
550     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
551     webView->setInitialFocus(false);
552     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
553     frame->setEditableSelectionOffsets(5, 13);
554     EXPECT_EQ("56789abc", frame->selectionAsText());
555     WebTextInputInfo info = webView->textInputInfo();
556     EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value);
557     EXPECT_EQ(5, info.selectionStart);
558     EXPECT_EQ(13, info.selectionEnd);
559     EXPECT_EQ(-1, info.compositionStart);
560     EXPECT_EQ(-1, info.compositionEnd);
561
562     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_editable_populated.html"));
563     webView = m_webViewHelper.initializeAndLoad(m_baseURL + "content_editable_populated.html");
564     webView->setInitialFocus(false);
565     frame = toWebLocalFrameImpl(webView->mainFrame());
566     frame->setEditableSelectionOffsets(8, 19);
567     EXPECT_EQ("89abcdefghi", frame->selectionAsText());
568     info = webView->textInputInfo();
569     EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value);
570     EXPECT_EQ(8, info.selectionStart);
571     EXPECT_EQ(19, info.selectionEnd);
572     EXPECT_EQ(-1, info.compositionStart);
573     EXPECT_EQ(-1, info.compositionEnd);
574 }
575
576 TEST_F(WebViewTest, ConfirmCompositionCursorPositionChange)
577 {
578     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
579     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
580     webView->setInitialFocus(false);
581
582     // Set up a composition that needs to be committed.
583     std::string compositionText("hello");
584
585     WebVector<WebCompositionUnderline> emptyUnderlines;
586     webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 3, 3);
587
588     WebTextInputInfo info = webView->textInputInfo();
589     EXPECT_EQ("hello", std::string(info.value.utf8().data()));
590     EXPECT_EQ(3, info.selectionStart);
591     EXPECT_EQ(3, info.selectionEnd);
592     EXPECT_EQ(0, info.compositionStart);
593     EXPECT_EQ(5, info.compositionEnd);
594
595     webView->confirmComposition(WebWidget::KeepSelection);
596     info = webView->textInputInfo();
597     EXPECT_EQ(3, info.selectionStart);
598     EXPECT_EQ(3, info.selectionEnd);
599     EXPECT_EQ(-1, info.compositionStart);
600     EXPECT_EQ(-1, info.compositionEnd);
601
602     webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 3, 3);
603     info = webView->textInputInfo();
604     EXPECT_EQ("helhellolo", std::string(info.value.utf8().data()));
605     EXPECT_EQ(6, info.selectionStart);
606     EXPECT_EQ(6, info.selectionEnd);
607     EXPECT_EQ(3, info.compositionStart);
608     EXPECT_EQ(8, info.compositionEnd);
609
610     webView->confirmComposition(WebWidget::DoNotKeepSelection);
611     info = webView->textInputInfo();
612     EXPECT_EQ(8, info.selectionStart);
613     EXPECT_EQ(8, info.selectionEnd);
614     EXPECT_EQ(-1, info.compositionStart);
615     EXPECT_EQ(-1, info.compositionEnd);
616 }
617
618 TEST_F(WebViewTest, InsertNewLinePlacementAfterConfirmComposition)
619 {
620     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("text_area_populated.html"));
621     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "text_area_populated.html");
622     webView->setInitialFocus(false);
623
624     WebVector<WebCompositionUnderline> emptyUnderlines;
625
626     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
627     frame->setEditableSelectionOffsets(4, 4);
628     frame->setCompositionFromExistingText(8, 12, emptyUnderlines);
629
630     WebTextInputInfo info = webView->textInputInfo();
631     EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
632     EXPECT_EQ(4, info.selectionStart);
633     EXPECT_EQ(4, info.selectionEnd);
634     EXPECT_EQ(8, info.compositionStart);
635     EXPECT_EQ(12, info.compositionEnd);
636
637     webView->confirmComposition(WebWidget::KeepSelection);
638     info = webView->textInputInfo();
639     EXPECT_EQ(4, info.selectionStart);
640     EXPECT_EQ(4, info.selectionEnd);
641     EXPECT_EQ(-1, info.compositionStart);
642     EXPECT_EQ(-1, info.compositionEnd);
643
644     std::string compositionText("\n");
645     webView->confirmComposition(WebString::fromUTF8(compositionText.c_str()));
646     info = webView->textInputInfo();
647     EXPECT_EQ(5, info.selectionStart);
648     EXPECT_EQ(5, info.selectionEnd);
649     EXPECT_EQ(-1, info.compositionStart);
650     EXPECT_EQ(-1, info.compositionEnd);
651     EXPECT_EQ("0123\n456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
652 }
653
654 TEST_F(WebViewTest, ExtendSelectionAndDelete)
655 {
656     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
657     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
658     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
659     webView->setInitialFocus(false);
660     frame->setEditableSelectionOffsets(10, 10);
661     frame->extendSelectionAndDelete(5, 8);
662     WebTextInputInfo info = webView->textInputInfo();
663     EXPECT_EQ("01234ijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
664     EXPECT_EQ(5, info.selectionStart);
665     EXPECT_EQ(5, info.selectionEnd);
666     frame->extendSelectionAndDelete(10, 0);
667     info = webView->textInputInfo();
668     EXPECT_EQ("ijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
669 }
670
671 TEST_F(WebViewTest, SetCompositionFromExistingText)
672 {
673     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
674     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
675     webView->setInitialFocus(false);
676     WebVector<WebCompositionUnderline> underlines(static_cast<size_t>(1));
677     underlines[0] = blink::WebCompositionUnderline(0, 4, 0, false, 0);
678     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
679     frame->setEditableSelectionOffsets(4, 10);
680     frame->setCompositionFromExistingText(8, 12, underlines);
681     WebVector<WebCompositionUnderline> underlineResults = toWebViewImpl(webView)->compositionUnderlines();
682     EXPECT_EQ(8u, underlineResults[0].startOffset);
683     EXPECT_EQ(12u, underlineResults[0].endOffset);
684     WebTextInputInfo info = webView->textInputInfo();
685     EXPECT_EQ(4, info.selectionStart);
686     EXPECT_EQ(10, info.selectionEnd);
687     EXPECT_EQ(8, info.compositionStart);
688     EXPECT_EQ(12, info.compositionEnd);
689     WebVector<WebCompositionUnderline> emptyUnderlines;
690     frame->setCompositionFromExistingText(0, 0, emptyUnderlines);
691     info = webView->textInputInfo();
692     EXPECT_EQ(4, info.selectionStart);
693     EXPECT_EQ(10, info.selectionEnd);
694     EXPECT_EQ(-1, info.compositionStart);
695     EXPECT_EQ(-1, info.compositionEnd);
696 }
697
698 TEST_F(WebViewTest, SetCompositionFromExistingTextInTextArea)
699 {
700     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("text_area_populated.html"));
701     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "text_area_populated.html");
702     webView->setInitialFocus(false);
703     WebVector<WebCompositionUnderline> underlines(static_cast<size_t>(1));
704     underlines[0] = blink::WebCompositionUnderline(0, 4, 0, false, 0);
705     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
706     frame->setEditableSelectionOffsets(27, 27);
707     std::string newLineText("\n");
708     webView->confirmComposition(WebString::fromUTF8(newLineText.c_str()));
709     WebTextInputInfo info = webView->textInputInfo();
710     EXPECT_EQ("0123456789abcdefghijklmnopq\nrstuvwxyz", std::string(info.value.utf8().data()));
711
712     frame->setEditableSelectionOffsets(31, 31);
713     frame->setCompositionFromExistingText(30, 34, underlines);
714     WebVector<WebCompositionUnderline> underlineResults = toWebViewImpl(webView)->compositionUnderlines();
715     EXPECT_EQ(2u, underlineResults[0].startOffset);
716     EXPECT_EQ(6u, underlineResults[0].endOffset);
717     info = webView->textInputInfo();
718     EXPECT_EQ("0123456789abcdefghijklmnopq\nrstuvwxyz", std::string(info.value.utf8().data()));
719     EXPECT_EQ(31, info.selectionStart);
720     EXPECT_EQ(31, info.selectionEnd);
721     EXPECT_EQ(30, info.compositionStart);
722     EXPECT_EQ(34, info.compositionEnd);
723
724     std::string compositionText("yolo");
725     webView->confirmComposition(WebString::fromUTF8(compositionText.c_str()));
726     info = webView->textInputInfo();
727     EXPECT_EQ("0123456789abcdefghijklmnopq\nrsyoloxyz", std::string(info.value.utf8().data()));
728     EXPECT_EQ(34, info.selectionStart);
729     EXPECT_EQ(34, info.selectionEnd);
730     EXPECT_EQ(-1, info.compositionStart);
731     EXPECT_EQ(-1, info.compositionEnd);
732 }
733
734 TEST_F(WebViewTest, SetEditableSelectionOffsetsKeepsComposition)
735 {
736     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
737     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
738     webView->setInitialFocus(false);
739
740     std::string compositionTextFirst("hello ");
741     std::string compositionTextSecond("world");
742     WebVector<WebCompositionUnderline> emptyUnderlines;
743
744     webView->confirmComposition(WebString::fromUTF8(compositionTextFirst.c_str()));
745     webView->setComposition(WebString::fromUTF8(compositionTextSecond.c_str()), emptyUnderlines, 5, 5);
746
747     WebTextInputInfo info = webView->textInputInfo();
748     EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
749     EXPECT_EQ(11, info.selectionStart);
750     EXPECT_EQ(11, info.selectionEnd);
751     EXPECT_EQ(6, info.compositionStart);
752     EXPECT_EQ(11, info.compositionEnd);
753
754     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
755     frame->setEditableSelectionOffsets(6, 6);
756     info = webView->textInputInfo();
757     EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
758     EXPECT_EQ(6, info.selectionStart);
759     EXPECT_EQ(6, info.selectionEnd);
760     EXPECT_EQ(6, info.compositionStart);
761     EXPECT_EQ(11, info.compositionEnd);
762
763     frame->setEditableSelectionOffsets(8, 8);
764     info = webView->textInputInfo();
765     EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
766     EXPECT_EQ(8, info.selectionStart);
767     EXPECT_EQ(8, info.selectionEnd);
768     EXPECT_EQ(6, info.compositionStart);
769     EXPECT_EQ(11, info.compositionEnd);
770
771     frame->setEditableSelectionOffsets(11, 11);
772     info = webView->textInputInfo();
773     EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
774     EXPECT_EQ(11, info.selectionStart);
775     EXPECT_EQ(11, info.selectionEnd);
776     EXPECT_EQ(6, info.compositionStart);
777     EXPECT_EQ(11, info.compositionEnd);
778
779     frame->setEditableSelectionOffsets(6, 11);
780     info = webView->textInputInfo();
781     EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
782     EXPECT_EQ(6, info.selectionStart);
783     EXPECT_EQ(11, info.selectionEnd);
784     EXPECT_EQ(6, info.compositionStart);
785     EXPECT_EQ(11, info.compositionEnd);
786
787     frame->setEditableSelectionOffsets(2, 2);
788     info = webView->textInputInfo();
789     EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
790     EXPECT_EQ(2, info.selectionStart);
791     EXPECT_EQ(2, info.selectionEnd);
792     EXPECT_EQ(-1, info.compositionStart);
793     EXPECT_EQ(-1, info.compositionEnd);
794 }
795
796 TEST_F(WebViewTest, IsSelectionAnchorFirst)
797 {
798     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
799     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
800     WebFrame* frame = webView->mainFrame();
801
802     webView->setPageScaleFactorLimits(1, 1);
803     webView->setInitialFocus(false);
804     frame->setEditableSelectionOffsets(4, 10);
805     EXPECT_TRUE(webView->isSelectionAnchorFirst());
806     WebRect anchor;
807     WebRect focus;
808     webView->selectionBounds(anchor, focus);
809     frame->selectRange(WebPoint(focus.x, focus.y), WebPoint(anchor.x, anchor.y));
810     EXPECT_FALSE(webView->isSelectionAnchorFirst());
811 }
812
813 TEST_F(WebViewTest, HistoryResetScrollAndScaleState)
814 {
815     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("hello_world.html"));
816     WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "hello_world.html");
817     webViewImpl->resize(WebSize(640, 480));
818     webViewImpl->layout();
819     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
820     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
821
822     // Make the page scale and scroll with the given paremeters.
823     webViewImpl->setPageScaleFactor(2.0f);
824     webViewImpl->setMainFrameScrollOffset(WebPoint(116, 84));
825     EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
826     EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
827     EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
828     blink::LocalFrame* mainFrameLocal = toLocalFrame(webViewImpl->page()->mainFrame());
829     mainFrameLocal->loader().saveScrollState();
830     EXPECT_EQ(2.0f, mainFrameLocal->loader().currentItem()->pageScaleFactor());
831     EXPECT_EQ(116, mainFrameLocal->loader().currentItem()->scrollPoint().x());
832     EXPECT_EQ(84, mainFrameLocal->loader().currentItem()->scrollPoint().y());
833
834     // Confirm that resetting the page state resets the saved scroll position.
835     // The HistoryController treats a page scale factor of 0.0f as special and avoids
836     // restoring it to the WebView.
837     webViewImpl->resetScrollAndScaleState();
838     EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
839     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
840     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
841     EXPECT_EQ(0.0f, mainFrameLocal->loader().currentItem()->pageScaleFactor());
842     EXPECT_EQ(0, mainFrameLocal->loader().currentItem()->scrollPoint().x());
843     EXPECT_EQ(0, mainFrameLocal->loader().currentItem()->scrollPoint().y());
844 }
845
846 TEST_F(WebViewTest, BackForwardRestoreScroll)
847 {
848     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("back_forward_restore_scroll.html"));
849     WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "back_forward_restore_scroll.html");
850     webViewImpl->resize(WebSize(640, 480));
851     webViewImpl->layout();
852
853     // Emulate a user scroll
854     webViewImpl->setMainFrameScrollOffset(WebPoint(0, 900));
855     blink::LocalFrame* mainFrameLocal = toLocalFrame(webViewImpl->page()->mainFrame());
856     RefPtr<blink::HistoryItem> item1 = mainFrameLocal->loader().currentItem();
857
858     // Click an anchor
859     mainFrameLocal->loader().load(blink::FrameLoadRequest(mainFrameLocal->document(), blink::ResourceRequest(mainFrameLocal->document()->completeURL("#a"))));
860     RefPtr<blink::HistoryItem> item2 = mainFrameLocal->loader().currentItem();
861
862     // Go back, then forward, then back again.
863     mainFrameLocal->loader().loadHistoryItem(item1.get(), blink::HistorySameDocumentLoad);
864     mainFrameLocal->loader().loadHistoryItem(item2.get(), blink::HistorySameDocumentLoad);
865     mainFrameLocal->loader().loadHistoryItem(item1.get(), blink::HistorySameDocumentLoad);
866
867     // Click a different anchor
868     mainFrameLocal->loader().load(blink::FrameLoadRequest(mainFrameLocal->document(), blink::ResourceRequest(mainFrameLocal->document()->completeURL("#b"))));
869     RefPtr<blink::HistoryItem> item3 = mainFrameLocal->loader().currentItem();
870
871     // Go back, then forward. The scroll position should be properly set on the forward navigation.
872     mainFrameLocal->loader().loadHistoryItem(item1.get(), blink::HistorySameDocumentLoad);
873     mainFrameLocal->loader().loadHistoryItem(item3.get(), blink::HistorySameDocumentLoad);
874     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
875     EXPECT_GT(webViewImpl->mainFrame()->scrollOffset().height, 2000);
876 }
877
878 class EnterFullscreenWebViewClient : public FrameTestHelpers::TestWebViewClient {
879 public:
880     // WebViewClient methods
881     virtual bool enterFullScreen() { return true; }
882     virtual void exitFullScreen() { }
883 };
884
885
886 TEST_F(WebViewTest, EnterFullscreenResetScrollAndScaleState)
887 {
888     EnterFullscreenWebViewClient client;
889     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("hello_world.html"));
890     WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "hello_world.html", true, 0, &client);
891     webViewImpl->resize(WebSize(640, 480));
892     webViewImpl->layout();
893     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
894     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
895
896     // Make the page scale and scroll with the given paremeters.
897     webViewImpl->setPageScaleFactor(2.0f);
898     webViewImpl->setMainFrameScrollOffset(WebPoint(116, 84));
899     EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
900     EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
901     EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
902
903     RefPtrWillBeRawPtr<blink::Element> element = static_cast<PassRefPtrWillBeRawPtr<blink::Element> >(webViewImpl->mainFrame()->document().body());
904     webViewImpl->enterFullScreenForElement(element.get());
905     webViewImpl->willEnterFullScreen();
906     webViewImpl->didEnterFullScreen();
907
908     // Page scale factor must be 1.0 during fullscreen for elements to be sized
909     // properly.
910     EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
911
912     // Make sure fullscreen nesting doesn't disrupt scroll/scale saving.
913     RefPtrWillBeRawPtr<blink::Element> otherElement = static_cast<PassRefPtrWillBeRawPtr<blink::Element> >(webViewImpl->mainFrame()->document().head());
914     webViewImpl->enterFullScreenForElement(otherElement.get());
915
916     // Confirm that exiting fullscreen restores the parameters.
917     webViewImpl->willExitFullScreen();
918     webViewImpl->didExitFullScreen();
919     EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
920     EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
921     EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
922
923     m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
924 }
925
926 class PrintWebViewClient : public FrameTestHelpers::TestWebViewClient {
927 public:
928     PrintWebViewClient()
929         : m_printCalled(false)
930     {
931     }
932
933     // WebViewClient methods
934     virtual void printPage(WebLocalFrame*) OVERRIDE
935     {
936         m_printCalled = true;
937     }
938
939     bool printCalled() const { return m_printCalled; }
940
941 private:
942     bool m_printCalled;
943 };
944
945
946 TEST_F(WebViewTest, PrintWithXHRInFlight)
947 {
948     PrintWebViewClient client;
949     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("print_with_xhr_inflight.html"));
950     WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "print_with_xhr_inflight.html", true, 0, &client);
951
952     ASSERT_EQ(blink::FrameStateComplete, toLocalFrame(webViewImpl->page()->mainFrame())->loader().state());
953     EXPECT_TRUE(client.printCalled());
954     m_webViewHelper.reset();
955 }
956
957 class DropTask : public WebThread::Task {
958 public:
959     explicit DropTask(WebView* webView) : m_webView(webView)
960     {
961     }
962
963     virtual void run() OVERRIDE
964     {
965         const WebPoint clientPoint(0, 0);
966         const WebPoint screenPoint(0, 0);
967         m_webView->dragTargetDrop(clientPoint, screenPoint, 0);
968     }
969
970 private:
971     WebView* const m_webView;
972 };
973 static void DragAndDropURL(WebViewImpl* webView, const std::string& url)
974 {
975     blink::WebDragData dragData;
976     dragData.initialize();
977
978     WebDragData::Item item;
979     item.storageType = WebDragData::Item::StorageTypeString;
980     item.stringType = "text/uri-list";
981     item.stringData = WebString::fromUTF8(url);
982     dragData.addItem(item);
983
984     const WebPoint clientPoint(0, 0);
985     const WebPoint screenPoint(0, 0);
986     webView->dragTargetDragEnter(dragData, clientPoint, screenPoint, blink::WebDragOperationCopy, 0);
987     Platform::current()->currentThread()->postTask(new DropTask(webView));
988     FrameTestHelpers::pumpPendingRequestsDoNotUse(webView->mainFrame());
989 }
990
991 TEST_F(WebViewTest, DragDropURL)
992 {
993     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "foo.html");
994     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "bar.html");
995
996     const std::string fooUrl = m_baseURL + "foo.html";
997     const std::string barUrl = m_baseURL + "bar.html";
998
999     WebViewImpl* webView = m_webViewHelper.initializeAndLoad(fooUrl);
1000
1001     ASSERT_TRUE(webView);
1002
1003     // Drag and drop barUrl and verify that we've navigated to it.
1004     DragAndDropURL(webView, barUrl);
1005     EXPECT_EQ(barUrl, webView->mainFrame()->document().url().string().utf8());
1006
1007     // Drag and drop fooUrl and verify that we've navigated back to it.
1008     DragAndDropURL(webView, fooUrl);
1009     EXPECT_EQ(fooUrl, webView->mainFrame()->document().url().string().utf8());
1010
1011     // Disable navigation on drag-and-drop.
1012     webView->settingsImpl()->setNavigateOnDragDrop(false);
1013
1014     // Attempt to drag and drop to barUrl and verify that no navigation has occurred.
1015     DragAndDropURL(webView, barUrl);
1016     EXPECT_EQ(fooUrl, webView->mainFrame()->document().url().string().utf8());
1017 }
1018
1019 class ContentDetectorClient : public FrameTestHelpers::TestWebViewClient {
1020 public:
1021     ContentDetectorClient() { reset(); }
1022
1023     virtual WebContentDetectionResult detectContentAround(const WebHitTestResult& hitTest) OVERRIDE
1024     {
1025         m_contentDetectionRequested = true;
1026         return m_contentDetectionResult;
1027     }
1028
1029     virtual void scheduleContentIntent(const WebURL& url) OVERRIDE
1030     {
1031         m_scheduledIntentURL = url;
1032     }
1033
1034     virtual void cancelScheduledContentIntents() OVERRIDE
1035     {
1036         m_pendingIntentsCancelled = true;
1037     }
1038
1039     void reset()
1040     {
1041         m_contentDetectionRequested = false;
1042         m_pendingIntentsCancelled = false;
1043         m_scheduledIntentURL = WebURL();
1044         m_contentDetectionResult = WebContentDetectionResult();
1045     }
1046
1047     bool contentDetectionRequested() const { return m_contentDetectionRequested; }
1048     bool pendingIntentsCancelled() const { return m_pendingIntentsCancelled; }
1049     const WebURL& scheduledIntentURL() const { return m_scheduledIntentURL; }
1050     void setContentDetectionResult(const WebContentDetectionResult& result) { m_contentDetectionResult = result; }
1051
1052 private:
1053     bool m_contentDetectionRequested;
1054     bool m_pendingIntentsCancelled;
1055     WebURL m_scheduledIntentURL;
1056     WebContentDetectionResult m_contentDetectionResult;
1057 };
1058
1059 static bool tapElementById(WebView* webView, WebInputEvent::Type type, const WebString& id)
1060 {
1061     ASSERT(webView);
1062     RefPtrWillBeRawPtr<blink::Element> element = static_cast<PassRefPtrWillBeRawPtr<blink::Element> >(webView->mainFrame()->document().getElementById(id));
1063     if (!element)
1064         return false;
1065
1066     element->scrollIntoViewIfNeeded();
1067     blink::IntPoint center = element->screenRect().center();
1068
1069     WebGestureEvent event;
1070     event.type = type;
1071     event.x = center.x();
1072     event.y = center.y();
1073
1074     webView->handleInputEvent(event);
1075     runPendingTasks();
1076     return true;
1077 }
1078
1079 TEST_F(WebViewTest, DetectContentAroundPosition)
1080 {
1081     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_listeners.html"));
1082
1083     ContentDetectorClient client;
1084     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "content_listeners.html", true, 0, &client);
1085     webView->resize(WebSize(500, 300));
1086     webView->layout();
1087     runPendingTasks();
1088
1089     WebString clickListener = WebString::fromUTF8("clickListener");
1090     WebString touchstartListener = WebString::fromUTF8("touchstartListener");
1091     WebString mousedownListener = WebString::fromUTF8("mousedownListener");
1092     WebString noListener = WebString::fromUTF8("noListener");
1093     WebString link = WebString::fromUTF8("link");
1094
1095     // Ensure content detection is not requested for nodes listening to click,
1096     // mouse or touch events when we do simple taps.
1097     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, clickListener));
1098     EXPECT_FALSE(client.contentDetectionRequested());
1099     client.reset();
1100
1101     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, touchstartListener));
1102     EXPECT_FALSE(client.contentDetectionRequested());
1103     client.reset();
1104
1105     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, mousedownListener));
1106     EXPECT_FALSE(client.contentDetectionRequested());
1107     client.reset();
1108
1109     // Content detection should work normally without these event listeners.
1110     // The click listener in the body should be ignored as a special case.
1111     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, noListener));
1112     EXPECT_TRUE(client.contentDetectionRequested());
1113     EXPECT_FALSE(client.scheduledIntentURL().isValid());
1114
1115     WebURL intentURL = toKURL(m_baseURL);
1116     client.setContentDetectionResult(WebContentDetectionResult(WebRange(), WebString(), intentURL));
1117     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, noListener));
1118     EXPECT_TRUE(client.scheduledIntentURL() == intentURL);
1119
1120     // Tapping elsewhere should cancel the scheduled intent.
1121     WebGestureEvent event;
1122     event.type = WebInputEvent::GestureTap;
1123     webView->handleInputEvent(event);
1124     runPendingTasks();
1125     EXPECT_TRUE(client.pendingIntentsCancelled());
1126
1127     m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
1128 }
1129
1130 TEST_F(WebViewTest, ClientTapHandling)
1131 {
1132     TapHandlingWebViewClient client;
1133     client.reset();
1134     WebView* webView = m_webViewHelper.initializeAndLoad("about:blank", true, 0, &client);
1135     WebGestureEvent event;
1136     event.type = WebInputEvent::GestureTap;
1137     event.x = 3;
1138     event.y = 8;
1139     webView->handleInputEvent(event);
1140     runPendingTasks();
1141     EXPECT_EQ(3, client.tapX());
1142     EXPECT_EQ(8, client.tapY());
1143     client.reset();
1144     event.type = WebInputEvent::GestureLongPress;
1145     event.x = 25;
1146     event.y = 7;
1147     webView->handleInputEvent(event);
1148     runPendingTasks();
1149     EXPECT_EQ(25, client.longpressX());
1150     EXPECT_EQ(7, client.longpressY());
1151
1152     m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
1153 }
1154
1155 #if OS(ANDROID)
1156 TEST_F(WebViewTest, LongPressSelection)
1157 {
1158     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html"));
1159
1160     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "longpress_selection.html", true);
1161     webView->resize(WebSize(500, 300));
1162     webView->layout();
1163     runPendingTasks();
1164
1165     WebString target = WebString::fromUTF8("target");
1166     WebString onselectstartfalse = WebString::fromUTF8("onselectstartfalse");
1167     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1168
1169     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, onselectstartfalse));
1170     EXPECT_EQ("", std::string(frame->selectionAsText().utf8().data()));
1171     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, target));
1172     EXPECT_EQ("testword", std::string(frame->selectionAsText().utf8().data()));
1173 }
1174
1175 TEST_F(WebViewTest, BlinkCaretOnTypingAfterLongPress)
1176 {
1177     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("blink_caret_on_typing_after_long_press.html"));
1178
1179     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "blink_caret_on_typing_after_long_press.html", true);
1180     webView->resize(WebSize(640, 480));
1181     webView->layout();
1182     runPendingTasks();
1183
1184     WebString target = WebString::fromUTF8("target");
1185     WebLocalFrameImpl* mainFrame = toWebLocalFrameImpl(webView->mainFrame());
1186
1187     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, target));
1188     EXPECT_TRUE(mainFrame->frame()->selection().isCaretBlinkingSuspended());
1189
1190     WebKeyboardEvent keyEvent;
1191     keyEvent.type = WebInputEvent::RawKeyDown;
1192     webView->handleInputEvent(keyEvent);
1193     keyEvent.type = WebInputEvent::KeyUp;
1194     webView->handleInputEvent(keyEvent);
1195     EXPECT_FALSE(mainFrame->frame()->selection().isCaretBlinkingSuspended());
1196 }
1197 #endif
1198
1199 TEST_F(WebViewTest, SelectionOnDisabledInput)
1200 {
1201     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("selection_disabled.html"));
1202     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "selection_disabled.html", true);
1203     webView->resize(WebSize(640, 480));
1204     webView->layout();
1205     runPendingTasks();
1206
1207     std::string testWord = "This text should be selected.";
1208
1209     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1210     EXPECT_EQ(testWord, std::string(frame->selectionAsText().utf8().data()));
1211
1212     size_t location;
1213     size_t length;
1214     EXPECT_TRUE(toWebViewImpl(webView)->caretOrSelectionRange(&location, &length));
1215     EXPECT_EQ(location, 0UL);
1216     EXPECT_EQ(length, testWord.length());
1217 }
1218
1219 TEST_F(WebViewTest, SelectionOnReadOnlyInput)
1220 {
1221     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("selection_readonly.html"));
1222     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "selection_readonly.html", true);
1223     webView->resize(WebSize(640, 480));
1224     webView->layout();
1225     runPendingTasks();
1226
1227     std::string testWord = "This text should be selected.";
1228
1229     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1230     EXPECT_EQ(testWord, std::string(frame->selectionAsText().utf8().data()));
1231
1232     size_t location;
1233     size_t length;
1234     EXPECT_TRUE(toWebViewImpl(webView)->caretOrSelectionRange(&location, &length));
1235     EXPECT_EQ(location, 0UL);
1236     EXPECT_EQ(length, testWord.length());
1237 }
1238
1239 static void configueCompositingWebView(WebSettings* settings)
1240 {
1241     settings->setAcceleratedCompositingEnabled(true);
1242     settings->setAcceleratedCompositingForFixedPositionEnabled(true);
1243     settings->setAcceleratedCompositingForOverflowScrollEnabled(true);
1244     settings->setCompositedScrollingForFramesEnabled(true);
1245 }
1246
1247 TEST_F(WebViewTest, ShowPressOnTransformedLink)
1248 {
1249     OwnPtr<FrameTestHelpers::TestWebViewClient> fakeCompositingWebViewClient = adoptPtr(new FrameTestHelpers::TestWebViewClient());
1250     FrameTestHelpers::WebViewHelper webViewHelper;
1251     WebViewImpl* webViewImpl = webViewHelper.initialize(true, 0, fakeCompositingWebViewClient.get(), &configueCompositingWebView);
1252
1253     int pageWidth = 640;
1254     int pageHeight = 480;
1255     webViewImpl->resize(WebSize(pageWidth, pageHeight));
1256
1257     WebURL baseURL = URLTestHelpers::toKURL("http://example.com/");
1258     FrameTestHelpers::loadHTMLString(webViewImpl->mainFrame(), "<a href='http://www.test.com' style='position: absolute; left: 20px; top: 20px; width: 200px; -webkit-transform:translateZ(0);'>A link to highlight</a>", baseURL);
1259
1260     WebGestureEvent event;
1261     event.type = WebInputEvent::GestureShowPress;
1262     event.x = 20;
1263     event.y = 20;
1264
1265     // Just make sure we don't hit any asserts.
1266     webViewImpl->handleInputEvent(event);
1267 }
1268
1269 class MockAutofillClient : public WebAutofillClient {
1270 public:
1271     MockAutofillClient()
1272         : m_ignoreTextChanges(false)
1273         , m_textChangesWhileIgnored(0)
1274         , m_textChangesWhileNotIgnored(0)
1275         , m_userGestureNotificationsCount(0) { }
1276
1277     virtual ~MockAutofillClient() { }
1278
1279     virtual void setIgnoreTextChanges(bool ignore) OVERRIDE { m_ignoreTextChanges = ignore; }
1280     virtual void textFieldDidChange(const WebFormControlElement&) OVERRIDE
1281     {
1282         if (m_ignoreTextChanges)
1283             ++m_textChangesWhileIgnored;
1284         else
1285             ++m_textChangesWhileNotIgnored;
1286     }
1287     virtual void firstUserGestureObserved() OVERRIDE { ++m_userGestureNotificationsCount; }
1288
1289     void clearChangeCounts()
1290     {
1291         m_textChangesWhileIgnored = 0;
1292         m_textChangesWhileNotIgnored = 0;
1293     }
1294
1295     int textChangesWhileIgnored() { return m_textChangesWhileIgnored; }
1296     int textChangesWhileNotIgnored() { return m_textChangesWhileNotIgnored; }
1297     int getUserGestureNotificationsCount() { return m_userGestureNotificationsCount; }
1298
1299 private:
1300     bool m_ignoreTextChanges;
1301     int m_textChangesWhileIgnored;
1302     int m_textChangesWhileNotIgnored;
1303     int m_userGestureNotificationsCount;
1304 };
1305
1306
1307 TEST_F(WebViewTest, LosingFocusDoesNotTriggerAutofillTextChange)
1308 {
1309     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
1310     MockAutofillClient client;
1311     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
1312     webView->setAutofillClient(&client);
1313     webView->setInitialFocus(false);
1314
1315     // Set up a composition that needs to be committed.
1316     WebVector<WebCompositionUnderline> emptyUnderlines;
1317     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1318     frame->setEditableSelectionOffsets(4, 10);
1319     frame->setCompositionFromExistingText(8, 12, emptyUnderlines);
1320     WebTextInputInfo info = webView->textInputInfo();
1321     EXPECT_EQ(4, info.selectionStart);
1322     EXPECT_EQ(10, info.selectionEnd);
1323     EXPECT_EQ(8, info.compositionStart);
1324     EXPECT_EQ(12, info.compositionEnd);
1325
1326     // Clear the focus and track that the subsequent composition commit does not trigger a
1327     // text changed notification for autofill.
1328     client.clearChangeCounts();
1329     webView->setFocus(false);
1330     EXPECT_EQ(1, client.textChangesWhileIgnored());
1331     EXPECT_EQ(0, client.textChangesWhileNotIgnored());
1332
1333     webView->setAutofillClient(0);
1334 }
1335
1336 TEST_F(WebViewTest, ConfirmCompositionTriggersAutofillTextChange)
1337 {
1338     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
1339     MockAutofillClient client;
1340     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
1341     webView->setAutofillClient(&client);
1342     webView->setInitialFocus(false);
1343
1344     // Set up a composition that needs to be committed.
1345     std::string compositionText("testingtext");
1346
1347     WebVector<WebCompositionUnderline> emptyUnderlines;
1348     webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 0, compositionText.length());
1349
1350     WebTextInputInfo info = webView->textInputInfo();
1351     EXPECT_EQ(0, info.selectionStart);
1352     EXPECT_EQ((int) compositionText.length(), info.selectionEnd);
1353     EXPECT_EQ(0, info.compositionStart);
1354     EXPECT_EQ((int) compositionText.length(), info.compositionEnd);
1355
1356     client.clearChangeCounts();
1357     webView->confirmComposition();
1358     EXPECT_EQ(0, client.textChangesWhileIgnored());
1359     EXPECT_EQ(1, client.textChangesWhileNotIgnored());
1360
1361     webView->setAutofillClient(0);
1362 }
1363
1364 TEST_F(WebViewTest, SetCompositionFromExistingTextTriggersAutofillTextChange)
1365 {
1366     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
1367     MockAutofillClient client;
1368     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html", true);
1369     webView->setAutofillClient(&client);
1370     webView->setInitialFocus(false);
1371
1372     WebVector<WebCompositionUnderline> emptyUnderlines;
1373
1374     client.clearChangeCounts();
1375     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1376     frame->setCompositionFromExistingText(8, 12, emptyUnderlines);
1377
1378     WebTextInputInfo info = webView->textInputInfo();
1379     EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
1380     EXPECT_EQ(8, info.compositionStart);
1381     EXPECT_EQ(12, info.compositionEnd);
1382
1383     EXPECT_EQ(0, client.textChangesWhileIgnored());
1384     EXPECT_EQ(0, client.textChangesWhileNotIgnored());
1385
1386     WebDocument document = webView->mainFrame()->document();
1387     EXPECT_EQ(WebString::fromUTF8("none"),  document.getElementById("inputEvent").firstChild().nodeValue());
1388
1389     webView->setAutofillClient(0);
1390 }
1391
1392 TEST_F(WebViewTest, ShadowRoot)
1393 {
1394     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("shadow_dom_test.html"));
1395     WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "shadow_dom_test.html", true);
1396
1397     WebDocument document = webViewImpl->mainFrame()->document();
1398     {
1399         WebElement elementWithShadowRoot = document.getElementById("shadowroot");
1400         EXPECT_FALSE(elementWithShadowRoot.isNull());
1401         WebNode shadowRoot = elementWithShadowRoot.shadowRoot();
1402         EXPECT_FALSE(shadowRoot.isNull());
1403     }
1404     {
1405         WebElement elementWithoutShadowRoot = document.getElementById("noshadowroot");
1406         EXPECT_FALSE(elementWithoutShadowRoot.isNull());
1407         WebNode shadowRoot = elementWithoutShadowRoot.shadowRoot();
1408         EXPECT_TRUE(shadowRoot.isNull());
1409     }
1410 }
1411
1412 class ViewCreatingWebViewClient : public FrameTestHelpers::TestWebViewClient {
1413 public:
1414     ViewCreatingWebViewClient()
1415         : m_didFocusCalled(false)
1416     {
1417     }
1418
1419     // WebViewClient methods
1420     virtual WebView* createView(WebLocalFrame*, const WebURLRequest&, const WebWindowFeatures&, const WebString& name, WebNavigationPolicy, bool) OVERRIDE
1421     {
1422         return m_webViewHelper.initialize(true, 0, 0);
1423     }
1424
1425     // WebWidgetClient methods
1426     virtual void didFocus() OVERRIDE
1427     {
1428         m_didFocusCalled = true;
1429     }
1430
1431     bool didFocusCalled() const { return m_didFocusCalled; }
1432     WebView* createdWebView() const { return m_webViewHelper.webView(); }
1433
1434 private:
1435     FrameTestHelpers::WebViewHelper m_webViewHelper;
1436     bool m_didFocusCalled;
1437 };
1438
1439 TEST_F(WebViewTest, FocusExistingFrameOnNavigate)
1440 {
1441     ViewCreatingWebViewClient client;
1442     FrameTestHelpers::WebViewHelper m_webViewHelper;
1443     WebViewImpl* webViewImpl = m_webViewHelper.initialize(true, 0, &client);
1444     webViewImpl->page()->settings().setJavaScriptCanOpenWindowsAutomatically(true);
1445     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewImpl->mainFrame());
1446     frame->setName("_start");
1447
1448     // Make a request that will open a new window
1449     WebURLRequest webURLRequest;
1450     webURLRequest.initialize();
1451     blink::FrameLoadRequest request(0, webURLRequest.toResourceRequest(), "_blank");
1452     toLocalFrame(webViewImpl->page()->mainFrame())->loader().load(request);
1453     ASSERT_TRUE(client.createdWebView());
1454     EXPECT_FALSE(client.didFocusCalled());
1455
1456     // Make a request from the new window that will navigate the original window. The original window should be focused.
1457     WebURLRequest webURLRequestWithTargetStart;
1458     webURLRequestWithTargetStart.initialize();
1459     blink::FrameLoadRequest requestWithTargetStart(0, webURLRequestWithTargetStart.toResourceRequest(), "_start");
1460     toLocalFrame(toWebViewImpl(client.createdWebView())->page()->mainFrame())->loader().load(requestWithTargetStart);
1461     EXPECT_TRUE(client.didFocusCalled());
1462
1463     m_webViewHelper.reset(); // Remove dependency on locally scoped client.
1464 }
1465
1466 TEST_F(WebViewTest, DispatchesFocusOutFocusInOnViewToggleFocus)
1467 {
1468     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "focusout_focusin_events.html");
1469     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "focusout_focusin_events.html", true, 0);
1470
1471     webView->setFocus(true);
1472     webView->setFocus(false);
1473     webView->setFocus(true);
1474
1475     WebElement element = webView->mainFrame()->document().getElementById("message");
1476     EXPECT_STREQ("focusoutfocusin", element.innerText().utf8().data());
1477 }
1478
1479 TEST_F(WebViewTest, DispatchesDomFocusOutDomFocusInOnViewToggleFocus)
1480 {
1481     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "domfocusout_domfocusin_events.html");
1482     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "domfocusout_domfocusin_events.html", true, 0);
1483
1484     webView->setFocus(true);
1485     webView->setFocus(false);
1486     webView->setFocus(true);
1487
1488     WebElement element = webView->mainFrame()->document().getElementById("message");
1489     EXPECT_STREQ("DOMFocusOutDOMFocusIn", element.innerText().utf8().data());
1490 }
1491
1492 #if !ENABLE(INPUT_MULTIPLE_FIELDS_UI)
1493 static void openDateTimeChooser(WebView* webView, blink::HTMLInputElement* inputElement)
1494 {
1495     inputElement->focus();
1496
1497     WebKeyboardEvent keyEvent;
1498     keyEvent.windowsKeyCode = blink::VKEY_SPACE;
1499     keyEvent.type = WebInputEvent::RawKeyDown;
1500     keyEvent.setKeyIdentifierFromWindowsKeyCode();
1501     webView->handleInputEvent(keyEvent);
1502
1503     keyEvent.type = WebInputEvent::KeyUp;
1504     webView->handleInputEvent(keyEvent);
1505 }
1506
1507 TEST_F(WebViewTest, ChooseValueFromDateTimeChooser)
1508 {
1509     DateTimeChooserWebViewClient client;
1510     std::string url = m_baseURL + "date_time_chooser.html";
1511     URLTestHelpers::registerMockedURLLoad(toKURL(url), "date_time_chooser.html");
1512     WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
1513
1514     blink::Document* document = webViewImpl->mainFrameImpl()->frame()->document();
1515
1516     blink::HTMLInputElement* inputElement;
1517
1518     inputElement = toHTMLInputElement(document->getElementById("date"));
1519     openDateTimeChooser(webViewImpl, inputElement);
1520     client.chooserCompletion()->didChooseValue(0);
1521     client.clearChooserCompletion();
1522     EXPECT_STREQ("1970-01-01", inputElement->value().utf8().data());
1523
1524     openDateTimeChooser(webViewImpl, inputElement);
1525     client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1526     client.clearChooserCompletion();
1527     EXPECT_STREQ("", inputElement->value().utf8().data());
1528
1529     inputElement = toHTMLInputElement(document->getElementById("datetimelocal"));
1530     openDateTimeChooser(webViewImpl, inputElement);
1531     client.chooserCompletion()->didChooseValue(0);
1532     client.clearChooserCompletion();
1533     EXPECT_STREQ("1970-01-01T00:00", inputElement->value().utf8().data());
1534
1535     openDateTimeChooser(webViewImpl, inputElement);
1536     client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1537     client.clearChooserCompletion();
1538     EXPECT_STREQ("", inputElement->value().utf8().data());
1539
1540     inputElement = toHTMLInputElement(document->getElementById("month"));
1541     openDateTimeChooser(webViewImpl, inputElement);
1542     client.chooserCompletion()->didChooseValue(0);
1543     client.clearChooserCompletion();
1544     EXPECT_STREQ("1970-01", inputElement->value().utf8().data());
1545
1546     openDateTimeChooser(webViewImpl, inputElement);
1547     client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1548     client.clearChooserCompletion();
1549     EXPECT_STREQ("", inputElement->value().utf8().data());
1550
1551     inputElement = toHTMLInputElement(document->getElementById("time"));
1552     openDateTimeChooser(webViewImpl, inputElement);
1553     client.chooserCompletion()->didChooseValue(0);
1554     client.clearChooserCompletion();
1555     EXPECT_STREQ("00:00", inputElement->value().utf8().data());
1556
1557     openDateTimeChooser(webViewImpl, inputElement);
1558     client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1559     client.clearChooserCompletion();
1560     EXPECT_STREQ("", inputElement->value().utf8().data());
1561
1562     inputElement = toHTMLInputElement(document->getElementById("week"));
1563     openDateTimeChooser(webViewImpl, inputElement);
1564     client.chooserCompletion()->didChooseValue(0);
1565     client.clearChooserCompletion();
1566     EXPECT_STREQ("1970-W01", inputElement->value().utf8().data());
1567
1568     openDateTimeChooser(webViewImpl, inputElement);
1569     client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1570     client.clearChooserCompletion();
1571     EXPECT_STREQ("", inputElement->value().utf8().data());
1572
1573     // Clear the WebViewClient from the webViewHelper to avoid use-after-free in the
1574     // WebViewHelper destructor.
1575     m_webViewHelper.reset();
1576 }
1577 #endif
1578
1579 TEST_F(WebViewTest, DispatchesFocusBlurOnViewToggle)
1580 {
1581     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "focus_blur_events.html");
1582     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "focus_blur_events.html", true, 0);
1583
1584     webView->setFocus(true);
1585     webView->setFocus(false);
1586     webView->setFocus(true);
1587
1588     WebElement element = webView->mainFrame()->document().getElementById("message");
1589     // Expect not to see duplication of events.
1590     EXPECT_STREQ("blurfocus", element.innerText().utf8().data());
1591 }
1592
1593 TEST_F(WebViewTest, SmartClipData)
1594 {
1595     static const char* kExpectedClipText = "\nPrice 10,000,000won";
1596     static const char* kExpectedClipHtml =
1597         "<div id=\"div4\" style=\"padding: 10px; margin: 10px; border: 2px "
1598         "solid rgb(135, 206, 235); float: left; width: 190px; height: 30px; "
1599         "color: rgb(0, 0, 0); font-family: myahem; font-size: 8px; font-style: "
1600         "normal; font-variant: normal; font-weight: normal; letter-spacing: "
1601         "normal; line-height: normal; orphans: auto; text-align: start; "
1602         "text-indent: 0px; text-transform: none; white-space: normal; widows: "
1603         "auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;\">Air "
1604         "conditioner</div><div id=\"div5\" style=\"padding: 10px; margin: "
1605         "10px; border: 2px solid rgb(135, 206, 235); float: left; width: "
1606         "190px; height: 30px; color: rgb(0, 0, 0); font-family: myahem; "
1607         "font-size: 8px; font-style: normal; font-variant: normal; "
1608         "font-weight: normal; letter-spacing: normal; line-height: normal; "
1609         "orphans: auto; text-align: start; text-indent: 0px; text-transform: "
1610         "none; white-space: normal; widows: auto; word-spacing: 0px; "
1611         "-webkit-text-stroke-width: 0px;\">Price 10,000,000won</div>";
1612     WebString clipText;
1613     WebString clipHtml;
1614     WebRect clipRect;
1615     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("Ahem.ttf"));
1616     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("smartclip.html"));
1617     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "smartclip.html");
1618     webView->setPageScaleFactorLimits(1, 1);
1619     webView->resize(WebSize(500, 500));
1620     webView->layout();
1621     WebRect cropRect(300, 125, 100, 50);
1622     webView->extractSmartClipData(cropRect, clipText, clipHtml, clipRect);
1623     EXPECT_STREQ(kExpectedClipText, clipText.utf8().c_str());
1624     EXPECT_STREQ(kExpectedClipHtml, clipHtml.utf8().c_str());
1625 }
1626
1627 class CreateChildCounterFrameClient : public FrameTestHelpers::TestWebFrameClient {
1628 public:
1629     CreateChildCounterFrameClient() : m_count(0) { }
1630     virtual WebFrame* createChildFrame(WebLocalFrame* parent, const WebString& frameName) OVERRIDE;
1631
1632     int count() const { return m_count; }
1633
1634 private:
1635     int m_count;
1636 };
1637
1638 WebFrame* CreateChildCounterFrameClient::createChildFrame(WebLocalFrame* parent, const WebString& frameName)
1639 {
1640     ++m_count;
1641     return TestWebFrameClient::createChildFrame(parent, frameName);
1642 }
1643
1644 TEST_F(WebViewTest, AddFrameInCloseUnload)
1645 {
1646     CreateChildCounterFrameClient frameClient;
1647     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
1648     m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload.html", true, &frameClient);
1649     m_webViewHelper.reset();
1650     EXPECT_EQ(0, frameClient.count());
1651 }
1652
1653 TEST_F(WebViewTest, AddFrameInCloseURLUnload)
1654 {
1655     CreateChildCounterFrameClient frameClient;
1656     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
1657     m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload.html", true, &frameClient);
1658     m_webViewHelper.webViewImpl()->mainFrame()->dispatchUnloadEvent();
1659     EXPECT_EQ(0, frameClient.count());
1660     m_webViewHelper.reset();
1661 }
1662
1663 TEST_F(WebViewTest, AddFrameInNavigateUnload)
1664 {
1665     CreateChildCounterFrameClient frameClient;
1666     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
1667     m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload.html", true, &frameClient);
1668     FrameTestHelpers::loadFrame(m_webViewHelper.webView()->mainFrame(), "about:blank");
1669     EXPECT_EQ(0, frameClient.count());
1670     m_webViewHelper.reset();
1671 }
1672
1673 TEST_F(WebViewTest, AddFrameInChildInNavigateUnload)
1674 {
1675     CreateChildCounterFrameClient frameClient;
1676     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload_wrapper.html"));
1677     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
1678     m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload_wrapper.html", true, &frameClient);
1679     FrameTestHelpers::loadFrame(m_webViewHelper.webView()->mainFrame(), "about:blank");
1680     EXPECT_EQ(1, frameClient.count());
1681     m_webViewHelper.reset();
1682 }
1683
1684 class TouchEventHandlerWebViewClient : public FrameTestHelpers::TestWebViewClient {
1685 public:
1686     // WebWidgetClient methods
1687     virtual void hasTouchEventHandlers(bool state) OVERRIDE
1688     {
1689         m_hasTouchEventHandlerCount[state]++;
1690     }
1691
1692     // Local methods
1693     TouchEventHandlerWebViewClient() : m_hasTouchEventHandlerCount()
1694     {
1695     }
1696
1697     int getAndResetHasTouchEventHandlerCallCount(bool state)
1698     {
1699         int value = m_hasTouchEventHandlerCount[state];
1700         m_hasTouchEventHandlerCount[state] = 0;
1701         return value;
1702     }
1703
1704 private:
1705     int m_hasTouchEventHandlerCount[2];
1706 };
1707
1708 // This test verifies that WebWidgetClient::hasTouchEventHandlers is called
1709 // accordingly for various calls to EventHandlerRegistry::did{Add|Remove|
1710 // RemoveAll}EventHandler(..., TouchEvent). Verifying that those calls are made
1711 // correctly is the job of LayoutTests/fast/events/event-handler-count.html.
1712 TEST_F(WebViewTest, HasTouchEventHandlers)
1713 {
1714     TouchEventHandlerWebViewClient client;
1715     std::string url = m_baseURL + "has_touch_event_handlers.html";
1716     URLTestHelpers::registerMockedURLLoad(toKURL(url), "has_touch_event_handlers.html");
1717     WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
1718     const blink::EventHandlerRegistry::EventHandlerClass touchEvent = blink::EventHandlerRegistry::TouchEvent;
1719
1720     // The page is initialized with at least one no-handlers call.
1721     // In practice we get two such calls because WebViewHelper::initializeAndLoad first
1722     // initializes and empty frame, and then loads a document into it, so there are two
1723     // FrameLoader::commitProvisionalLoad calls.
1724     EXPECT_GE(client.getAndResetHasTouchEventHandlerCallCount(false), 1);
1725     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1726
1727     // Adding the first document handler results in a has-handlers call.
1728     blink::Document* document = webViewImpl->mainFrameImpl()->frame()->document();
1729     blink::EventHandlerRegistry* registry = &document->frameHost()->eventHandlerRegistry();
1730     registry->didAddEventHandler(*document, touchEvent);
1731     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1732     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1733
1734     // Adding another handler has no effect.
1735     registry->didAddEventHandler(*document, touchEvent);
1736     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1737     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1738
1739     // Removing the duplicate handler has no effect.
1740     registry->didRemoveEventHandler(*document, touchEvent);
1741     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1742     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1743
1744     // Removing the final handler results in a no-handlers call.
1745     registry->didRemoveEventHandler(*document, touchEvent);
1746     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1747     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1748
1749     // Adding a handler on a div results in a has-handlers call.
1750     blink::Element* parentDiv = document->getElementById("parentdiv");
1751     ASSERT(parentDiv);
1752     registry->didAddEventHandler(*parentDiv, touchEvent);
1753     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1754     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1755
1756     // Adding a duplicate handler on the div, clearing all document handlers
1757     // (of which there are none) and removing the extra handler on the div
1758     // all have no effect.
1759     registry->didAddEventHandler(*parentDiv, touchEvent);
1760     registry->didRemoveAllEventHandlers(*document);
1761     registry->didRemoveEventHandler(*parentDiv, touchEvent);
1762     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1763     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1764
1765     // Removing the final handler on the div results in a no-handlers call.
1766     registry->didRemoveEventHandler(*parentDiv, touchEvent);
1767     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1768     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1769
1770     // Adding two handlers then clearing them in a single call results in a
1771     // has-handlers then no-handlers call.
1772     registry->didAddEventHandler(*parentDiv, touchEvent);
1773     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1774     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1775     registry->didAddEventHandler(*parentDiv, touchEvent);
1776     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1777     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1778     registry->didRemoveAllEventHandlers(*parentDiv);
1779     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1780     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1781
1782     // Adding a handler inside of a child iframe results in a has-handlers call.
1783     blink::Element* childFrame = document->getElementById("childframe");
1784     ASSERT(childFrame);
1785     blink::Document* childDocument = toHTMLIFrameElement(childFrame)->contentDocument();
1786     blink::Element* childDiv = childDocument->getElementById("childdiv");
1787     ASSERT(childDiv);
1788     registry->didAddEventHandler(*childDiv, touchEvent);
1789     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1790     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1791
1792     // Adding and clearing handlers in the parent doc or elsewhere in the child doc
1793     // has no impact.
1794     registry->didAddEventHandler(*document, touchEvent);
1795     registry->didAddEventHandler(*childFrame, touchEvent);
1796     registry->didAddEventHandler(*childDocument, touchEvent);
1797     registry->didRemoveAllEventHandlers(*document);
1798     registry->didRemoveAllEventHandlers(*childFrame);
1799     registry->didRemoveAllEventHandlers(*childDocument);
1800     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1801     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1802
1803     // Removing the final handler inside the child frame results in a no-handlers call.
1804     registry->didRemoveAllEventHandlers(*childDiv);
1805     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1806     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1807
1808     // Adding a handler inside the child frame results in a has-handlers call.
1809     registry->didAddEventHandler(*childDocument, touchEvent);
1810     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1811     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1812
1813     // Adding a handler in the parent document and removing the one in the frame
1814     // has no effect.
1815     registry->didAddEventHandler(*childFrame, touchEvent);
1816     registry->didRemoveEventHandler(*childDocument, touchEvent);
1817     registry->didRemoveAllEventHandlers(*childDocument);
1818     registry->didRemoveAllEventHandlers(*document);
1819     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1820     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1821
1822     // Now removing the handler in the parent document results in a no-handlers call.
1823     registry->didRemoveEventHandler(*childFrame, touchEvent);
1824     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1825     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1826
1827     // Free the webView before the TouchEventHandlerWebViewClient gets freed.
1828     m_webViewHelper.reset();
1829 }
1830
1831 // This test checks that deleting nodes which have only non-JS-registered touch
1832 // handlers also removes them from the event handler registry. Note that this
1833 // is different from detaching and re-attaching the same node, which is covered
1834 // by layout tests under fast/events/.
1835 TEST_F(WebViewTest, DeleteElementWithRegisteredHandler)
1836 {
1837     std::string url = m_baseURL + "simple_div.html";
1838     URLTestHelpers::registerMockedURLLoad(toKURL(url), "simple_div.html");
1839     WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true);
1840
1841     RefPtrWillBePersistent<blink::Document> document = webViewImpl->mainFrameImpl()->frame()->document();
1842     blink::Element* div = document->getElementById("div");
1843     blink::EventHandlerRegistry& registry = document->frameHost()->eventHandlerRegistry();
1844
1845     registry.didAddEventHandler(*div, blink::EventHandlerRegistry::ScrollEvent);
1846     EXPECT_TRUE(registry.hasEventHandlers(blink::EventHandlerRegistry::ScrollEvent));
1847
1848     blink::TrackExceptionState exceptionState;
1849     div->remove(exceptionState);
1850 #if ENABLE(OILPAN)
1851     // For oilpan we have to force a GC to ensure the event handlers have been removed when
1852     // checking below. We do a precise GC (collectAllGarbage does not scan the stack)
1853     // to ensure the div element dies. This is also why the Document is in a Persistent
1854     // since we want that to stay around.
1855     Heap::collectAllGarbage();
1856 #endif
1857     EXPECT_FALSE(registry.hasEventHandlers(blink::EventHandlerRegistry::ScrollEvent));
1858 }
1859
1860 static WebRect ExpectedRootBounds(blink::Document* document, float scaleFactor)
1861 {
1862     blink::Element* element = document->getElementById("root");
1863     if (!element)
1864         element = document->getElementById("target");
1865     if (element->hasTagName(blink::HTMLNames::iframeTag))
1866         return ExpectedRootBounds(toHTMLIFrameElement(element)->contentDocument(), scaleFactor);
1867
1868     blink::IntRect boundingBox;
1869     if (element->hasTagName(blink::HTMLNames::htmlTag))
1870         boundingBox = blink::IntRect(blink::IntPoint(0, 0), document->frame()->view()->contentsSize());
1871     else
1872         boundingBox = element->pixelSnappedBoundingBox();
1873     boundingBox = document->frame()->view()->contentsToWindow(boundingBox);
1874     boundingBox.scale(scaleFactor);
1875     return boundingBox;
1876 }
1877
1878 void WebViewTest::testSelectionRootBounds(const char* htmlFile, float pageScaleFactor)
1879 {
1880     std::string url = m_baseURL + htmlFile;
1881
1882     WebView* webView = m_webViewHelper.initializeAndLoad(url, true);
1883     webView->resize(WebSize(640, 480));
1884     webView->setPageScaleFactor(pageScaleFactor);
1885     webView->layout();
1886     runPendingTasks();
1887
1888     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1889     EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
1890     blink::HTMLDocument* document = blink::toHTMLDocument(frame->frame()->document());
1891
1892     WebRect expectedRootBounds = ExpectedRootBounds(document, webView->pageScaleFactor());
1893     WebRect actualRootBounds;
1894     webView->getSelectionRootBounds(actualRootBounds);
1895     ASSERT_EQ(expectedRootBounds, actualRootBounds);
1896
1897     WebRect anchor, focus;
1898     webView->selectionBounds(anchor, focus);
1899     blink::IntRect expectedIntRect = expectedRootBounds;
1900     ASSERT_TRUE(expectedIntRect.contains(anchor));
1901     // The "overflow" tests have the focus boundary outside of the element box.
1902     ASSERT_EQ(url.find("overflow") == std::string::npos, expectedIntRect.contains(focus));
1903 }
1904
1905 TEST_F(WebViewTest, GetSelectionRootBounds)
1906 {
1907     // Register all the pages we will be using.
1908     registerMockedHttpURLLoad("select_range_basic.html");
1909     registerMockedHttpURLLoad("select_range_div_editable.html");
1910     registerMockedHttpURLLoad("select_range_scroll.html");
1911     registerMockedHttpURLLoad("select_range_span_editable.html");
1912     registerMockedHttpURLLoad("select_range_input.html");
1913     registerMockedHttpURLLoad("select_range_input_overflow.html");
1914     registerMockedHttpURLLoad("select_range_textarea.html");
1915     registerMockedHttpURLLoad("select_range_textarea_overflow.html");
1916     registerMockedHttpURLLoad("select_range_iframe.html");
1917     registerMockedHttpURLLoad("select_range_iframe_div_editable.html");
1918     registerMockedHttpURLLoad("select_range_iframe_scroll.html");
1919     registerMockedHttpURLLoad("select_range_iframe_span_editable.html");
1920     registerMockedHttpURLLoad("select_range_iframe_input.html");
1921     registerMockedHttpURLLoad("select_range_iframe_input_overflow.html");
1922     registerMockedHttpURLLoad("select_range_iframe_textarea.html");
1923     registerMockedHttpURLLoad("select_range_iframe_textarea_overflow.html");
1924
1925     // Test with simple pages.
1926     testSelectionRootBounds("select_range_basic.html", 1.0f);
1927     testSelectionRootBounds("select_range_div_editable.html", 1.0f);
1928     testSelectionRootBounds("select_range_scroll.html", 1.0f);
1929     testSelectionRootBounds("select_range_span_editable.html", 1.0f);
1930     testSelectionRootBounds("select_range_input.html", 1.0f);
1931     testSelectionRootBounds("select_range_input_overflow.html", 1.0f);
1932     testSelectionRootBounds("select_range_textarea.html", 1.0f);
1933     testSelectionRootBounds("select_range_textarea_overflow.html", 1.0f);
1934
1935     // Test with the same pages as above in iframes.
1936     testSelectionRootBounds("select_range_iframe.html", 1.0f);
1937     testSelectionRootBounds("select_range_iframe_div_editable.html", 1.0f);
1938     testSelectionRootBounds("select_range_iframe_scroll.html", 1.0f);
1939     testSelectionRootBounds("select_range_iframe_span_editable.html", 1.0f);
1940     testSelectionRootBounds("select_range_iframe_input.html", 1.0f);
1941     testSelectionRootBounds("select_range_iframe_input_overflow.html", 1.0f);
1942     testSelectionRootBounds("select_range_iframe_textarea.html", 1.0f);
1943     testSelectionRootBounds("select_range_iframe_textarea_overflow.html", 1.0f);
1944
1945     // Basic page with scale factor.
1946     testSelectionRootBounds("select_range_basic.html", 0.0f);
1947     testSelectionRootBounds("select_range_basic.html", 0.1f);
1948     testSelectionRootBounds("select_range_basic.html", 1.5f);
1949     testSelectionRootBounds("select_range_basic.html", 2.0f);
1950 }
1951
1952 TEST_F(WebViewTest, GetSelectionRootBoundsBrokenHeight)
1953 {
1954     WebSize contentSize = WebSize(640, 480);
1955
1956     registerMockedHttpURLLoad("select_range_basic_broken_height.html");
1957
1958     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "select_range_basic_broken_height.html", true);
1959     webView->resize(contentSize);
1960     webView->setPageScaleFactor(1.0f, WebPoint(0, 0));
1961     webView->layout();
1962     runPendingTasks();
1963
1964     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1965     EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
1966
1967     WebRect expectedRootBounds = WebRect(0, 0, contentSize.width, contentSize.height);
1968     WebRect actualRootBounds;
1969     webView->getSelectionRootBounds(actualRootBounds);
1970     ASSERT_EQ(expectedRootBounds, actualRootBounds);
1971 }
1972
1973 class NonUserInputTextUpdateWebViewClient : public FrameTestHelpers::TestWebViewClient {
1974 public:
1975     NonUserInputTextUpdateWebViewClient() : m_textIsUpdated(false) { }
1976
1977     // WebWidgetClient methods
1978     virtual void didUpdateTextOfFocusedElementByNonUserInput() OVERRIDE
1979     {
1980         m_textIsUpdated = true;
1981     }
1982
1983     void reset()
1984     {
1985         m_textIsUpdated = false;
1986     }
1987
1988     bool textIsUpdated() const
1989     {
1990         return m_textIsUpdated;
1991     }
1992
1993 private:
1994     int m_textIsUpdated;
1995 };
1996
1997 // This test verifies that WebWidgetClient::didUpdateTextOfFocusedElementByNonUserInput is
1998 // called iff value of a focused element is modified via script.
1999 TEST_F(WebViewTest, NonUserInputTextUpdate)
2000 {
2001     NonUserInputTextUpdateWebViewClient client;
2002     std::string url = m_baseURL + "non_user_input_text_update.html";
2003     URLTestHelpers::registerMockedURLLoad(toKURL(url), "non_user_input_text_update.html");
2004     WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
2005     webViewImpl->setInitialFocus(false);
2006
2007     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewImpl->mainFrame());
2008     blink::HTMLDocument* document = blink::toHTMLDocument(frame->frame()->document());
2009
2010     // (A) <input>
2011     // (A.1) Focused and value is changed by script.
2012     client.reset();
2013     EXPECT_FALSE(client.textIsUpdated());
2014
2015     blink::HTMLInputElement* inputElement = toHTMLInputElement(document->getElementById("input"));
2016     document->setFocusedElement(inputElement);
2017     webViewImpl->setFocus(true);
2018     EXPECT_EQ(document->focusedElement(), static_cast<blink::Element*>(inputElement));
2019
2020     // Emulate value change from script.
2021     inputElement->setValue("testA");
2022     EXPECT_TRUE(client.textIsUpdated());
2023     WebTextInputInfo info = webViewImpl->textInputInfo();
2024     EXPECT_EQ("testA", std::string(info.value.utf8().data()));
2025
2026     // (A.2) Focused and user input modifies value.
2027     client.reset();
2028     EXPECT_FALSE(client.textIsUpdated());
2029
2030     WebVector<WebCompositionUnderline> emptyUnderlines;
2031     webViewImpl->setComposition(WebString::fromUTF8("2"), emptyUnderlines, 1, 1);
2032     webViewImpl->confirmComposition(WebWidget::KeepSelection);
2033     EXPECT_FALSE(client.textIsUpdated());
2034     info = webViewImpl->textInputInfo();
2035     EXPECT_EQ("testA2", std::string(info.value.utf8().data()));
2036
2037     // (A.3) Unfocused and value is changed by script.
2038     client.reset();
2039     EXPECT_FALSE(client.textIsUpdated());
2040     document->setFocusedElement(nullptr);
2041     webViewImpl->setFocus(false);
2042     EXPECT_NE(document->focusedElement(), static_cast<blink::Element*>(inputElement));
2043     inputElement->setValue("testA3");
2044     EXPECT_FALSE(client.textIsUpdated());
2045
2046     // (B) <textarea>
2047     // (B.1) Focused and value is changed by script.
2048     client.reset();
2049     EXPECT_FALSE(client.textIsUpdated());
2050     blink::HTMLTextAreaElement* textAreaElement = toHTMLTextAreaElement(document->getElementById("textarea"));
2051     document->setFocusedElement(textAreaElement);
2052     webViewImpl->setFocus(true);
2053     EXPECT_EQ(document->focusedElement(), static_cast<blink::Element*>(textAreaElement));
2054     textAreaElement->setValue("testB");
2055     EXPECT_TRUE(client.textIsUpdated());
2056     info = webViewImpl->textInputInfo();
2057     EXPECT_EQ("testB", std::string(info.value.utf8().data()));
2058
2059     // (B.2) Focused and user input modifies value.
2060     client.reset();
2061     EXPECT_FALSE(client.textIsUpdated());
2062     webViewImpl->setComposition(WebString::fromUTF8("2"), emptyUnderlines, 1, 1);
2063     webViewImpl->confirmComposition(WebWidget::KeepSelection);
2064     info = webViewImpl->textInputInfo();
2065     EXPECT_EQ("testB2", std::string(info.value.utf8().data()));
2066
2067     // (B.3) Unfocused and value is changed by script.
2068     client.reset();
2069     EXPECT_FALSE(client.textIsUpdated());
2070     document->setFocusedElement(nullptr);
2071     webViewImpl->setFocus(false);
2072     EXPECT_NE(document->focusedElement(), static_cast<blink::Element*>(textAreaElement));
2073     inputElement->setValue("testB3");
2074     EXPECT_FALSE(client.textIsUpdated());
2075
2076     // Free the webView before freeing the NonUserInputTextUpdateWebViewClient.
2077     m_webViewHelper.reset();
2078 }
2079
2080 // Check that the WebAutofillClient is correctly notified about first user
2081 // gestures after load, following various input events.
2082 TEST_F(WebViewTest, FirstUserGestureObservedKeyEvent)
2083 {
2084     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("form.html"));
2085     MockAutofillClient client;
2086     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "form.html", true);
2087     webView->setAutofillClient(&client);
2088     webView->setInitialFocus(false);
2089
2090     EXPECT_EQ(0, client.getUserGestureNotificationsCount());
2091
2092     WebKeyboardEvent keyEvent;
2093     keyEvent.windowsKeyCode = blink::VKEY_SPACE;
2094     keyEvent.type = WebInputEvent::RawKeyDown;
2095     keyEvent.setKeyIdentifierFromWindowsKeyCode();
2096     webView->handleInputEvent(keyEvent);
2097     keyEvent.type = WebInputEvent::KeyUp;
2098     webView->handleInputEvent(keyEvent);
2099
2100     EXPECT_EQ(1, client.getUserGestureNotificationsCount());
2101     webView->setAutofillClient(0);
2102 }
2103
2104 TEST_F(WebViewTest, FirstUserGestureObservedMouseEvent)
2105 {
2106     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("form.html"));
2107     MockAutofillClient client;
2108     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "form.html", true);
2109     webView->setAutofillClient(&client);
2110     webView->setInitialFocus(false);
2111
2112     EXPECT_EQ(0, client.getUserGestureNotificationsCount());
2113
2114     WebMouseEvent mouseEvent;
2115     mouseEvent.button = WebMouseEvent::ButtonLeft;
2116     mouseEvent.x = 1;
2117     mouseEvent.y = 1;
2118     mouseEvent.clickCount = 1;
2119     mouseEvent.type = WebInputEvent::MouseDown;
2120     webView->handleInputEvent(mouseEvent);
2121     mouseEvent.type = WebInputEvent::MouseUp;
2122     webView->handleInputEvent(mouseEvent);
2123
2124     EXPECT_EQ(1, client.getUserGestureNotificationsCount());
2125     webView->setAutofillClient(0);
2126 }
2127
2128 TEST_F(WebViewTest, FirstUserGestureObservedGestureTap)
2129 {
2130     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html"));
2131     MockAutofillClient client;
2132     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "longpress_selection.html", true);
2133     webView->setAutofillClient(&client);
2134     webView->setInitialFocus(false);
2135
2136     EXPECT_EQ(0, client.getUserGestureNotificationsCount());
2137
2138     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, WebString::fromUTF8("target")));
2139
2140     EXPECT_EQ(1, client.getUserGestureNotificationsCount());
2141     webView->setAutofillClient(0);
2142 }
2143
2144 TEST_F(WebViewTest, CompareSelectAllToContentAsText)
2145 {
2146     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html"));
2147     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "longpress_selection.html", true);
2148
2149     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
2150     frame->executeScript(WebScriptSource(WebString::fromUTF8("document.execCommand('SelectAll', false, null)")));
2151     std::string actual = frame->selectionAsText().utf8();
2152
2153     const int kMaxOutputCharacters = 1024;
2154     std::string expected = frame->contentAsText(kMaxOutputCharacters).utf8();
2155     EXPECT_EQ(expected, actual);
2156 }
2157
2158 } // namespace