Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "WebView.h"
     33 
     34 #include <gtest/gtest.h>
     35 #include "FrameTestHelpers.h"
     36 #include "URLTestHelpers.h"
     37 #include "WebAutofillClient.h"
     38 #include "WebContentDetectionResult.h"
     39 #include "WebDateTimeChooserCompletion.h"
     40 #include "WebDocument.h"
     41 #include "WebElement.h"
     42 #include "WebFrame.h"
     43 #include "WebFrameClient.h"
     44 #include "WebFrameImpl.h"
     45 #include "WebHelperPluginImpl.h"
     46 #include "WebHitTestResult.h"
     47 #include "WebInputEvent.h"
     48 #include "WebSettings.h"
     49 #include "WebViewClient.h"
     50 #include "WebViewImpl.h"
     51 #include "WebWidget.h"
     52 #include "core/dom/Document.h"
     53 #include "core/dom/Element.h"
     54 #include "core/html/HTMLDocument.h"
     55 #include "core/html/HTMLInputElement.h"
     56 #include "core/loader/FrameLoadRequest.h"
     57 #include "core/frame/FrameView.h"
     58 #include "core/page/Chrome.h"
     59 #include "core/frame/Settings.h"
     60 #include "platform/KeyboardCodes.h"
     61 #include "platform/graphics/Color.h"
     62 #include "public/platform/Platform.h"
     63 #include "public/platform/WebSize.h"
     64 #include "public/platform/WebThread.h"
     65 #include "public/platform/WebUnitTestSupport.h"
     66 #include "public/web/WebWidgetClient.h"
     67 #include "third_party/skia/include/core/SkBitmap.h"
     68 #include "third_party/skia/include/core/SkBitmapDevice.h"
     69 #include "third_party/skia/include/core/SkCanvas.h"
     70 
     71 using namespace blink;
     72 using blink::FrameTestHelpers::runPendingTasks;
     73 using blink::URLTestHelpers::toKURL;
     74 
     75 namespace {
     76 
     77 enum HorizontalScrollbarState {
     78     NoHorizontalScrollbar,
     79     VisibleHorizontalScrollbar,
     80 };
     81 
     82 enum VerticalScrollbarState {
     83     NoVerticalScrollbar,
     84     VisibleVerticalScrollbar,
     85 };
     86 
     87 class TestData {
     88 public:
     89     void setWebView(WebView* webView) { m_webView = toWebViewImpl(webView); }
     90     void setSize(const WebSize& newSize) { m_size = newSize; }
     91     HorizontalScrollbarState horizontalScrollbarState() const
     92     {
     93         return m_webView->hasHorizontalScrollbar() ? VisibleHorizontalScrollbar: NoHorizontalScrollbar;
     94     }
     95     VerticalScrollbarState verticalScrollbarState() const
     96     {
     97         return m_webView->hasVerticalScrollbar() ? VisibleVerticalScrollbar : NoVerticalScrollbar;
     98     }
     99     int width() const { return m_size.width; }
    100     int height() const { return m_size.height; }
    101 
    102 private:
    103     WebSize m_size;
    104     WebViewImpl* m_webView;
    105 };
    106 
    107 class AutoResizeWebViewClient : public WebViewClient {
    108 public:
    109     // WebViewClient methods
    110     virtual void didAutoResize(const WebSize& newSize) { m_testData.setSize(newSize); }
    111 
    112     // Local methods
    113     TestData& testData() { return m_testData; }
    114 
    115 private:
    116     TestData m_testData;
    117 };
    118 
    119 class TapHandlingWebViewClient : public WebViewClient {
    120 public:
    121     // WebViewClient methods
    122     virtual void didHandleGestureEvent(const WebGestureEvent& event, bool eventCancelled)
    123     {
    124         if (event.type == WebInputEvent::GestureTap) {
    125             m_tapX = event.x;
    126             m_tapY = event.y;
    127         } else if (event.type == WebInputEvent::GestureLongPress) {
    128             m_longpressX = event.x;
    129             m_longpressY = event.y;
    130         }
    131     }
    132 
    133     // Local methods
    134     void reset()
    135     {
    136         m_tapX = -1;
    137         m_tapY = -1;
    138         m_longpressX = -1;
    139         m_longpressY = -1;
    140     }
    141     int tapX() { return m_tapX; }
    142     int tapY() { return m_tapY; }
    143     int longpressX() { return m_longpressX; }
    144     int longpressY() { return m_longpressY; }
    145 
    146 private:
    147     int m_tapX;
    148     int m_tapY;
    149     int m_longpressX;
    150     int m_longpressY;
    151 };
    152 
    153 class HelperPluginCreatingWebViewClient : public WebViewClient {
    154 public:
    155     // WebViewClient methods
    156     virtual blink::WebWidget* createPopupMenu(blink::WebPopupType popupType) OVERRIDE
    157     {
    158         EXPECT_EQ(WebPopupTypeHelperPlugin, popupType);
    159         m_helperPluginWebWidget = blink::WebHelperPlugin::create(this);
    160         // The caller owns the object, but we retain a pointer for use in closeWidgetSoon().
    161         return m_helperPluginWebWidget;
    162     }
    163 
    164     virtual void initializeHelperPluginWebFrame(blink::WebHelperPlugin* plugin) OVERRIDE
    165     {
    166         ASSERT_TRUE(m_webFrameClient);
    167         plugin->initializeFrame(m_webFrameClient);
    168     }
    169 
    170     // WebWidgetClient methods
    171     virtual void closeWidgetSoon() OVERRIDE
    172     {
    173         ASSERT_TRUE(m_helperPluginWebWidget);
    174         m_helperPluginWebWidget->close();
    175         m_helperPluginWebWidget = 0;
    176     }
    177 
    178     // Local methods
    179     HelperPluginCreatingWebViewClient()
    180         :   m_helperPluginWebWidget(0)
    181         ,   m_webFrameClient(0)
    182     {
    183     }
    184 
    185     void setWebFrameClient(WebFrameClient* client) { m_webFrameClient = client; }
    186 
    187 private:
    188     WebWidget* m_helperPluginWebWidget;
    189     WebFrameClient* m_webFrameClient;
    190 };
    191 
    192 class DateTimeChooserWebViewClient : public WebViewClient {
    193 public:
    194     WebDateTimeChooserCompletion* chooserCompletion()
    195     {
    196         return m_chooserCompletion;
    197     }
    198 
    199     void clearChooserCompletion()
    200     {
    201         m_chooserCompletion = 0;
    202     }
    203 
    204     // WebViewClient methods
    205     virtual bool openDateTimeChooser(const WebDateTimeChooserParams&, WebDateTimeChooserCompletion* chooser_completion) OVERRIDE
    206     {
    207         m_chooserCompletion = chooser_completion;
    208         return true;
    209     }
    210 
    211 private:
    212     WebDateTimeChooserCompletion* m_chooserCompletion;
    213 
    214 };
    215 
    216 class WebViewTest : public testing::Test {
    217 public:
    218     WebViewTest()
    219         : m_baseURL("http://www.test.com/")
    220     {
    221     }
    222 
    223     virtual void TearDown()
    224     {
    225         Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
    226     }
    227 
    228 protected:
    229     void testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize,
    230                         const std::string& pageWidth, const std::string& pageHeight,
    231                         int expectedWidth, int expectedHeight,
    232                         HorizontalScrollbarState expectedHorizontalState, VerticalScrollbarState expectedVerticalState);
    233 
    234     void testTextInputType(WebTextInputType expectedType, const std::string& htmlFile);
    235     void testInputMode(const WebString& expectedInputMode, const std::string& htmlFile);
    236 
    237     std::string m_baseURL;
    238     FrameTestHelpers::WebViewHelper m_webViewHelper;
    239 };
    240 
    241 TEST_F(WebViewTest, SetBaseBackgroundColor)
    242 {
    243     const WebColor kWhite    = 0xFFFFFFFF;
    244     const WebColor kBlue     = 0xFF0000FF;
    245     const WebColor kDarkCyan = 0xFF227788;
    246     const WebColor kTranslucentPutty = 0x80BFB196;
    247 
    248     WebView* webView = m_webViewHelper.initialize();
    249     EXPECT_EQ(kWhite, webView->backgroundColor());
    250 
    251     webView->setBaseBackgroundColor(kBlue);
    252     EXPECT_EQ(kBlue, webView->backgroundColor());
    253 
    254     WebURL baseURL = URLTestHelpers::toKURL("http://example.com/");
    255     webView->mainFrame()->loadHTMLString(
    256         "<html><head><style>body {background-color:#227788}</style></head></html>", baseURL);
    257     Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
    258     EXPECT_EQ(kDarkCyan, webView->backgroundColor());
    259 
    260     webView->mainFrame()->loadHTMLString(
    261         "<html><head><style>body {background-color:rgba(255,0,0,0.5)}</style></head></html>", baseURL);
    262     Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
    263     // Expected: red (50% alpha) blended atop base of kBlue.
    264     EXPECT_EQ(0xFF7F0080, webView->backgroundColor());
    265 
    266     webView->setBaseBackgroundColor(kTranslucentPutty);
    267     // Expected: red (50% alpha) blended atop kTranslucentPutty. Note the alpha.
    268     EXPECT_EQ(0xBFE93B32, webView->backgroundColor());
    269 }
    270 
    271 TEST_F(WebViewTest, SetBaseBackgroundColorBeforeMainFrame)
    272 {
    273     const WebColor kBlue = 0xFF0000FF;
    274     WebView* webView = WebViewImpl::create(0);
    275     EXPECT_NE(kBlue, webView->backgroundColor());
    276     // webView does not have a frame yet, but we should still be able to set the background color.
    277     webView->setBaseBackgroundColor(kBlue);
    278     EXPECT_EQ(kBlue, webView->backgroundColor());
    279 }
    280 
    281 TEST_F(WebViewTest, SetBaseBackgroundColorAndBlendWithExistingContent)
    282 {
    283     const WebColor kAlphaRed = 0x80FF0000;
    284     const WebColor kAlphaGreen = 0x8000FF00;
    285     const int kWidth = 100;
    286     const int kHeight = 100;
    287 
    288     // Set WebView background to green with alpha.
    289     WebView* webView = m_webViewHelper.initialize();
    290     webView->setBaseBackgroundColor(kAlphaGreen);
    291     webView->settings()->setShouldClearDocumentBackground(false);
    292     webView->resize(WebSize(kWidth, kHeight));
    293     webView->layout();
    294 
    295     // Set canvas background to red with alpha.
    296     SkBitmap bitmap;
    297     bitmap.setConfig(SkBitmap::kARGB_8888_Config, kWidth, kHeight);
    298     bitmap.allocPixels();
    299     SkBitmapDevice device(bitmap);
    300     SkCanvas canvas(&device);
    301     canvas.clear(kAlphaRed);
    302     webView->paint(&canvas, WebRect(0, 0, kWidth, kHeight));
    303 
    304     // The result should be a blend of red and green.
    305     SkColor color = bitmap.getColor(kWidth / 2, kHeight / 2);
    306     EXPECT_TRUE(WebCore::redChannel(color));
    307     EXPECT_TRUE(WebCore::greenChannel(color));
    308 }
    309 
    310 TEST_F(WebViewTest, FocusIsInactive)
    311 {
    312     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "visible_iframe.html");
    313     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "visible_iframe.html");
    314 
    315     webView->setFocus(true);
    316     webView->setIsActive(true);
    317     WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
    318     EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
    319 
    320     WebCore::HTMLDocument* document = WebCore::toHTMLDocument(frame->frame()->document());
    321     EXPECT_TRUE(document->hasFocus());
    322     webView->setFocus(false);
    323     webView->setIsActive(false);
    324     EXPECT_FALSE(document->hasFocus());
    325     webView->setFocus(true);
    326     webView->setIsActive(true);
    327     EXPECT_TRUE(document->hasFocus());
    328     webView->setFocus(true);
    329     webView->setIsActive(false);
    330     EXPECT_FALSE(document->hasFocus());
    331     webView->setFocus(false);
    332     webView->setIsActive(true);
    333     EXPECT_FALSE(document->hasFocus());
    334 }
    335 
    336 TEST_F(WebViewTest, ActiveState)
    337 {
    338     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "visible_iframe.html");
    339     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "visible_iframe.html");
    340 
    341     ASSERT_TRUE(webView);
    342 
    343     webView->setIsActive(true);
    344     EXPECT_TRUE(webView->isActive());
    345 
    346     webView->setIsActive(false);
    347     EXPECT_FALSE(webView->isActive());
    348 
    349     webView->setIsActive(true);
    350     EXPECT_TRUE(webView->isActive());
    351 }
    352 
    353 TEST_F(WebViewTest, HitTestResultAtWithPageScale)
    354 {
    355     std::string url = m_baseURL + "specify_size.html?" + "50px" + ":" + "50px";
    356     URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html");
    357     WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0);
    358     webView->resize(WebSize(100, 100));
    359     WebPoint hitPoint(75, 75);
    360 
    361     // Image is at top left quandrant, so should not hit it.
    362     WebHitTestResult negativeResult = webView->hitTestResultAt(hitPoint);
    363     ASSERT_EQ(WebNode::ElementNode, negativeResult.node().nodeType());
    364     EXPECT_FALSE(negativeResult.node().to<WebElement>().hasTagName("img"));
    365     negativeResult.reset();
    366 
    367     // Scale page up 2x so image should occupy the whole viewport.
    368     webView->setPageScaleFactor(2.0f, WebPoint(0, 0));
    369     WebHitTestResult positiveResult = webView->hitTestResultAt(hitPoint);
    370     ASSERT_EQ(WebNode::ElementNode, positiveResult.node().nodeType());
    371     EXPECT_TRUE(positiveResult.node().to<WebElement>().hasTagName("img"));
    372     positiveResult.reset();
    373 }
    374 
    375 void WebViewTest::testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize,
    376                                  const std::string& pageWidth, const std::string& pageHeight,
    377                                  int expectedWidth, int expectedHeight,
    378                                  HorizontalScrollbarState expectedHorizontalState, VerticalScrollbarState expectedVerticalState)
    379 {
    380     AutoResizeWebViewClient client;
    381     std::string url = m_baseURL + "specify_size.html?" + pageWidth + ":" + pageHeight;
    382     URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html");
    383     WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
    384     client.testData().setWebView(webView);
    385 
    386     WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
    387     WebCore::FrameView* frameView = frame->frame()->view();
    388     frameView->layout();
    389     EXPECT_FALSE(frameView->layoutPending());
    390     EXPECT_FALSE(frameView->needsLayout());
    391 
    392     webView->enableAutoResizeMode(minAutoResize, maxAutoResize);
    393     EXPECT_TRUE(frameView->layoutPending());
    394     EXPECT_TRUE(frameView->needsLayout());
    395     frameView->layout();
    396 
    397     EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
    398 
    399     EXPECT_EQ(expectedWidth, client.testData().width());
    400     EXPECT_EQ(expectedHeight, client.testData().height());
    401     EXPECT_EQ(expectedHorizontalState, client.testData().horizontalScrollbarState());
    402     EXPECT_EQ(expectedVerticalState, client.testData().verticalScrollbarState());
    403 
    404     m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
    405 }
    406 
    407 TEST_F(WebViewTest, DISABLED_AutoResizeMinimumSize)
    408 {
    409     WebSize minAutoResize(91, 56);
    410     WebSize maxAutoResize(403, 302);
    411     std::string pageWidth = "91px";
    412     std::string pageHeight = "56px";
    413     int expectedWidth = 91;
    414     int expectedHeight = 56;
    415     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
    416                    expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
    417 }
    418 
    419 TEST_F(WebViewTest, AutoResizeHeightOverflowAndFixedWidth)
    420 {
    421     WebSize minAutoResize(90, 95);
    422     WebSize maxAutoResize(90, 100);
    423     std::string pageWidth = "60px";
    424     std::string pageHeight = "200px";
    425     int expectedWidth = 90;
    426     int expectedHeight = 100;
    427     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
    428                    expectedWidth, expectedHeight, NoHorizontalScrollbar, VisibleVerticalScrollbar);
    429 }
    430 
    431 TEST_F(WebViewTest, AutoResizeFixedHeightAndWidthOverflow)
    432 {
    433     WebSize minAutoResize(90, 100);
    434     WebSize maxAutoResize(200, 100);
    435     std::string pageWidth = "300px";
    436     std::string pageHeight = "80px";
    437     int expectedWidth = 200;
    438     int expectedHeight = 100;
    439     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
    440                    expectedWidth, expectedHeight, VisibleHorizontalScrollbar, NoVerticalScrollbar);
    441 }
    442 
    443 // Next three tests disabled for https://bugs.webkit.org/show_bug.cgi?id=92318 .
    444 // It seems we can run three AutoResize tests, then the next one breaks.
    445 TEST_F(WebViewTest, DISABLED_AutoResizeInBetweenSizes)
    446 {
    447     WebSize minAutoResize(90, 95);
    448     WebSize maxAutoResize(200, 300);
    449     std::string pageWidth = "100px";
    450     std::string pageHeight = "200px";
    451     int expectedWidth = 100;
    452     int expectedHeight = 200;
    453     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
    454                    expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
    455 }
    456 
    457 TEST_F(WebViewTest, DISABLED_AutoResizeOverflowSizes)
    458 {
    459     WebSize minAutoResize(90, 95);
    460     WebSize maxAutoResize(200, 300);
    461     std::string pageWidth = "300px";
    462     std::string pageHeight = "400px";
    463     int expectedWidth = 200;
    464     int expectedHeight = 300;
    465     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
    466                    expectedWidth, expectedHeight, VisibleHorizontalScrollbar, VisibleVerticalScrollbar);
    467 }
    468 
    469 TEST_F(WebViewTest, DISABLED_AutoResizeMaxSize)
    470 {
    471     WebSize minAutoResize(90, 95);
    472     WebSize maxAutoResize(200, 300);
    473     std::string pageWidth = "200px";
    474     std::string pageHeight = "300px";
    475     int expectedWidth = 200;
    476     int expectedHeight = 300;
    477     testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
    478                    expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
    479 }
    480 
    481 void WebViewTest::testTextInputType(WebTextInputType expectedType, const std::string& htmlFile)
    482 {
    483     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(htmlFile.c_str()));
    484     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + htmlFile);
    485     webView->setInitialFocus(false);
    486     EXPECT_EQ(expectedType, webView->textInputInfo().type);
    487 }
    488 
    489 TEST_F(WebViewTest, TextInputType)
    490 {
    491     testTextInputType(WebTextInputTypeText, "input_field_default.html");
    492     testTextInputType(WebTextInputTypePassword, "input_field_password.html");
    493     testTextInputType(WebTextInputTypeEmail, "input_field_email.html");
    494     testTextInputType(WebTextInputTypeSearch, "input_field_search.html");
    495     testTextInputType(WebTextInputTypeNumber, "input_field_number.html");
    496     testTextInputType(WebTextInputTypeTelephone, "input_field_tel.html");
    497     testTextInputType(WebTextInputTypeURL, "input_field_url.html");
    498 }
    499 
    500 void WebViewTest::testInputMode(const WebString& expectedInputMode, const std::string& htmlFile)
    501 {
    502     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(htmlFile.c_str()));
    503     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + htmlFile);
    504     webView->setInitialFocus(false);
    505     EXPECT_EQ(expectedInputMode, webView->textInputInfo().inputMode);
    506 }
    507 
    508 TEST_F(WebViewTest, InputMode)
    509 {
    510     testInputMode(WebString(), "input_mode_default.html");
    511     testInputMode(WebString("unknown"), "input_mode_default_unknown.html");
    512     testInputMode(WebString("verbatim"), "input_mode_default_verbatim.html");
    513     testInputMode(WebString("verbatim"), "input_mode_type_text_verbatim.html");
    514     testInputMode(WebString("verbatim"), "input_mode_type_search_verbatim.html");
    515     testInputMode(WebString(), "input_mode_type_url_verbatim.html");
    516     testInputMode(WebString("verbatim"), "input_mode_textarea_verbatim.html");
    517 }
    518 
    519 TEST_F(WebViewTest, SetEditableSelectionOffsetsAndTextInputInfo)
    520 {
    521     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
    522     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
    523     webView->setInitialFocus(false);
    524     webView->setEditableSelectionOffsets(5, 13);
    525     WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
    526     EXPECT_EQ("56789abc", frame->selectionAsText());
    527     WebTextInputInfo info = webView->textInputInfo();
    528     EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value);
    529     EXPECT_EQ(5, info.selectionStart);
    530     EXPECT_EQ(13, info.selectionEnd);
    531     EXPECT_EQ(-1, info.compositionStart);
    532     EXPECT_EQ(-1, info.compositionEnd);
    533 
    534     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_editable_populated.html"));
    535     webView = m_webViewHelper.initializeAndLoad(m_baseURL + "content_editable_populated.html");
    536     webView->setInitialFocus(false);
    537     webView->setEditableSelectionOffsets(8, 19);
    538     frame = toWebFrameImpl(webView->mainFrame());
    539     EXPECT_EQ("89abcdefghi", frame->selectionAsText());
    540     info = webView->textInputInfo();
    541     EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value);
    542     EXPECT_EQ(8, info.selectionStart);
    543     EXPECT_EQ(19, info.selectionEnd);
    544     EXPECT_EQ(-1, info.compositionStart);
    545     EXPECT_EQ(-1, info.compositionEnd);
    546 }
    547 
    548 TEST_F(WebViewTest, ConfirmCompositionCursorPositionChange)
    549 {
    550     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
    551     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
    552     webView->setInitialFocus(false);
    553 
    554     // Set up a composition that needs to be committed.
    555     std::string compositionText("hello");
    556 
    557     WebVector<WebCompositionUnderline> emptyUnderlines;
    558     webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 3, 3);
    559 
    560     WebTextInputInfo info = webView->textInputInfo();
    561     EXPECT_EQ("hello", std::string(info.value.utf8().data()));
    562     EXPECT_EQ(3, info.selectionStart);
    563     EXPECT_EQ(3, info.selectionEnd);
    564     EXPECT_EQ(0, info.compositionStart);
    565     EXPECT_EQ(5, info.compositionEnd);
    566 
    567     webView->confirmComposition(WebWidget::KeepSelection);
    568     info = webView->textInputInfo();
    569     EXPECT_EQ(3, info.selectionStart);
    570     EXPECT_EQ(3, info.selectionEnd);
    571     EXPECT_EQ(-1, info.compositionStart);
    572     EXPECT_EQ(-1, info.compositionEnd);
    573 
    574     webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 3, 3);
    575     info = webView->textInputInfo();
    576     EXPECT_EQ("helhellolo", std::string(info.value.utf8().data()));
    577     EXPECT_EQ(6, info.selectionStart);
    578     EXPECT_EQ(6, info.selectionEnd);
    579     EXPECT_EQ(3, info.compositionStart);
    580     EXPECT_EQ(8, info.compositionEnd);
    581 
    582     webView->confirmComposition(WebWidget::DoNotKeepSelection);
    583     info = webView->textInputInfo();
    584     EXPECT_EQ(8, info.selectionStart);
    585     EXPECT_EQ(8, info.selectionEnd);
    586     EXPECT_EQ(-1, info.compositionStart);
    587     EXPECT_EQ(-1, info.compositionEnd);
    588 }
    589 
    590 TEST_F(WebViewTest, InsertNewLinePlacementAfterConfirmComposition)
    591 {
    592     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("text_area_populated.html"));
    593     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "text_area_populated.html");
    594     webView->setInitialFocus(false);
    595 
    596     WebVector<WebCompositionUnderline> emptyUnderlines;
    597 
    598     webView->setEditableSelectionOffsets(4, 4);
    599     webView->setCompositionFromExistingText(8, 12, emptyUnderlines);
    600 
    601     WebTextInputInfo info = webView->textInputInfo();
    602     EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
    603     EXPECT_EQ(4, info.selectionStart);
    604     EXPECT_EQ(4, info.selectionEnd);
    605     EXPECT_EQ(8, info.compositionStart);
    606     EXPECT_EQ(12, info.compositionEnd);
    607 
    608     webView->confirmComposition(WebWidget::KeepSelection);
    609     info = webView->textInputInfo();
    610     EXPECT_EQ(4, info.selectionStart);
    611     EXPECT_EQ(4, info.selectionEnd);
    612     EXPECT_EQ(-1, info.compositionStart);
    613     EXPECT_EQ(-1, info.compositionEnd);
    614 
    615     std::string compositionText("\n");
    616     webView->confirmComposition(WebString::fromUTF8(compositionText.c_str()));
    617     info = webView->textInputInfo();
    618     EXPECT_EQ(5, info.selectionStart);
    619     EXPECT_EQ(5, info.selectionEnd);
    620     EXPECT_EQ(-1, info.compositionStart);
    621     EXPECT_EQ(-1, info.compositionEnd);
    622     EXPECT_EQ("0123\n456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
    623 }
    624 
    625 TEST_F(WebViewTest, ExtendSelectionAndDelete)
    626 {
    627     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
    628     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
    629     webView->setInitialFocus(false);
    630     webView->setEditableSelectionOffsets(10, 10);
    631     webView->extendSelectionAndDelete(5, 8);
    632     WebTextInputInfo info = webView->textInputInfo();
    633     EXPECT_EQ("01234ijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
    634     EXPECT_EQ(5, info.selectionStart);
    635     EXPECT_EQ(5, info.selectionEnd);
    636     webView->extendSelectionAndDelete(10, 0);
    637     info = webView->textInputInfo();
    638     EXPECT_EQ("ijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
    639 }
    640 
    641 TEST_F(WebViewTest, SetCompositionFromExistingText)
    642 {
    643     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
    644     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
    645     webView->setInitialFocus(false);
    646     WebVector<WebCompositionUnderline> underlines(static_cast<size_t>(1));
    647     underlines[0] = blink::WebCompositionUnderline(0, 4, 0, false);
    648     webView->setEditableSelectionOffsets(4, 10);
    649     webView->setCompositionFromExistingText(8, 12, underlines);
    650     WebVector<WebCompositionUnderline> underlineResults = toWebViewImpl(webView)->compositionUnderlines();
    651     EXPECT_EQ(8u, underlineResults[0].startOffset);
    652     EXPECT_EQ(12u, underlineResults[0].endOffset);
    653     WebTextInputInfo info = webView->textInputInfo();
    654     EXPECT_EQ(4, info.selectionStart);
    655     EXPECT_EQ(10, info.selectionEnd);
    656     EXPECT_EQ(8, info.compositionStart);
    657     EXPECT_EQ(12, info.compositionEnd);
    658     WebVector<WebCompositionUnderline> emptyUnderlines;
    659     webView->setCompositionFromExistingText(0, 0, emptyUnderlines);
    660     info = webView->textInputInfo();
    661     EXPECT_EQ(4, info.selectionStart);
    662     EXPECT_EQ(10, info.selectionEnd);
    663     EXPECT_EQ(-1, info.compositionStart);
    664     EXPECT_EQ(-1, info.compositionEnd);
    665 }
    666 
    667 TEST_F(WebViewTest, SetCompositionFromExistingTextInTextArea)
    668 {
    669     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("text_area_populated.html"));
    670     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "text_area_populated.html");
    671     webView->setInitialFocus(false);
    672     WebVector<WebCompositionUnderline> underlines(static_cast<size_t>(1));
    673     underlines[0] = blink::WebCompositionUnderline(0, 4, 0, false);
    674     webView->setEditableSelectionOffsets(27, 27);
    675     std::string newLineText("\n");
    676     webView->confirmComposition(WebString::fromUTF8(newLineText.c_str()));
    677     WebTextInputInfo info = webView->textInputInfo();
    678     EXPECT_EQ("0123456789abcdefghijklmnopq\nrstuvwxyz", std::string(info.value.utf8().data()));
    679 
    680     webView->setEditableSelectionOffsets(31, 31);
    681     webView->setCompositionFromExistingText(30, 34, underlines);
    682     WebVector<WebCompositionUnderline> underlineResults = toWebViewImpl(webView)->compositionUnderlines();
    683     EXPECT_EQ(2u, underlineResults[0].startOffset);
    684     EXPECT_EQ(6u, underlineResults[0].endOffset);
    685     info = webView->textInputInfo();
    686     EXPECT_EQ("0123456789abcdefghijklmnopq\nrstuvwxyz", std::string(info.value.utf8().data()));
    687     EXPECT_EQ(31, info.selectionStart);
    688     EXPECT_EQ(31, info.selectionEnd);
    689     EXPECT_EQ(30, info.compositionStart);
    690     EXPECT_EQ(34, info.compositionEnd);
    691 
    692     std::string compositionText("yolo");
    693     webView->confirmComposition(WebString::fromUTF8(compositionText.c_str()));
    694     info = webView->textInputInfo();
    695     EXPECT_EQ("0123456789abcdefghijklmnopq\nrsyoloxyz", std::string(info.value.utf8().data()));
    696     EXPECT_EQ(34, info.selectionStart);
    697     EXPECT_EQ(34, info.selectionEnd);
    698     EXPECT_EQ(-1, info.compositionStart);
    699     EXPECT_EQ(-1, info.compositionEnd);
    700 }
    701 
    702 TEST_F(WebViewTest, SetEditableSelectionOffsetsKeepsComposition)
    703 {
    704     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
    705     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
    706     webView->setInitialFocus(false);
    707 
    708     std::string compositionTextFirst("hello ");
    709     std::string compositionTextSecond("world");
    710     WebVector<WebCompositionUnderline> emptyUnderlines;
    711 
    712     webView->confirmComposition(WebString::fromUTF8(compositionTextFirst.c_str()));
    713     webView->setComposition(WebString::fromUTF8(compositionTextSecond.c_str()), emptyUnderlines, 5, 5);
    714 
    715     WebTextInputInfo info = webView->textInputInfo();
    716     EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
    717     EXPECT_EQ(11, info.selectionStart);
    718     EXPECT_EQ(11, info.selectionEnd);
    719     EXPECT_EQ(6, info.compositionStart);
    720     EXPECT_EQ(11, info.compositionEnd);
    721 
    722     webView->setEditableSelectionOffsets(6, 6);
    723     info = webView->textInputInfo();
    724     EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
    725     EXPECT_EQ(6, info.selectionStart);
    726     EXPECT_EQ(6, info.selectionEnd);
    727     EXPECT_EQ(6, info.compositionStart);
    728     EXPECT_EQ(11, info.compositionEnd);
    729 
    730     webView->setEditableSelectionOffsets(8, 8);
    731     info = webView->textInputInfo();
    732     EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
    733     EXPECT_EQ(8, info.selectionStart);
    734     EXPECT_EQ(8, info.selectionEnd);
    735     EXPECT_EQ(6, info.compositionStart);
    736     EXPECT_EQ(11, info.compositionEnd);
    737 
    738     webView->setEditableSelectionOffsets(11, 11);
    739     info = webView->textInputInfo();
    740     EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
    741     EXPECT_EQ(11, info.selectionStart);
    742     EXPECT_EQ(11, info.selectionEnd);
    743     EXPECT_EQ(6, info.compositionStart);
    744     EXPECT_EQ(11, info.compositionEnd);
    745 
    746     webView->setEditableSelectionOffsets(6, 11);
    747     info = webView->textInputInfo();
    748     EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
    749     EXPECT_EQ(6, info.selectionStart);
    750     EXPECT_EQ(11, info.selectionEnd);
    751     EXPECT_EQ(6, info.compositionStart);
    752     EXPECT_EQ(11, info.compositionEnd);
    753 
    754     webView->setEditableSelectionOffsets(2, 2);
    755     info = webView->textInputInfo();
    756     EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
    757     EXPECT_EQ(2, info.selectionStart);
    758     EXPECT_EQ(2, info.selectionEnd);
    759     EXPECT_EQ(-1, info.compositionStart);
    760     EXPECT_EQ(-1, info.compositionEnd);
    761 }
    762 
    763 TEST_F(WebViewTest, IsSelectionAnchorFirst)
    764 {
    765     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
    766     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
    767     WebFrame* frame = webView->mainFrame();
    768 
    769     webView->setInitialFocus(false);
    770     webView->setEditableSelectionOffsets(4, 10);
    771     EXPECT_TRUE(webView->isSelectionAnchorFirst());
    772     WebRect anchor;
    773     WebRect focus;
    774     webView->selectionBounds(anchor, focus);
    775     frame->selectRange(WebPoint(focus.x, focus.y), WebPoint(anchor.x, anchor.y));
    776     EXPECT_FALSE(webView->isSelectionAnchorFirst());
    777 }
    778 
    779 TEST_F(WebViewTest, HistoryResetScrollAndScaleState)
    780 {
    781     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("hello_world.html"));
    782     WebViewImpl* webViewImpl = toWebViewImpl(m_webViewHelper.initializeAndLoad(m_baseURL + "hello_world.html"));
    783     webViewImpl->resize(WebSize(640, 480));
    784     webViewImpl->layout();
    785     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
    786     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
    787 
    788     // Make the page scale and scroll with the given paremeters.
    789     webViewImpl->setPageScaleFactor(2.0f, WebPoint(116, 84));
    790     EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
    791     EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
    792     EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
    793     webViewImpl->page()->mainFrame()->loader().saveDocumentAndScrollState();
    794 
    795     // Confirm that restoring the page state restores the parameters.
    796     webViewImpl->setPageScaleFactor(1.5f, WebPoint(16, 24));
    797     EXPECT_EQ(1.5f, webViewImpl->pageScaleFactor());
    798     EXPECT_EQ(16, webViewImpl->mainFrame()->scrollOffset().width);
    799     EXPECT_EQ(24, webViewImpl->mainFrame()->scrollOffset().height);
    800     // WebViewImpl::setPageScaleFactor is performing user scrolls, which will set the
    801     // wasScrolledByUser flag on the main frame, and prevent restoreScrollPositionAndViewState
    802     // from restoring the scrolling position.
    803     webViewImpl->page()->mainFrame()->view()->setWasScrolledByUser(false);
    804     webViewImpl->page()->mainFrame()->loader().setLoadType(WebCore::FrameLoadTypeBackForward);
    805     webViewImpl->page()->mainFrame()->loader().restoreScrollPositionAndViewState();
    806     EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
    807     EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
    808     EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
    809     webViewImpl->page()->mainFrame()->loader().saveDocumentAndScrollState();
    810 
    811     // Confirm that resetting the page state resets the saved scroll position.
    812     // The HistoryController treats a page scale factor of 0.0f as special and avoids
    813     // restoring it to the WebView.
    814     webViewImpl->resetScrollAndScaleState();
    815     EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
    816     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
    817     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
    818     webViewImpl->page()->mainFrame()->loader().restoreScrollPositionAndViewState();
    819     EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
    820     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
    821     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
    822 }
    823 
    824 class EnterFullscreenWebViewClient : public WebViewClient {
    825 public:
    826     // WebViewClient methods
    827     virtual bool enterFullScreen() { return true; }
    828     virtual void exitFullScreen() { }
    829 };
    830 
    831 
    832 TEST_F(WebViewTest, EnterFullscreenResetScrollAndScaleState)
    833 {
    834     EnterFullscreenWebViewClient client;
    835     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("hello_world.html"));
    836     WebViewImpl* webViewImpl = toWebViewImpl(m_webViewHelper.initializeAndLoad(m_baseURL + "hello_world.html", true, 0, &client));
    837     webViewImpl->settings()->setFullScreenEnabled(true);
    838     webViewImpl->resize(WebSize(640, 480));
    839     webViewImpl->layout();
    840     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
    841     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
    842 
    843     // Make the page scale and scroll with the given paremeters.
    844     webViewImpl->setPageScaleFactor(2.0f, WebPoint(116, 84));
    845     EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
    846     EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
    847     EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
    848 
    849     RefPtr<WebCore::Element> element = static_cast<PassRefPtr<WebCore::Element> >(webViewImpl->mainFrame()->document().body());
    850     webViewImpl->enterFullScreenForElement(element.get());
    851     webViewImpl->willEnterFullScreen();
    852     webViewImpl->didEnterFullScreen();
    853 
    854     // Page scale factor must be 1.0 during fullscreen for elements to be sized
    855     // properly.
    856     EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
    857 
    858     // Make sure fullscreen nesting doesn't disrupt scroll/scale saving.
    859     RefPtr<WebCore::Element> otherElement = static_cast<PassRefPtr<WebCore::Element> >(webViewImpl->mainFrame()->document().head());
    860     webViewImpl->enterFullScreenForElement(otherElement.get());
    861 
    862     // Confirm that exiting fullscreen restores the parameters.
    863     webViewImpl->willExitFullScreen();
    864     webViewImpl->didExitFullScreen();
    865     EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
    866     EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
    867     EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
    868 
    869     m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
    870 }
    871 
    872 class ContentDetectorClient : public WebViewClient {
    873 public:
    874     ContentDetectorClient() { reset(); }
    875 
    876     virtual WebContentDetectionResult detectContentAround(const WebHitTestResult& hitTest) OVERRIDE
    877     {
    878         m_contentDetectionRequested = true;
    879         return m_contentDetectionResult;
    880     }
    881 
    882     virtual void scheduleContentIntent(const WebURL& url) OVERRIDE
    883     {
    884         m_scheduledIntentURL = url;
    885     }
    886 
    887     virtual void cancelScheduledContentIntents() OVERRIDE
    888     {
    889         m_pendingIntentsCancelled = true;
    890     }
    891 
    892     void reset()
    893     {
    894         m_contentDetectionRequested = false;
    895         m_pendingIntentsCancelled = false;
    896         m_scheduledIntentURL = WebURL();
    897         m_contentDetectionResult = WebContentDetectionResult();
    898     }
    899 
    900     bool contentDetectionRequested() const { return m_contentDetectionRequested; }
    901     bool pendingIntentsCancelled() const { return m_pendingIntentsCancelled; }
    902     const WebURL& scheduledIntentURL() const { return m_scheduledIntentURL; }
    903     void setContentDetectionResult(const WebContentDetectionResult& result) { m_contentDetectionResult = result; }
    904 
    905 private:
    906     bool m_contentDetectionRequested;
    907     bool m_pendingIntentsCancelled;
    908     WebURL m_scheduledIntentURL;
    909     WebContentDetectionResult m_contentDetectionResult;
    910 };
    911 
    912 static bool tapElementById(WebView* webView, WebInputEvent::Type type, const WebString& id)
    913 {
    914     ASSERT(webView);
    915     RefPtr<WebCore::Element> element = static_cast<PassRefPtr<WebCore::Element> >(webView->mainFrame()->document().getElementById(id));
    916     if (!element)
    917         return false;
    918 
    919     element->scrollIntoViewIfNeeded();
    920     WebCore::IntPoint center = element->screenRect().center();
    921 
    922     WebGestureEvent event;
    923     event.type = type;
    924     event.x = center.x();
    925     event.y = center.y();
    926 
    927     webView->handleInputEvent(event);
    928     runPendingTasks();
    929     return true;
    930 }
    931 
    932 TEST_F(WebViewTest, DetectContentAroundPosition)
    933 {
    934     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_listeners.html"));
    935 
    936     ContentDetectorClient client;
    937     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "content_listeners.html", true, 0, &client);
    938     webView->resize(WebSize(500, 300));
    939     webView->layout();
    940     runPendingTasks();
    941 
    942     WebString clickListener = WebString::fromUTF8("clickListener");
    943     WebString touchstartListener = WebString::fromUTF8("touchstartListener");
    944     WebString mousedownListener = WebString::fromUTF8("mousedownListener");
    945     WebString noListener = WebString::fromUTF8("noListener");
    946     WebString link = WebString::fromUTF8("link");
    947 
    948     // Ensure content detection is not requested for nodes listening to click,
    949     // mouse or touch events when we do simple taps.
    950     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, clickListener));
    951     EXPECT_FALSE(client.contentDetectionRequested());
    952     client.reset();
    953 
    954     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, touchstartListener));
    955     EXPECT_FALSE(client.contentDetectionRequested());
    956     client.reset();
    957 
    958     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, mousedownListener));
    959     EXPECT_FALSE(client.contentDetectionRequested());
    960     client.reset();
    961 
    962     // Content detection should work normally without these event listeners.
    963     // The click listener in the body should be ignored as a special case.
    964     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, noListener));
    965     EXPECT_TRUE(client.contentDetectionRequested());
    966     EXPECT_FALSE(client.scheduledIntentURL().isValid());
    967 
    968     WebURL intentURL = toKURL(m_baseURL);
    969     client.setContentDetectionResult(WebContentDetectionResult(WebRange(), WebString(), intentURL));
    970     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, noListener));
    971     EXPECT_TRUE(client.scheduledIntentURL() == intentURL);
    972 
    973     // Tapping elsewhere should cancel the scheduled intent.
    974     WebGestureEvent event;
    975     event.type = WebInputEvent::GestureTap;
    976     webView->handleInputEvent(event);
    977     runPendingTasks();
    978     EXPECT_TRUE(client.pendingIntentsCancelled());
    979 }
    980 
    981 TEST_F(WebViewTest, ClientTapHandling)
    982 {
    983     TapHandlingWebViewClient client;
    984     client.reset();
    985     WebView* webView = m_webViewHelper.initializeAndLoad("about:blank", true, 0, &client);
    986     WebGestureEvent event;
    987     event.type = WebInputEvent::GestureTap;
    988     event.x = 3;
    989     event.y = 8;
    990     webView->handleInputEvent(event);
    991     runPendingTasks();
    992     EXPECT_EQ(3, client.tapX());
    993     EXPECT_EQ(8, client.tapY());
    994     client.reset();
    995     event.type = WebInputEvent::GestureLongPress;
    996     event.x = 25;
    997     event.y = 7;
    998     webView->handleInputEvent(event);
    999     runPendingTasks();
   1000     EXPECT_EQ(25, client.longpressX());
   1001     EXPECT_EQ(7, client.longpressY());
   1002 
   1003     m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
   1004 }
   1005 
   1006 #if OS(ANDROID)
   1007 TEST_F(WebViewTest, LongPressSelection)
   1008 {
   1009     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html"));
   1010 
   1011     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "longpress_selection.html", true);
   1012     webView->resize(WebSize(500, 300));
   1013     webView->layout();
   1014     runPendingTasks();
   1015 
   1016     WebString target = WebString::fromUTF8("target");
   1017     WebString onselectstartfalse = WebString::fromUTF8("onselectstartfalse");
   1018     WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
   1019 
   1020     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, onselectstartfalse));
   1021     EXPECT_EQ("", std::string(frame->selectionAsText().utf8().data()));
   1022     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, target));
   1023     EXPECT_EQ("testword", std::string(frame->selectionAsText().utf8().data()));
   1024 }
   1025 #endif
   1026 
   1027 TEST_F(WebViewTest, SelectionOnDisabledInput)
   1028 {
   1029     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("selection_disabled.html"));
   1030     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "selection_disabled.html", true);
   1031     webView->resize(WebSize(640, 480));
   1032     webView->layout();
   1033     runPendingTasks();
   1034 
   1035     std::string testWord = "This text should be selected.";
   1036 
   1037     WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
   1038     EXPECT_EQ(testWord, std::string(frame->selectionAsText().utf8().data()));
   1039 
   1040     size_t location;
   1041     size_t length;
   1042     EXPECT_TRUE(toWebViewImpl(webView)->caretOrSelectionRange(&location, &length));
   1043     EXPECT_EQ(location, 0UL);
   1044     EXPECT_EQ(length, testWord.length());
   1045 }
   1046 
   1047 TEST_F(WebViewTest, SelectionOnReadOnlyInput)
   1048 {
   1049     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("selection_readonly.html"));
   1050     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "selection_readonly.html", true);
   1051     webView->resize(WebSize(640, 480));
   1052     webView->layout();
   1053     runPendingTasks();
   1054 
   1055     std::string testWord = "This text should be selected.";
   1056 
   1057     WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
   1058     EXPECT_EQ(testWord, std::string(frame->selectionAsText().utf8().data()));
   1059 
   1060     size_t location;
   1061     size_t length;
   1062     EXPECT_TRUE(toWebViewImpl(webView)->caretOrSelectionRange(&location, &length));
   1063     EXPECT_EQ(location, 0UL);
   1064     EXPECT_EQ(length, testWord.length());
   1065 }
   1066 
   1067 class MockAutofillClient : public WebAutofillClient {
   1068 public:
   1069     MockAutofillClient()
   1070         : m_ignoreTextChanges(false)
   1071         , m_textChangesWhileIgnored(0)
   1072         , m_textChangesWhileNotIgnored(0) { }
   1073 
   1074     virtual ~MockAutofillClient() { }
   1075 
   1076     virtual void setIgnoreTextChanges(bool ignore) OVERRIDE { m_ignoreTextChanges = ignore; }
   1077     virtual void textFieldDidChange(const WebInputElement&) OVERRIDE
   1078     {
   1079         if (m_ignoreTextChanges)
   1080             ++m_textChangesWhileIgnored;
   1081         else
   1082             ++m_textChangesWhileNotIgnored;
   1083     }
   1084 
   1085     void clearChangeCounts()
   1086     {
   1087         m_textChangesWhileIgnored = 0;
   1088         m_textChangesWhileNotIgnored = 0;
   1089     }
   1090 
   1091     int textChangesWhileIgnored() { return m_textChangesWhileIgnored; }
   1092     int textChangesWhileNotIgnored() { return m_textChangesWhileNotIgnored; }
   1093 
   1094 private:
   1095     bool m_ignoreTextChanges;
   1096     int m_textChangesWhileIgnored;
   1097     int m_textChangesWhileNotIgnored;
   1098 };
   1099 
   1100 
   1101 TEST_F(WebViewTest, LosingFocusDoesNotTriggerAutofillTextChange)
   1102 {
   1103     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
   1104     MockAutofillClient client;
   1105     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
   1106     webView->setAutofillClient(&client);
   1107     webView->setInitialFocus(false);
   1108 
   1109     // Set up a composition that needs to be committed.
   1110     WebVector<WebCompositionUnderline> emptyUnderlines;
   1111     webView->setEditableSelectionOffsets(4, 10);
   1112     webView->setCompositionFromExistingText(8, 12, emptyUnderlines);
   1113     WebTextInputInfo info = webView->textInputInfo();
   1114     EXPECT_EQ(4, info.selectionStart);
   1115     EXPECT_EQ(10, info.selectionEnd);
   1116     EXPECT_EQ(8, info.compositionStart);
   1117     EXPECT_EQ(12, info.compositionEnd);
   1118 
   1119     // Clear the focus and track that the subsequent composition commit does not trigger a
   1120     // text changed notification for autofill.
   1121     client.clearChangeCounts();
   1122     webView->setFocus(false);
   1123     EXPECT_EQ(1, client.textChangesWhileIgnored());
   1124     EXPECT_EQ(0, client.textChangesWhileNotIgnored());
   1125 
   1126     webView->setAutofillClient(0);
   1127 }
   1128 
   1129 TEST_F(WebViewTest, ConfirmCompositionTriggersAutofillTextChange)
   1130 {
   1131     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
   1132     MockAutofillClient client;
   1133     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
   1134     webView->setAutofillClient(&client);
   1135     webView->setInitialFocus(false);
   1136 
   1137     // Set up a composition that needs to be committed.
   1138     std::string compositionText("testingtext");
   1139 
   1140     WebVector<WebCompositionUnderline> emptyUnderlines;
   1141     webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 0, compositionText.length());
   1142 
   1143     WebTextInputInfo info = webView->textInputInfo();
   1144     EXPECT_EQ(0, info.selectionStart);
   1145     EXPECT_EQ((int) compositionText.length(), info.selectionEnd);
   1146     EXPECT_EQ(0, info.compositionStart);
   1147     EXPECT_EQ((int) compositionText.length(), info.compositionEnd);
   1148 
   1149     client.clearChangeCounts();
   1150     webView->confirmComposition();
   1151     EXPECT_EQ(0, client.textChangesWhileIgnored());
   1152     EXPECT_EQ(1, client.textChangesWhileNotIgnored());
   1153 
   1154     webView->setAutofillClient(0);
   1155 }
   1156 
   1157 TEST_F(WebViewTest, SetCompositionFromExistingTextTriggersAutofillTextChange)
   1158 {
   1159     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
   1160     MockAutofillClient client;
   1161     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html", true);
   1162     webView->setAutofillClient(&client);
   1163     webView->setInitialFocus(false);
   1164 
   1165     WebVector<WebCompositionUnderline> emptyUnderlines;
   1166 
   1167     client.clearChangeCounts();
   1168     webView->setCompositionFromExistingText(8, 12, emptyUnderlines);
   1169 
   1170     WebTextInputInfo info = webView->textInputInfo();
   1171     EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
   1172     EXPECT_EQ(8, info.compositionStart);
   1173     EXPECT_EQ(12, info.compositionEnd);
   1174 
   1175     EXPECT_EQ(0, client.textChangesWhileIgnored());
   1176     EXPECT_EQ(0, client.textChangesWhileNotIgnored());
   1177 
   1178     WebDocument document = webView->mainFrame()->document();
   1179     EXPECT_EQ(WebString::fromUTF8("none"),  document.getElementById("inputEvent").firstChild().nodeValue());
   1180 
   1181     webView->setAutofillClient(0);
   1182 }
   1183 
   1184 TEST_F(WebViewTest, ShadowRoot)
   1185 {
   1186     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("shadow_dom_test.html"));
   1187     WebViewImpl* webViewImpl = toWebViewImpl(m_webViewHelper.initializeAndLoad(m_baseURL + "shadow_dom_test.html", true));
   1188 
   1189     WebDocument document = webViewImpl->mainFrame()->document();
   1190     {
   1191         WebElement elementWithShadowRoot = document.getElementById("shadowroot");
   1192         EXPECT_FALSE(elementWithShadowRoot.isNull());
   1193         WebNode shadowRoot = elementWithShadowRoot.shadowRoot();
   1194         EXPECT_FALSE(shadowRoot.isNull());
   1195     }
   1196     {
   1197         WebElement elementWithoutShadowRoot = document.getElementById("noshadowroot");
   1198         EXPECT_FALSE(elementWithoutShadowRoot.isNull());
   1199         WebNode shadowRoot = elementWithoutShadowRoot.shadowRoot();
   1200         EXPECT_TRUE(shadowRoot.isNull());
   1201     }
   1202 }
   1203 
   1204 TEST_F(WebViewTest, HelperPlugin)
   1205 {
   1206     HelperPluginCreatingWebViewClient client;
   1207     WebViewImpl* webViewImpl = toWebViewImpl(m_webViewHelper.initialize(true, 0, &client));
   1208 
   1209     WebFrameImpl* frame = toWebFrameImpl(webViewImpl->mainFrame());
   1210     client.setWebFrameClient(frame->client());
   1211 
   1212     WebHelperPluginImpl* helperPlugin = webViewImpl->createHelperPlugin("dummy-plugin-type", frame->document());
   1213     EXPECT_TRUE(helperPlugin);
   1214     EXPECT_EQ(0, helperPlugin->getPlugin()); // Invalid plugin type means no plugin.
   1215 
   1216     webViewImpl->closeHelperPluginSoon(helperPlugin);
   1217 
   1218     m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
   1219 }
   1220 
   1221 
   1222 class ViewCreatingWebViewClient : public WebViewClient {
   1223 public:
   1224     ViewCreatingWebViewClient()
   1225         : m_didFocusCalled(false)
   1226     {
   1227     }
   1228 
   1229     // WebViewClient methods
   1230     virtual WebView* createView(WebFrame*, const WebURLRequest&, const WebWindowFeatures&, const WebString& name, WebNavigationPolicy, bool) OVERRIDE
   1231     {
   1232         return m_webViewHelper.initialize(true, 0, 0);
   1233     }
   1234 
   1235     // WebWidgetClient methods
   1236     virtual void didFocus() OVERRIDE
   1237     {
   1238         m_didFocusCalled = true;
   1239     }
   1240 
   1241     bool didFocusCalled() const { return m_didFocusCalled; }
   1242     WebView* createdWebView() const { return m_webViewHelper.webView(); }
   1243 
   1244 private:
   1245     FrameTestHelpers::WebViewHelper m_webViewHelper;
   1246     bool m_didFocusCalled;
   1247 };
   1248 
   1249 TEST_F(WebViewTest, FocusExistingFrameOnNavigate)
   1250 {
   1251     ViewCreatingWebViewClient client;
   1252     FrameTestHelpers::WebViewHelper m_webViewHelper;
   1253     WebViewImpl* webViewImpl = toWebViewImpl(m_webViewHelper.initialize(true, 0, &client));
   1254     webViewImpl->page()->settings().setJavaScriptCanOpenWindowsAutomatically(true);
   1255     WebFrameImpl* frame = toWebFrameImpl(webViewImpl->mainFrame());
   1256     frame->setName("_start");
   1257 
   1258     // Make a request that will open a new window
   1259     WebURLRequest webURLRequest;
   1260     webURLRequest.initialize();
   1261     WebCore::FrameLoadRequest request(0, webURLRequest.toResourceRequest(), WTF::String("_blank"));
   1262     webViewImpl->page()->mainFrame()->loader().load(request);
   1263     ASSERT_TRUE(client.createdWebView());
   1264     EXPECT_FALSE(client.didFocusCalled());
   1265 
   1266     // Make a request from the new window that will navigate the original window. The original window should be focused.
   1267     WebURLRequest webURLRequestWithTargetStart;
   1268     webURLRequestWithTargetStart.initialize();
   1269     WebCore::FrameLoadRequest requestWithTargetStart(0, webURLRequestWithTargetStart.toResourceRequest(), WTF::String("_start"));
   1270     toWebViewImpl(client.createdWebView())->page()->mainFrame()->loader().load(requestWithTargetStart);
   1271     EXPECT_TRUE(client.didFocusCalled());
   1272 
   1273     m_webViewHelper.reset(); // Remove dependency on locally scoped client.
   1274 }
   1275 
   1276 TEST_F(WebViewTest, DispatchesFocusOutFocusInOnViewToggleFocus)
   1277 {
   1278     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "focusout_focusin_events.html");
   1279     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "focusout_focusin_events.html", true, 0);
   1280 
   1281     webView->setFocus(true);
   1282     webView->setFocus(false);
   1283     webView->setFocus(true);
   1284 
   1285     WebElement element = webView->mainFrame()->document().getElementById("message");
   1286     EXPECT_STREQ("focusoutfocusin", element.innerText().utf8().data());
   1287 }
   1288 
   1289 TEST_F(WebViewTest, DispatchesDomFocusOutDomFocusInOnViewToggleFocus)
   1290 {
   1291     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "domfocusout_domfocusin_events.html");
   1292     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "domfocusout_domfocusin_events.html", true, 0);
   1293 
   1294     webView->setFocus(true);
   1295     webView->setFocus(false);
   1296     webView->setFocus(true);
   1297 
   1298     WebElement element = webView->mainFrame()->document().getElementById("message");
   1299     EXPECT_STREQ("DOMFocusOutDOMFocusIn", element.innerText().utf8().data());
   1300 }
   1301 
   1302 #if !ENABLE(INPUT_MULTIPLE_FIELDS_UI)
   1303 static void openDateTimeChooser(WebView* webView, WebCore::HTMLInputElement* inputElement)
   1304 {
   1305     inputElement->focus();
   1306 
   1307     WebKeyboardEvent keyEvent;
   1308     keyEvent.windowsKeyCode = WebCore::VKEY_SPACE;
   1309     keyEvent.type = WebInputEvent::RawKeyDown;
   1310     keyEvent.setKeyIdentifierFromWindowsKeyCode();
   1311     webView->handleInputEvent(keyEvent);
   1312 
   1313     keyEvent.type = WebInputEvent::KeyUp;
   1314     webView->handleInputEvent(keyEvent);
   1315 }
   1316 
   1317 TEST_F(WebViewTest, ChooseValueFromDateTimeChooser)
   1318 {
   1319     DateTimeChooserWebViewClient client;
   1320     std::string url = m_baseURL + "date_time_chooser.html";
   1321     URLTestHelpers::registerMockedURLLoad(toKURL(url), "date_time_chooser.html");
   1322     WebViewImpl* webViewImpl = toWebViewImpl(m_webViewHelper.initializeAndLoad(url, true, 0, &client));
   1323 
   1324     WebCore::Document* document = webViewImpl->mainFrameImpl()->frame()->document();
   1325 
   1326     WebCore::HTMLInputElement* inputElement;
   1327 
   1328     inputElement = toHTMLInputElement(document->getElementById("date"));
   1329     openDateTimeChooser(webViewImpl, inputElement);
   1330     client.chooserCompletion()->didChooseValue(0);
   1331     client.clearChooserCompletion();
   1332     EXPECT_STREQ("1970-01-01", inputElement->value().utf8().data());
   1333 
   1334     openDateTimeChooser(webViewImpl, inputElement);
   1335     client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
   1336     client.clearChooserCompletion();
   1337     EXPECT_STREQ("", inputElement->value().utf8().data());
   1338 
   1339     inputElement = toHTMLInputElement(document->getElementById("datetimelocal"));
   1340     openDateTimeChooser(webViewImpl, inputElement);
   1341     client.chooserCompletion()->didChooseValue(0);
   1342     client.clearChooserCompletion();
   1343     EXPECT_STREQ("1970-01-01T00:00", inputElement->value().utf8().data());
   1344 
   1345     openDateTimeChooser(webViewImpl, inputElement);
   1346     client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
   1347     client.clearChooserCompletion();
   1348     EXPECT_STREQ("", inputElement->value().utf8().data());
   1349 
   1350     inputElement = toHTMLInputElement(document->getElementById("month"));
   1351     openDateTimeChooser(webViewImpl, inputElement);
   1352     client.chooserCompletion()->didChooseValue(0);
   1353     client.clearChooserCompletion();
   1354     EXPECT_STREQ("1970-01", inputElement->value().utf8().data());
   1355 
   1356     openDateTimeChooser(webViewImpl, inputElement);
   1357     client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
   1358     client.clearChooserCompletion();
   1359     EXPECT_STREQ("", inputElement->value().utf8().data());
   1360 
   1361     inputElement = toHTMLInputElement(document->getElementById("time"));
   1362     openDateTimeChooser(webViewImpl, inputElement);
   1363     client.chooserCompletion()->didChooseValue(0);
   1364     client.clearChooserCompletion();
   1365     EXPECT_STREQ("00:00", inputElement->value().utf8().data());
   1366 
   1367     openDateTimeChooser(webViewImpl, inputElement);
   1368     client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
   1369     client.clearChooserCompletion();
   1370     EXPECT_STREQ("", inputElement->value().utf8().data());
   1371 
   1372     inputElement = toHTMLInputElement(document->getElementById("week"));
   1373     openDateTimeChooser(webViewImpl, inputElement);
   1374     client.chooserCompletion()->didChooseValue(0);
   1375     client.clearChooserCompletion();
   1376     EXPECT_STREQ("1970-W01", inputElement->value().utf8().data());
   1377 
   1378     openDateTimeChooser(webViewImpl, inputElement);
   1379     client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
   1380     client.clearChooserCompletion();
   1381     EXPECT_STREQ("", inputElement->value().utf8().data());
   1382 }
   1383 #endif
   1384 
   1385 TEST_F(WebViewTest, SmartClipData)
   1386 {
   1387     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("Ahem.ttf"));
   1388     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("smartclip.html"));
   1389     WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "smartclip.html");
   1390     webView->resize(WebSize(500, 500));
   1391     webView->layout();
   1392     WebRect cropRect(300, 125, 100, 50);
   1393 
   1394     // FIXME: We should test the structure of the data we get back.
   1395     EXPECT_FALSE(webView->getSmartClipData(cropRect).isEmpty());
   1396 }
   1397 
   1398 }
   1399