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