/*
 * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "public/web/WebView.h"

#include "bindings/core/v8/V8Document.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/editing/FrameSelection.h"
#include "core/editing/InputMethodController.h"
#include "core/editing/markers/DocumentMarkerController.h"
#include "core/frame/EventHandlerRegistry.h"
#include "core/frame/FrameHost.h"
#include "core/frame/FrameView.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "core/frame/VisualViewport.h"
#include "core/html/HTMLDocument.h"
#include "core/html/HTMLIFrameElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLTextAreaElement.h"
#include "core/layout/LayoutView.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoadRequest.h"
#include "core/page/Page.h"
#include "core/paint/PaintLayer.h"
#include "core/paint/PaintLayerPainter.h"
#include "core/timing/DOMWindowPerformance.h"
#include "core/timing/Performance.h"
#include "core/timing/PerformanceCompositeTiming.h"
#include "platform/KeyboardCodes.h"
#include "platform/UserGestureIndicator.h"
#include "platform/geometry/IntSize.h"
#include "platform/graphics/Color.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/paint/SkPictureBuilder.h"
#include "platform/testing/URLTestHelpers.h"
#include "platform/testing/UnitTestHelpers.h"
#include "public/platform/Platform.h"
#include "public/platform/WebDisplayMode.h"
#include "public/platform/WebDragData.h"
#include "public/platform/WebDragOperation.h"
#include "public/platform/WebMockClipboard.h"
#include "public/platform/WebSize.h"
#include "public/platform/WebThread.h"
#include "public/platform/WebURLLoaderMockFactory.h"
#include "public/web/WebAutofillClient.h"
#include "public/web/WebCache.h"
#include "public/web/WebContentDetectionResult.h"
#include "public/web/WebDateTimeChooserCompletion.h"
#include "public/web/WebDeviceEmulationParams.h"
#include "public/web/WebDocument.h"
#include "public/web/WebElement.h"
#include "public/web/WebFrame.h"
#include "public/web/WebFrameClient.h"
#include "public/web/WebFrameContentDumper.h"
#include "public/web/WebHitTestResult.h"
#include "public/web/WebInputEvent.h"
#include "public/web/WebScriptSource.h"
#include "public/web/WebSettings.h"
#include "public/web/WebTreeScopeType.h"
#include "public/web/WebViewClient.h"
#include "public/web/WebWidget.h"
#include "public/web/WebWidgetClient.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "web/WebLocalFrameImpl.h"
#include "web/WebSettingsImpl.h"
#include "web/WebViewImpl.h"
#include "web/tests/FrameTestHelpers.h"

#if OS(MACOSX)
#include "public/web/mac/WebSubstringUtil.h"
#endif

using blink::FrameTestHelpers::loadFrame;
using blink::URLTestHelpers::toKURL;
using blink::URLTestHelpers::registerMockedURLLoad;
using blink::testing::runPendingTasks;

namespace blink {

enum HorizontalScrollbarState {
    NoHorizontalScrollbar,
    VisibleHorizontalScrollbar,
};

enum VerticalScrollbarState {
    NoVerticalScrollbar,
    VisibleVerticalScrollbar,
};

class TestData {
public:
    void setWebView(WebView* webView) { m_webView = toWebViewImpl(webView); }
    void setSize(const WebSize& newSize) { m_size = newSize; }
    HorizontalScrollbarState getHorizontalScrollbarState() const
    {
        return m_webView->hasHorizontalScrollbar() ? VisibleHorizontalScrollbar: NoHorizontalScrollbar;
    }
    VerticalScrollbarState getVerticalScrollbarState() const
    {
        return m_webView->hasVerticalScrollbar() ? VisibleVerticalScrollbar : NoVerticalScrollbar;
    }
    int width() const { return m_size.width; }
    int height() const { return m_size.height; }

private:
    WebSize m_size;
    WebViewImpl* m_webView;
};

class AutoResizeWebViewClient : public FrameTestHelpers::TestWebViewClient {
public:
    // WebViewClient methods
    void didAutoResize(const WebSize& newSize) override { m_testData.setSize(newSize); }

    // Local methods
    TestData& testData() { return m_testData; }

private:
    TestData m_testData;
};

class SaveImageFromDataURLWebViewClient : public FrameTestHelpers::TestWebViewClient {
public:
    // WebViewClient methods
    void saveImageFromDataURL(const WebString& dataURL) override { m_dataURL = dataURL; }

    // Local methods
    const WebString& result() const { return m_dataURL; }
    void reset() { m_dataURL = WebString(); }

private:
    WebString m_dataURL;
};

class TapHandlingWebViewClient : public FrameTestHelpers::TestWebViewClient {
public:
    // WebViewClient methods
    void didHandleGestureEvent(const WebGestureEvent& event, bool eventCancelled) override
    {
        if (event.type == WebInputEvent::GestureTap) {
            m_tapX = event.x;
            m_tapY = event.y;
        } else if (event.type == WebInputEvent::GestureLongPress) {
            m_longpressX = event.x;
            m_longpressY = event.y;
        }
    }

    // Local methods
    void reset()
    {
        m_tapX = -1;
        m_tapY = -1;
        m_longpressX = -1;
        m_longpressY = -1;
    }
    int tapX() { return m_tapX; }
    int tapY() { return m_tapY; }
    int longpressX() { return m_longpressX; }
    int longpressY() { return m_longpressY; }

private:
    int m_tapX;
    int m_tapY;
    int m_longpressX;
    int m_longpressY;
};

class DateTimeChooserWebViewClient : public FrameTestHelpers::TestWebViewClient {
public:
    WebDateTimeChooserCompletion* chooserCompletion()
    {
        return m_chooserCompletion;
    }

    void clearChooserCompletion()
    {
        m_chooserCompletion = 0;
    }

    // WebViewClient methods
    bool openDateTimeChooser(const WebDateTimeChooserParams&, WebDateTimeChooserCompletion* chooser_completion) override
    {
        m_chooserCompletion = chooser_completion;
        return true;
    }

private:
    WebDateTimeChooserCompletion* m_chooserCompletion;

};

class WebViewTest : public ::testing::Test {
public:
    WebViewTest()
        : m_baseURL("http://www.test.com/")
    {
    }

    void TearDown() override
    {
        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
        WebCache::clear();
    }

protected:
    void registerMockedHttpURLLoad(const std::string& fileName)
    {
        URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(fileName.c_str()));
    }

    void testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize,
                        const std::string& pageWidth, const std::string& pageHeight,
                        int expectedWidth, int expectedHeight,
                        HorizontalScrollbarState expectedHorizontalState, VerticalScrollbarState expectedVerticalState);

    void testTextInputType(WebTextInputType expectedType, const std::string& htmlFile);
    void testInputMode(const WebString& expectedInputMode, const std::string& htmlFile);
    bool tapElement(WebInputEvent::Type, Element*);
    bool tapElementById(WebInputEvent::Type, const WebString& id);

    std::string m_baseURL;
    FrameTestHelpers::WebViewHelper m_webViewHelper;
};

TEST_F(WebViewTest, SaveImageAt)
{
    SaveImageFromDataURLWebViewClient client;

    std::string url = m_baseURL + "image-with-data-url.html";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "image-with-data-url.html");
    URLTestHelpers::registerMockedURLLoad(toKURL("http://test"), "white-1x1.png");
    WebViewImpl* webView = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
    webView->resize(WebSize(400, 400));
    webView->updateAllLifecyclePhases();

    client.reset();
    webView->saveImageAt(WebPoint(1, 1));
    EXPECT_EQ(WebString::fromUTF8("data:image/gif;base64"
        ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), client.result());

    client.reset();
    webView->saveImageAt(WebPoint(1, 2));
    EXPECT_EQ(WebString(), client.result());

    webView->setPageScaleFactor(4);
    webView->setVisualViewportOffset(WebFloatPoint(1, 1));

    client.reset();
    webView->saveImageAt(WebPoint(3, 3));
    EXPECT_EQ(WebString::fromUTF8("data:image/gif;base64"
        ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), client.result());

    m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
};

TEST_F(WebViewTest, SaveImageWithImageMap)
{
    SaveImageFromDataURLWebViewClient client;

    std::string url = m_baseURL + "image-map.html";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "image-map.html");
    WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
    webView->resize(WebSize(400, 400));

    client.reset();
    webView->saveImageAt(WebPoint(25, 25));
    EXPECT_EQ(WebString::fromUTF8("data:image/gif;base64"
        ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), client.result());

    client.reset();
    webView->saveImageAt(WebPoint(75, 25));
    EXPECT_EQ(WebString::fromUTF8("data:image/gif;base64"
        ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), client.result());

    client.reset();
    webView->saveImageAt(WebPoint(125, 25));
    EXPECT_EQ(WebString(), client.result());

    m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
}

TEST_F(WebViewTest, CopyImageAt)
{
    std::string url = m_baseURL + "canvas-copy-image.html";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "canvas-copy-image.html");
    WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0);
    webView->resize(WebSize(400, 400));

    uint64_t sequence = Platform::current()->clipboard()->sequenceNumber(WebClipboard::BufferStandard);

    webView->copyImageAt(WebPoint(50, 50));

    EXPECT_NE(sequence, Platform::current()->clipboard()->sequenceNumber(WebClipboard::BufferStandard));

    WebImage image = static_cast<WebMockClipboard*>(Platform::current()->clipboard())->readRawImage(WebClipboard::Buffer());

    SkAutoLockPixels autoLock(image.getSkBitmap());
    EXPECT_EQ(SkColorSetARGB(255, 255, 0, 0), image.getSkBitmap().getColor(0, 0));
};

TEST_F(WebViewTest, CopyImageAtWithPinchZoom)
{
    std::string url = m_baseURL + "canvas-copy-image.html";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "canvas-copy-image.html");
    WebViewImpl* webView = m_webViewHelper.initializeAndLoad(url, true, 0);
    webView->resize(WebSize(400, 400));
    webView->updateAllLifecyclePhases();
    webView->setPageScaleFactor(2);
    webView->setVisualViewportOffset(WebFloatPoint(200, 200));

    uint64_t sequence = Platform::current()->clipboard()->sequenceNumber(WebClipboard::BufferStandard);

    webView->copyImageAt(WebPoint(0, 0));

    EXPECT_NE(sequence, Platform::current()->clipboard()->sequenceNumber(WebClipboard::BufferStandard));

    WebImage image = static_cast<WebMockClipboard*>(Platform::current()->clipboard())->readRawImage(WebClipboard::Buffer());

    SkAutoLockPixels autoLock(image.getSkBitmap());
    EXPECT_EQ(SkColorSetARGB(255, 255, 0, 0), image.getSkBitmap().getColor(0, 0));
};

TEST_F(WebViewTest, CopyImageWithImageMap)
{
    SaveImageFromDataURLWebViewClient client;

    std::string url = m_baseURL + "image-map.html";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "image-map.html");
    WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
    webView->resize(WebSize(400, 400));

    client.reset();
    webView->saveImageAt(WebPoint(25, 25));
    EXPECT_EQ(WebString::fromUTF8("data:image/gif;base64"
        ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), client.result());

    client.reset();
    webView->saveImageAt(WebPoint(75, 25));
    EXPECT_EQ(WebString::fromUTF8("data:image/gif;base64"
        ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), client.result());

    client.reset();
    webView->saveImageAt(WebPoint(125, 25));
    EXPECT_EQ(WebString(), client.result());

    m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
}

static bool hitTestIsContentEditable(WebView* view, int x, int y)
{
    WebPoint hitPoint(x, y);
    WebHitTestResult hitTestResult = view->hitTestResultAt(hitPoint);
    return hitTestResult.isContentEditable();
}

static std::string hitTestElementId(WebView* view, int x, int y)
{
    WebPoint hitPoint(x, y);
    WebHitTestResult hitTestResult = view->hitTestResultAt(hitPoint);
    return hitTestResult.node().to<WebElement>().getAttribute("id").utf8();
}

TEST_F(WebViewTest, HitTestContentEditableImageMaps)
{
    std::string url = m_baseURL + "content-editable-image-maps.html";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "content-editable-image-maps.html");
    WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0);
    webView->resize(WebSize(500, 500));

    EXPECT_EQ("areaANotEditable", hitTestElementId(webView, 25, 25));
    EXPECT_FALSE(hitTestIsContentEditable(webView, 25, 25));
    EXPECT_EQ("imageANotEditable", hitTestElementId(webView, 75, 25));
    EXPECT_FALSE(hitTestIsContentEditable(webView, 75, 25));

    EXPECT_EQ("areaBNotEditable", hitTestElementId(webView, 25, 125));
    EXPECT_FALSE(hitTestIsContentEditable(webView, 25, 125));
    EXPECT_EQ("imageBEditable", hitTestElementId(webView, 75, 125));
    EXPECT_TRUE(hitTestIsContentEditable(webView, 75, 125));

    EXPECT_EQ("areaCNotEditable", hitTestElementId(webView, 25, 225));
    EXPECT_FALSE(hitTestIsContentEditable(webView, 25, 225));
    EXPECT_EQ("imageCNotEditable", hitTestElementId(webView, 75, 225));
    EXPECT_FALSE(hitTestIsContentEditable(webView, 75, 225));

    EXPECT_EQ("areaDEditable", hitTestElementId(webView, 25, 325));
    EXPECT_TRUE(hitTestIsContentEditable(webView, 25, 325));
    EXPECT_EQ("imageDNotEditable", hitTestElementId(webView, 75, 325));
    EXPECT_FALSE(hitTestIsContentEditable(webView, 75, 325));
}

static std::string hitTestAbsoluteUrl(WebView* view, int x, int y)
{
    WebPoint hitPoint(x, y);
    WebHitTestResult hitTestResult = view->hitTestResultAt(hitPoint);
    return hitTestResult.absoluteImageURL().string().utf8();
}

static WebElement hitTestUrlElement(WebView* view, int x, int y)
{
    WebPoint hitPoint(x, y);
    WebHitTestResult hitTestResult = view->hitTestResultAt(hitPoint);
    return hitTestResult.urlElement();
}

TEST_F(WebViewTest, ImageMapUrls)
{
    std::string url = m_baseURL + "image-map.html";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "image-map.html");
    WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0);
    webView->resize(WebSize(400, 400));

    std::string imageUrl = "data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=";

    EXPECT_EQ("area", hitTestElementId(webView, 25, 25));
    EXPECT_EQ("area", hitTestUrlElement(webView, 25, 25).getAttribute("id").utf8());
    EXPECT_EQ(imageUrl, hitTestAbsoluteUrl(webView, 25, 25));

    EXPECT_EQ("image", hitTestElementId(webView, 75, 25));
    EXPECT_TRUE(hitTestUrlElement(webView, 75, 25).isNull());
    EXPECT_EQ(imageUrl, hitTestAbsoluteUrl(webView, 75, 25));
}

TEST_F(WebViewTest, BrokenImage)
{
    URLTestHelpers::registerMockedErrorURLLoad(KURL(toKURL(m_baseURL), "non_existent.png"));
    std::string url = m_baseURL + "image-broken.html";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "image-broken.html");

    WebView* webView = m_webViewHelper.initialize();
    webView->settings()->setLoadsImagesAutomatically(true);
    loadFrame(webView->mainFrame(), url);
    webView->resize(WebSize(400, 400));

    std::string imageUrl = "http://www.test.com/non_existent.png";

    EXPECT_EQ("image", hitTestElementId(webView, 25, 25));
    EXPECT_TRUE(hitTestUrlElement(webView, 25, 25).isNull());
    EXPECT_EQ(imageUrl, hitTestAbsoluteUrl(webView, 25, 25));
}

TEST_F(WebViewTest, BrokenInputImage)
{
    URLTestHelpers::registerMockedErrorURLLoad(KURL(toKURL(m_baseURL), "non_existent.png"));
    std::string url = m_baseURL + "input-image-broken.html";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "input-image-broken.html");

    WebView* webView = m_webViewHelper.initialize();
    webView->settings()->setLoadsImagesAutomatically(true);
    loadFrame(webView->mainFrame(), url);
    webView->resize(WebSize(400, 400));

    std::string imageUrl = "http://www.test.com/non_existent.png";

    EXPECT_EQ("image", hitTestElementId(webView, 25, 25));
    EXPECT_TRUE(hitTestUrlElement(webView, 25, 25).isNull());
    EXPECT_EQ(imageUrl, hitTestAbsoluteUrl(webView, 25, 25));
}

TEST_F(WebViewTest, SetBaseBackgroundColor)
{
    const WebColor kWhite    = 0xFFFFFFFF;
    const WebColor kBlue     = 0xFF0000FF;
    const WebColor kDarkCyan = 0xFF227788;
    const WebColor kTranslucentPutty = 0x80BFB196;
    const WebColor kTransparent = 0x00000000;

    WebViewImpl* webView = m_webViewHelper.initialize();
    EXPECT_EQ(kWhite, webView->backgroundColor());

    webView->setBaseBackgroundColor(kBlue);
    EXPECT_EQ(kBlue, webView->backgroundColor());

    WebURL baseURL = URLTestHelpers::toKURL("http://example.com/");
    FrameTestHelpers::loadHTMLString(webView->mainFrame(), "<html><head><style>body {background-color:#227788}</style></head></html>", baseURL);
    EXPECT_EQ(kDarkCyan, webView->backgroundColor());

    FrameTestHelpers::loadHTMLString(webView->mainFrame(), "<html><head><style>body {background-color:rgba(255,0,0,0.5)}</style></head></html>", baseURL);
    // Expected: red (50% alpha) blended atop base of kBlue.
    EXPECT_EQ(0xFF7F0080, webView->backgroundColor());

    webView->setBaseBackgroundColor(kTranslucentPutty);
    // Expected: red (50% alpha) blended atop kTranslucentPutty. Note the alpha.
    EXPECT_EQ(0xBFE93B32, webView->backgroundColor());

    webView->setBaseBackgroundColor(kTransparent);
    FrameTestHelpers::loadHTMLString(webView->mainFrame(), "<html><head><style>body {background-color:transparent}</style></head></html>", baseURL);
    // Expected: transparent on top of kTransparent will still be transparent.
    EXPECT_EQ(kTransparent, webView->backgroundColor());

    LocalFrame* frame = webView->mainFrameImpl()->frame();
    // The detach() and dispose() calls are a hack to prevent this test
    // from violating invariants about frame state during navigation/detach.
    frame->document()->detach();

    // Creating a new frame view with the background color having 0 alpha.
    frame->createView(IntSize(1024, 768), Color::transparent, true);
    EXPECT_EQ(kTransparent, frame->view()->baseBackgroundColor());
    frame->view()->dispose();

    const Color transparentRed(100, 0, 0, 0);
    frame->createView(IntSize(1024, 768), transparentRed, true);
    EXPECT_EQ(transparentRed, frame->view()->baseBackgroundColor());
    frame->view()->dispose();
}

TEST_F(WebViewTest, SetBaseBackgroundColorBeforeMainFrame)
{
    const WebColor kBlue = 0xFF0000FF;
    FrameTestHelpers::TestWebViewClient webViewClient;
    WebViewImpl* webView = WebViewImpl::create(&webViewClient);
    EXPECT_NE(kBlue, webView->backgroundColor());
    // webView does not have a frame yet, but we should still be able to set the background color.
    webView->setBaseBackgroundColor(kBlue);
    EXPECT_EQ(kBlue, webView->backgroundColor());
    WebLocalFrame* frame = WebLocalFrame::create(WebTreeScopeType::Document, nullptr);
    webView->setMainFrame(frame);
    webView->close();
    frame->close();
}

TEST_F(WebViewTest, SetBaseBackgroundColorAndBlendWithExistingContent)
{
    const WebColor kAlphaRed = 0x80FF0000;
    const WebColor kAlphaGreen = 0x8000FF00;
    const int kWidth = 100;
    const int kHeight = 100;

    WebViewImpl* webView = m_webViewHelper.initialize();

    // Set WebView background to green with alpha.
    webView->setBaseBackgroundColor(kAlphaGreen);
    webView->settings()->setShouldClearDocumentBackground(false);
    webView->resize(WebSize(kWidth, kHeight));
    webView->updateAllLifecyclePhases();

    // Set canvas background to red with alpha.
    SkBitmap bitmap;
    bitmap.allocN32Pixels(kWidth, kHeight);
    SkCanvas canvas(bitmap);
    canvas.clear(kAlphaRed);

    SkPictureBuilder pictureBuilder(FloatRect(0, 0, kWidth, kHeight));

    // Paint the root of the main frame in the way that CompositedLayerMapping would.
    FrameView* view = m_webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
    PaintLayer* rootLayer = view->layoutViewItem().layer();
    LayoutRect paintRect(0, 0, kWidth, kHeight);
    PaintLayerPaintingInfo paintingInfo(rootLayer, paintRect, GlobalPaintNormalPhase, LayoutSize());
    PaintLayerPainter(*rootLayer).paintLayerContents(pictureBuilder.context(), paintingInfo, PaintLayerPaintingCompositingAllPhases);

    pictureBuilder.endRecording()->playback(&canvas);

    // The result should be a blend of red and green.
    SkColor color = bitmap.getColor(kWidth / 2, kHeight / 2);
    EXPECT_TRUE(redChannel(color));
    EXPECT_TRUE(greenChannel(color));
}

TEST_F(WebViewTest, FocusIsInactive)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "visible_iframe.html");
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "visible_iframe.html");

    webView->setFocus(true);
    webView->setIsActive(true);
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());

    HTMLDocument* document = toHTMLDocument(frame->frame()->document());
    EXPECT_TRUE(document->hasFocus());
    webView->setFocus(false);
    webView->setIsActive(false);
    EXPECT_FALSE(document->hasFocus());
    webView->setFocus(true);
    webView->setIsActive(true);
    EXPECT_TRUE(document->hasFocus());
    webView->setFocus(true);
    webView->setIsActive(false);
    EXPECT_FALSE(document->hasFocus());
    webView->setFocus(false);
    webView->setIsActive(true);
    EXPECT_FALSE(document->hasFocus());
}

TEST_F(WebViewTest, ActiveState)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "visible_iframe.html");
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "visible_iframe.html");

    ASSERT_TRUE(webView);

    webView->setIsActive(true);
    EXPECT_TRUE(webView->isActive());

    webView->setIsActive(false);
    EXPECT_FALSE(webView->isActive());

    webView->setIsActive(true);
    EXPECT_TRUE(webView->isActive());
}

TEST_F(WebViewTest, HitTestResultAtWithPageScale)
{
    std::string url = m_baseURL + "specify_size.html?" + "50px" + ":" + "50px";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html");
    WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0);
    webView->resize(WebSize(100, 100));
    WebPoint hitPoint(75, 75);

    // Image is at top left quandrant, so should not hit it.
    WebHitTestResult negativeResult = webView->hitTestResultAt(hitPoint);
    EXPECT_FALSE(negativeResult.node().to<WebElement>().hasHTMLTagName("img"));
    negativeResult.reset();

    // Scale page up 2x so image should occupy the whole viewport.
    webView->setPageScaleFactor(2.0f);
    WebHitTestResult positiveResult = webView->hitTestResultAt(hitPoint);
    EXPECT_TRUE(positiveResult.node().to<WebElement>().hasHTMLTagName("img"));
    positiveResult.reset();
}

TEST_F(WebViewTest, HitTestResultAtWithPageScaleAndPan)
{
    std::string url = m_baseURL + "specify_size.html?" + "50px" + ":" + "50px";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html");
    WebView* webView = m_webViewHelper.initialize(true);
    loadFrame(webView->mainFrame(), url);
    webView->resize(WebSize(100, 100));
    WebPoint hitPoint(75, 75);

    // Image is at top left quandrant, so should not hit it.
    WebHitTestResult negativeResult = webView->hitTestResultAt(hitPoint);
    EXPECT_FALSE(negativeResult.node().to<WebElement>().hasHTMLTagName("img"));
    negativeResult.reset();

    // Scale page up 2x so image should occupy the whole viewport.
    webView->setPageScaleFactor(2.0f);
    WebHitTestResult positiveResult = webView->hitTestResultAt(hitPoint);
    EXPECT_TRUE(positiveResult.node().to<WebElement>().hasHTMLTagName("img"));
    positiveResult.reset();

    // Pan around the zoomed in page so the image is not visible in viewport.
    webView->setVisualViewportOffset(WebFloatPoint(100, 100));
    WebHitTestResult negativeResult2 = webView->hitTestResultAt(hitPoint);
    EXPECT_FALSE(negativeResult2.node().to<WebElement>().hasHTMLTagName("img"));
    negativeResult2.reset();
}

TEST_F(WebViewTest, HitTestResultForTapWithTapArea)
{
    std::string url = m_baseURL + "hit_test.html";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "hit_test.html");
    WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0);
    webView->resize(WebSize(100, 100));
    WebPoint hitPoint(55, 55);

    // Image is at top left quandrant, so should not hit it.
    WebHitTestResult negativeResult = webView->hitTestResultAt(hitPoint);
    EXPECT_FALSE(negativeResult.node().to<WebElement>().hasHTMLTagName("img"));
    negativeResult.reset();

    // The tap area is 20 by 20 square, centered at 55, 55.
    WebSize tapArea(20, 20);
    WebHitTestResult positiveResult = webView->hitTestResultForTap(hitPoint, tapArea);
    EXPECT_TRUE(positiveResult.node().to<WebElement>().hasHTMLTagName("img"));
    positiveResult.reset();

    // Move the hit point the image is just outside the tapped area now.
    hitPoint = WebPoint(61, 61);
    WebHitTestResult negativeResult2 = webView->hitTestResultForTap(hitPoint, tapArea);
    EXPECT_FALSE(negativeResult2.node().to<WebElement>().hasHTMLTagName("img"));
    negativeResult2.reset();
}

TEST_F(WebViewTest, HitTestResultForTapWithTapAreaPageScaleAndPan)
{
    std::string url = m_baseURL + "hit_test.html";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "hit_test.html");
    WebView* webView = m_webViewHelper.initialize(true);
    loadFrame(webView->mainFrame(), url);
    webView->resize(WebSize(100, 100));
    WebPoint hitPoint(55, 55);

    // Image is at top left quandrant, so should not hit it.
    WebHitTestResult negativeResult = webView->hitTestResultAt(hitPoint);
    EXPECT_FALSE(negativeResult.node().to<WebElement>().hasHTMLTagName("img"));
    negativeResult.reset();

    // The tap area is 20 by 20 square, centered at 55, 55.
    WebSize tapArea(20, 20);
    WebHitTestResult positiveResult = webView->hitTestResultForTap(hitPoint, tapArea);
    EXPECT_TRUE(positiveResult.node().to<WebElement>().hasHTMLTagName("img"));
    positiveResult.reset();

    // Zoom in and pan around the page so the image is not visible in viewport.
    webView->setPageScaleFactor(2.0f);
    webView->setVisualViewportOffset(WebFloatPoint(100, 100));
    WebHitTestResult negativeResult2 = webView->hitTestResultForTap(hitPoint, tapArea);
    EXPECT_FALSE(negativeResult2.node().to<WebElement>().hasHTMLTagName("img"));
    negativeResult2.reset();
}

void WebViewTest::testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize,
                                 const std::string& pageWidth, const std::string& pageHeight,
                                 int expectedWidth, int expectedHeight,
                                 HorizontalScrollbarState expectedHorizontalState, VerticalScrollbarState expectedVerticalState)
{
    AutoResizeWebViewClient client;
    std::string url = m_baseURL + "specify_size.html?" + pageWidth + ":" + pageHeight;
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html");
    WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
    client.testData().setWebView(webView);

    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    FrameView* frameView = frame->frame()->view();
    frameView->layout();
    EXPECT_FALSE(frameView->layoutPending());
    EXPECT_FALSE(frameView->needsLayout());

    webView->enableAutoResizeMode(minAutoResize, maxAutoResize);
    EXPECT_TRUE(frameView->layoutPending());
    EXPECT_TRUE(frameView->needsLayout());
    frameView->layout();

    EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());

    EXPECT_EQ(expectedWidth, client.testData().width());
    EXPECT_EQ(expectedHeight, client.testData().height());

    // Android disables main frame scrollbars.
#if !OS(ANDROID)
    EXPECT_EQ(expectedHorizontalState, client.testData().getHorizontalScrollbarState());
    EXPECT_EQ(expectedVerticalState, client.testData().getVerticalScrollbarState());
#endif

    m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
}

TEST_F(WebViewTest, AutoResizeMinimumSize)
{
    WebSize minAutoResize(91, 56);
    WebSize maxAutoResize(403, 302);
    std::string pageWidth = "91px";
    std::string pageHeight = "56px";
    int expectedWidth = 91;
    int expectedHeight = 56;
    testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
                   expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
}

TEST_F(WebViewTest, AutoResizeHeightOverflowAndFixedWidth)
{
    WebSize minAutoResize(90, 95);
    WebSize maxAutoResize(90, 100);
    std::string pageWidth = "60px";
    std::string pageHeight = "200px";
    int expectedWidth = 90;
    int expectedHeight = 100;
    testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
                   expectedWidth, expectedHeight, NoHorizontalScrollbar, VisibleVerticalScrollbar);
}

TEST_F(WebViewTest, AutoResizeFixedHeightAndWidthOverflow)
{
    WebSize minAutoResize(90, 100);
    WebSize maxAutoResize(200, 100);
    std::string pageWidth = "300px";
    std::string pageHeight = "80px";
    int expectedWidth = 200;
    int expectedHeight = 100;
    testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
                   expectedWidth, expectedHeight, VisibleHorizontalScrollbar, NoVerticalScrollbar);
}

// Next three tests disabled for https://bugs.webkit.org/show_bug.cgi?id=92318 .
// It seems we can run three AutoResize tests, then the next one breaks.
TEST_F(WebViewTest, AutoResizeInBetweenSizes)
{
    WebSize minAutoResize(90, 95);
    WebSize maxAutoResize(200, 300);
    std::string pageWidth = "100px";
    std::string pageHeight = "200px";
    int expectedWidth = 100;
    int expectedHeight = 200;
    testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
                   expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
}

TEST_F(WebViewTest, AutoResizeOverflowSizes)
{
    WebSize minAutoResize(90, 95);
    WebSize maxAutoResize(200, 300);
    std::string pageWidth = "300px";
    std::string pageHeight = "400px";
    int expectedWidth = 200;
    int expectedHeight = 300;
    testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
                   expectedWidth, expectedHeight, VisibleHorizontalScrollbar, VisibleVerticalScrollbar);
}

TEST_F(WebViewTest, AutoResizeMaxSize)
{
    WebSize minAutoResize(90, 95);
    WebSize maxAutoResize(200, 300);
    std::string pageWidth = "200px";
    std::string pageHeight = "300px";
    int expectedWidth = 200;
    int expectedHeight = 300;
    testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
                   expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
}

void WebViewTest::testTextInputType(WebTextInputType expectedType, const std::string& htmlFile)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(htmlFile.c_str()));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + htmlFile);
    EXPECT_EQ(WebTextInputTypeNone, webView->textInputType());
    EXPECT_EQ(WebTextInputTypeNone, webView->textInputInfo().type);
    webView->setInitialFocus(false);
    EXPECT_EQ(expectedType, webView->textInputType());
    EXPECT_EQ(expectedType, webView->textInputInfo().type);
    webView->clearFocusedElement();
    EXPECT_EQ(WebTextInputTypeNone, webView->textInputType());
    EXPECT_EQ(WebTextInputTypeNone, webView->textInputInfo().type);
}

TEST_F(WebViewTest, TextInputType)
{
    testTextInputType(WebTextInputTypeText, "input_field_default.html");
    testTextInputType(WebTextInputTypePassword, "input_field_password.html");
    testTextInputType(WebTextInputTypeEmail, "input_field_email.html");
    testTextInputType(WebTextInputTypeSearch, "input_field_search.html");
    testTextInputType(WebTextInputTypeNumber, "input_field_number.html");
    testTextInputType(WebTextInputTypeTelephone, "input_field_tel.html");
    testTextInputType(WebTextInputTypeURL, "input_field_url.html");
}

void WebViewTest::testInputMode(const WebString& expectedInputMode, const std::string& htmlFile)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(htmlFile.c_str()));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + htmlFile);
    webView->setInitialFocus(false);
    EXPECT_EQ(expectedInputMode, webView->textInputInfo().inputMode);
}

TEST_F(WebViewTest, InputMode)
{
    testInputMode(WebString(), "input_mode_default.html");
    testInputMode(WebString("unknown"), "input_mode_default_unknown.html");
    testInputMode(WebString("verbatim"), "input_mode_default_verbatim.html");
    testInputMode(WebString("verbatim"), "input_mode_type_text_verbatim.html");
    testInputMode(WebString("verbatim"), "input_mode_type_search_verbatim.html");
    testInputMode(WebString(), "input_mode_type_url_verbatim.html");
    testInputMode(WebString("verbatim"), "input_mode_textarea_verbatim.html");
}

TEST_F(WebViewTest, TextInputInfoWithReplacedElements)
{
    std::string url = m_baseURL + "div_with_image.html";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "div_with_image.html");
    URLTestHelpers::registerMockedURLLoad(toKURL("http://www.test.com/foo.png"), "white-1x1.png");
    WebView* webView = m_webViewHelper.initializeAndLoad(url);
    webView->setInitialFocus(false);
    WebTextInputInfo info = webView->textInputInfo();

    EXPECT_EQ("foo\xef\xbf\xbc", info.value.utf8());
}

TEST_F(WebViewTest, SetEditableSelectionOffsetsAndTextInputInfo)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
    webView->setInitialFocus(false);
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    frame->setEditableSelectionOffsets(5, 13);
    EXPECT_EQ("56789abc", frame->selectionAsText());
    WebTextInputInfo info = webView->textInputInfo();
    EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value);
    EXPECT_EQ(5, info.selectionStart);
    EXPECT_EQ(13, info.selectionEnd);
    EXPECT_EQ(-1, info.compositionStart);
    EXPECT_EQ(-1, info.compositionEnd);

    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_editable_populated.html"));
    webView = m_webViewHelper.initializeAndLoad(m_baseURL + "content_editable_populated.html");
    webView->setInitialFocus(false);
    frame = toWebLocalFrameImpl(webView->mainFrame());
    frame->setEditableSelectionOffsets(8, 19);
    EXPECT_EQ("89abcdefghi", frame->selectionAsText());
    info = webView->textInputInfo();
    EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value);
    EXPECT_EQ(8, info.selectionStart);
    EXPECT_EQ(19, info.selectionEnd);
    EXPECT_EQ(-1, info.compositionStart);
    EXPECT_EQ(-1, info.compositionEnd);
}

TEST_F(WebViewTest, ConfirmCompositionCursorPositionChange)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
    webView->setInitialFocus(false);

    // Set up a composition that needs to be committed.
    std::string compositionText("hello");

    WebVector<WebCompositionUnderline> emptyUnderlines;
    webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 3, 3);

    WebTextInputInfo info = webView->textInputInfo();
    EXPECT_EQ("hello", std::string(info.value.utf8().data()));
    EXPECT_EQ(3, info.selectionStart);
    EXPECT_EQ(3, info.selectionEnd);
    EXPECT_EQ(0, info.compositionStart);
    EXPECT_EQ(5, info.compositionEnd);

    webView->confirmComposition(WebWidget::KeepSelection);
    info = webView->textInputInfo();
    EXPECT_EQ(3, info.selectionStart);
    EXPECT_EQ(3, info.selectionEnd);
    EXPECT_EQ(-1, info.compositionStart);
    EXPECT_EQ(-1, info.compositionEnd);

    webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 3, 3);
    info = webView->textInputInfo();
    EXPECT_EQ("helhellolo", std::string(info.value.utf8().data()));
    EXPECT_EQ(6, info.selectionStart);
    EXPECT_EQ(6, info.selectionEnd);
    EXPECT_EQ(3, info.compositionStart);
    EXPECT_EQ(8, info.compositionEnd);

    webView->confirmComposition(WebWidget::DoNotKeepSelection);
    info = webView->textInputInfo();
    EXPECT_EQ(8, info.selectionStart);
    EXPECT_EQ(8, info.selectionEnd);
    EXPECT_EQ(-1, info.compositionStart);
    EXPECT_EQ(-1, info.compositionEnd);
}

TEST_F(WebViewTest, FinishCompositionDoesNotRevealSelection)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("form_with_input.html"));
    WebViewImpl* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "form_with_input.html");
    webView->resize(WebSize(800, 600));
    webView->setInitialFocus(false);
    EXPECT_EQ(0, webView->mainFrame()->scrollOffset().width);
    EXPECT_EQ(0, webView->mainFrame()->scrollOffset().height);

    // Set up a composition from existing text that needs to be committed.
    Vector<CompositionUnderline> emptyUnderlines;
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    frame->frame()->inputMethodController().setCompositionFromExistingText(emptyUnderlines, 3, 3);

    // Scroll the input field out of the viewport.
    Element* element = static_cast<Element*>(webView->mainFrame()->document().getElementById("btn"));
    element->scrollIntoView();
    float offsetHeight = webView->mainFrame()->scrollOffset().height;
    EXPECT_EQ(0, webView->mainFrame()->scrollOffset().width);
    EXPECT_LT(0, offsetHeight);

    WebTextInputInfo info = webView->textInputInfo();
    EXPECT_EQ("hello", std::string(info.value.utf8().data()));

    // Verify that the input field is not scrolled back into the viewport.
    webView->confirmComposition(WebWidget::DoNotKeepSelection);
    EXPECT_EQ(0, webView->mainFrame()->scrollOffset().width);
    EXPECT_EQ(offsetHeight, webView->mainFrame()->scrollOffset().height);
}

TEST_F(WebViewTest, InsertNewLinePlacementAfterConfirmComposition)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("text_area_populated.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "text_area_populated.html");
    webView->setInitialFocus(false);

    WebVector<WebCompositionUnderline> emptyUnderlines;

    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    frame->setEditableSelectionOffsets(4, 4);
    frame->setCompositionFromExistingText(8, 12, emptyUnderlines);

    WebTextInputInfo info = webView->textInputInfo();
    EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
    EXPECT_EQ(4, info.selectionStart);
    EXPECT_EQ(4, info.selectionEnd);
    EXPECT_EQ(8, info.compositionStart);
    EXPECT_EQ(12, info.compositionEnd);

    webView->confirmComposition(WebWidget::KeepSelection);
    info = webView->textInputInfo();
    EXPECT_EQ(4, info.selectionStart);
    EXPECT_EQ(4, info.selectionEnd);
    EXPECT_EQ(-1, info.compositionStart);
    EXPECT_EQ(-1, info.compositionEnd);

    std::string compositionText("\n");
    webView->confirmComposition(WebString::fromUTF8(compositionText.c_str()));
    info = webView->textInputInfo();
    EXPECT_EQ(5, info.selectionStart);
    EXPECT_EQ(5, info.selectionEnd);
    EXPECT_EQ(-1, info.compositionStart);
    EXPECT_EQ(-1, info.compositionEnd);
    EXPECT_EQ("0123\n456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
}

TEST_F(WebViewTest, ExtendSelectionAndDelete)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    webView->setInitialFocus(false);
    frame->setEditableSelectionOffsets(10, 10);
    frame->extendSelectionAndDelete(5, 8);
    WebTextInputInfo info = webView->textInputInfo();
    EXPECT_EQ("01234ijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
    EXPECT_EQ(5, info.selectionStart);
    EXPECT_EQ(5, info.selectionEnd);
    frame->extendSelectionAndDelete(10, 0);
    info = webView->textInputInfo();
    EXPECT_EQ("ijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
}

TEST_F(WebViewTest, SetCompositionFromExistingText)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
    webView->setInitialFocus(false);
    WebVector<WebCompositionUnderline> underlines(static_cast<size_t>(1));
    underlines[0] = WebCompositionUnderline(0, 4, 0, false, 0);
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    frame->setEditableSelectionOffsets(4, 10);
    frame->setCompositionFromExistingText(8, 12, underlines);
    WebTextInputInfo info = webView->textInputInfo();
    EXPECT_EQ(4, info.selectionStart);
    EXPECT_EQ(10, info.selectionEnd);
    EXPECT_EQ(8, info.compositionStart);
    EXPECT_EQ(12, info.compositionEnd);
    WebVector<WebCompositionUnderline> emptyUnderlines;
    frame->setCompositionFromExistingText(0, 0, emptyUnderlines);
    info = webView->textInputInfo();
    EXPECT_EQ(4, info.selectionStart);
    EXPECT_EQ(10, info.selectionEnd);
    EXPECT_EQ(-1, info.compositionStart);
    EXPECT_EQ(-1, info.compositionEnd);
}

TEST_F(WebViewTest, SetCompositionFromExistingTextInTextArea)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("text_area_populated.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "text_area_populated.html");
    webView->setInitialFocus(false);
    WebVector<WebCompositionUnderline> underlines(static_cast<size_t>(1));
    underlines[0] = WebCompositionUnderline(0, 4, 0, false, 0);
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    frame->setEditableSelectionOffsets(27, 27);
    std::string newLineText("\n");
    webView->confirmComposition(WebString::fromUTF8(newLineText.c_str()));
    WebTextInputInfo info = webView->textInputInfo();
    EXPECT_EQ("0123456789abcdefghijklmnopq\nrstuvwxyz", std::string(info.value.utf8().data()));

    frame->setEditableSelectionOffsets(31, 31);
    frame->setCompositionFromExistingText(30, 34, underlines);
    info = webView->textInputInfo();
    EXPECT_EQ("0123456789abcdefghijklmnopq\nrstuvwxyz", std::string(info.value.utf8().data()));
    EXPECT_EQ(31, info.selectionStart);
    EXPECT_EQ(31, info.selectionEnd);
    EXPECT_EQ(30, info.compositionStart);
    EXPECT_EQ(34, info.compositionEnd);

    std::string compositionText("yolo");
    webView->confirmComposition(WebString::fromUTF8(compositionText.c_str()));
    info = webView->textInputInfo();
    EXPECT_EQ("0123456789abcdefghijklmnopq\nrsyoloxyz", std::string(info.value.utf8().data()));
    EXPECT_EQ(34, info.selectionStart);
    EXPECT_EQ(34, info.selectionEnd);
    EXPECT_EQ(-1, info.compositionStart);
    EXPECT_EQ(-1, info.compositionEnd);
}

TEST_F(WebViewTest, SetCompositionFromExistingTextInRichText)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_editable_rich_text.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "content_editable_rich_text.html");
    webView->setInitialFocus(false);
    WebVector<WebCompositionUnderline> underlines(static_cast<size_t>(1));
    underlines[0] = WebCompositionUnderline(0, 4, 0, false, 0);
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    frame->setEditableSelectionOffsets(1, 1);
    WebDocument document = webView->mainFrame()->document();
    EXPECT_FALSE(document.getElementById("bold").isNull());
    frame->setCompositionFromExistingText(0, 4, underlines);
    EXPECT_FALSE(document.getElementById("bold").isNull());
}

TEST_F(WebViewTest, SetEditableSelectionOffsetsKeepsComposition)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
    webView->setInitialFocus(false);

    std::string compositionTextFirst("hello ");
    std::string compositionTextSecond("world");
    WebVector<WebCompositionUnderline> emptyUnderlines;

    webView->confirmComposition(WebString::fromUTF8(compositionTextFirst.c_str()));
    webView->setComposition(WebString::fromUTF8(compositionTextSecond.c_str()), emptyUnderlines, 5, 5);

    WebTextInputInfo info = webView->textInputInfo();
    EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
    EXPECT_EQ(11, info.selectionStart);
    EXPECT_EQ(11, info.selectionEnd);
    EXPECT_EQ(6, info.compositionStart);
    EXPECT_EQ(11, info.compositionEnd);

    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    frame->setEditableSelectionOffsets(6, 6);
    info = webView->textInputInfo();
    EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
    EXPECT_EQ(6, info.selectionStart);
    EXPECT_EQ(6, info.selectionEnd);
    EXPECT_EQ(6, info.compositionStart);
    EXPECT_EQ(11, info.compositionEnd);

    frame->setEditableSelectionOffsets(8, 8);
    info = webView->textInputInfo();
    EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
    EXPECT_EQ(8, info.selectionStart);
    EXPECT_EQ(8, info.selectionEnd);
    EXPECT_EQ(6, info.compositionStart);
    EXPECT_EQ(11, info.compositionEnd);

    frame->setEditableSelectionOffsets(11, 11);
    info = webView->textInputInfo();
    EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
    EXPECT_EQ(11, info.selectionStart);
    EXPECT_EQ(11, info.selectionEnd);
    EXPECT_EQ(6, info.compositionStart);
    EXPECT_EQ(11, info.compositionEnd);

    frame->setEditableSelectionOffsets(6, 11);
    info = webView->textInputInfo();
    EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
    EXPECT_EQ(6, info.selectionStart);
    EXPECT_EQ(11, info.selectionEnd);
    EXPECT_EQ(6, info.compositionStart);
    EXPECT_EQ(11, info.compositionEnd);

    frame->setEditableSelectionOffsets(2, 2);
    info = webView->textInputInfo();
    EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
    EXPECT_EQ(2, info.selectionStart);
    EXPECT_EQ(2, info.selectionEnd);
    EXPECT_EQ(-1, info.compositionStart);
    EXPECT_EQ(-1, info.compositionEnd);
}

TEST_F(WebViewTest, IsSelectionAnchorFirst)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
    WebFrame* frame = webView->mainFrame();

    webView->setInitialFocus(false);
    frame->setEditableSelectionOffsets(4, 10);
    EXPECT_TRUE(webView->isSelectionAnchorFirst());
    WebRect anchor;
    WebRect focus;
    webView->selectionBounds(anchor, focus);
    frame->selectRange(WebPoint(focus.x, focus.y), WebPoint(anchor.x, anchor.y));
    EXPECT_FALSE(webView->isSelectionAnchorFirst());
}

TEST_F(WebViewTest, ExitingDeviceEmulationResetsPageScale)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("200-by-300.html"));
    WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "200-by-300.html");
    webViewImpl->resize(WebSize(200, 300));

    float pageScaleExpected = webViewImpl->pageScaleFactor();

    WebDeviceEmulationParams params;
    params.screenPosition = WebDeviceEmulationParams::Desktop;
    params.deviceScaleFactor = 0;
    params.fitToView = false;
    params.offset = WebFloatPoint();
    params.scale = 1;

    webViewImpl->enableDeviceEmulation(params);

    webViewImpl->setPageScaleFactor(2);

    webViewImpl->disableDeviceEmulation();

    EXPECT_EQ(pageScaleExpected, webViewImpl->pageScaleFactor());
}

TEST_F(WebViewTest, HistoryResetScrollAndScaleState)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("200-by-300.html"));
    WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "200-by-300.html");
    webViewImpl->resize(WebSize(100, 150));
    webViewImpl->updateAllLifecyclePhases();
    EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
    EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);

    // Make the page scale and scroll with the given paremeters.
    webViewImpl->setPageScaleFactor(2.0f);
    webViewImpl->mainFrame()->setScrollOffset(WebSize(94, 111));
    EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
    EXPECT_EQ(94, webViewImpl->mainFrame()->scrollOffset().width);
    EXPECT_EQ(111, webViewImpl->mainFrame()->scrollOffset().height);
    LocalFrame* mainFrameLocal = toLocalFrame(webViewImpl->page()->mainFrame());
    mainFrameLocal->loader().saveScrollState();
    EXPECT_EQ(2.0f, mainFrameLocal->loader().currentItem()->pageScaleFactor());
    EXPECT_EQ(94, mainFrameLocal->loader().currentItem()->scrollPoint().x());
    EXPECT_EQ(111, mainFrameLocal->loader().currentItem()->scrollPoint().y());

    // Confirm that resetting the page state resets the saved scroll position.
    webViewImpl->resetScrollAndScaleState();
    EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
    EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
    EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
    EXPECT_EQ(1.0f, mainFrameLocal->loader().currentItem()->pageScaleFactor());
    EXPECT_EQ(0, mainFrameLocal->loader().currentItem()->scrollPoint().x());
    EXPECT_EQ(0, mainFrameLocal->loader().currentItem()->scrollPoint().y());
}

TEST_F(WebViewTest, BackForwardRestoreScroll)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("back_forward_restore_scroll.html"));
    WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "back_forward_restore_scroll.html");
    webViewImpl->resize(WebSize(640, 480));
    webViewImpl->updateAllLifecyclePhases();

    // Emulate a user scroll
    webViewImpl->mainFrame()->setScrollOffset(WebSize(0, 900));
    LocalFrame* mainFrameLocal = toLocalFrame(webViewImpl->page()->mainFrame());
    Persistent<HistoryItem> item1 = mainFrameLocal->loader().currentItem();

    // Click an anchor
    mainFrameLocal->loader().load(FrameLoadRequest(mainFrameLocal->document(), ResourceRequest(mainFrameLocal->document()->completeURL("#a"))));
    Persistent<HistoryItem> item2 = mainFrameLocal->loader().currentItem();

    // Go back, then forward, then back again.
    mainFrameLocal->loader().load(
        FrameLoadRequest(nullptr, FrameLoader::resourceRequestFromHistoryItem(item1.get(), WebCachePolicy::UseProtocolCachePolicy)),
        FrameLoadTypeBackForward, item1.get(), HistorySameDocumentLoad);
    mainFrameLocal->loader().load(
        FrameLoadRequest(nullptr, FrameLoader::resourceRequestFromHistoryItem(item2.get(), WebCachePolicy::UseProtocolCachePolicy)),
        FrameLoadTypeBackForward, item2.get(), HistorySameDocumentLoad);
    mainFrameLocal->loader().load(
        FrameLoadRequest(nullptr, FrameLoader::resourceRequestFromHistoryItem(item1.get(), WebCachePolicy::UseProtocolCachePolicy)),
        FrameLoadTypeBackForward, item1.get(), HistorySameDocumentLoad);

    // Click a different anchor
    mainFrameLocal->loader().load(FrameLoadRequest(mainFrameLocal->document(), ResourceRequest(mainFrameLocal->document()->completeURL("#b"))));
    Persistent<HistoryItem> item3 = mainFrameLocal->loader().currentItem();

    // Go back, then forward. The scroll position should be properly set on the forward navigation.
    mainFrameLocal->loader().load(
        FrameLoadRequest(nullptr, FrameLoader::resourceRequestFromHistoryItem(item1.get(), WebCachePolicy::UseProtocolCachePolicy)),
        FrameLoadTypeBackForward, item1.get(), HistorySameDocumentLoad);
    mainFrameLocal->loader().load(
        FrameLoadRequest(nullptr, FrameLoader::resourceRequestFromHistoryItem(item3.get(), WebCachePolicy::UseProtocolCachePolicy)),
        FrameLoadTypeBackForward, item3.get(), HistorySameDocumentLoad);
    EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
    EXPECT_GT(webViewImpl->mainFrame()->scrollOffset().height, 2000);
}

TEST_F(WebViewTest, EnterFullscreenResetScrollAndScaleState)
{
    FrameTestHelpers::TestWebViewClient client;
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("200-by-300.html"));
    WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "200-by-300.html", true, 0, &client);
    webViewImpl->resize(WebSize(100, 150));
    webViewImpl->updateAllLifecyclePhases();
    EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
    EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);

    // Make the page scale and scroll with the given paremeters.
    webViewImpl->setPageScaleFactor(2.0f);
    webViewImpl->mainFrame()->setScrollOffset(WebSize(94, 111));
    webViewImpl->setVisualViewportOffset(WebFloatPoint(12, 20));
    EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
    EXPECT_EQ(94, webViewImpl->mainFrame()->scrollOffset().width);
    EXPECT_EQ(111, webViewImpl->mainFrame()->scrollOffset().height);
    EXPECT_EQ(12, webViewImpl->visualViewportOffset().x);
    EXPECT_EQ(20, webViewImpl->visualViewportOffset().y);

    Element* element = static_cast<Element*>(webViewImpl->mainFrame()->document().body());
    webViewImpl->enterFullScreenForElement(element);
    webViewImpl->didEnterFullScreen();

    // Page scale factor must be 1.0 during fullscreen for elements to be sized
    // properly.
    EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());

    // Make sure fullscreen nesting doesn't disrupt scroll/scale saving.
    Element* otherElement = static_cast<Element*>(webViewImpl->mainFrame()->document().head());
    webViewImpl->enterFullScreenForElement(otherElement);

    // Confirm that exiting fullscreen restores the parameters.
    webViewImpl->didExitFullScreen();
    EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
    EXPECT_EQ(94, webViewImpl->mainFrame()->scrollOffset().width);
    EXPECT_EQ(111, webViewImpl->mainFrame()->scrollOffset().height);
    EXPECT_EQ(12, webViewImpl->visualViewportOffset().x);
    EXPECT_EQ(20, webViewImpl->visualViewportOffset().y);

    m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
}

class PrintWebViewClient : public FrameTestHelpers::TestWebViewClient {
public:
    PrintWebViewClient()
        : m_printCalled(false)
    {
    }

    // WebViewClient methods
    void printPage(WebLocalFrame*) override
    {
        m_printCalled = true;
    }

    bool printCalled() const { return m_printCalled; }

private:
    bool m_printCalled;
};


TEST_F(WebViewTest, PrintWithXHRInFlight)
{
    PrintWebViewClient client;
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("print_with_xhr_inflight.html"));
    WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "print_with_xhr_inflight.html", true, 0, &client);

    ASSERT_TRUE(toLocalFrame(webViewImpl->page()->mainFrame())->document()->loadEventFinished());
    EXPECT_TRUE(client.printCalled());
    m_webViewHelper.reset();
}

static void DragAndDropURL(WebViewImpl* webView, const std::string& url)
{
    WebDragData dragData;
    dragData.initialize();

    WebDragData::Item item;
    item.storageType = WebDragData::Item::StorageTypeString;
    item.stringType = "text/uri-list";
    item.stringData = WebString::fromUTF8(url);
    dragData.addItem(item);

    const WebPoint clientPoint(0, 0);
    const WebPoint screenPoint(0, 0);
    webView->dragTargetDragEnter(dragData, clientPoint, screenPoint, WebDragOperationCopy, 0);
    webView->dragTargetDrop(clientPoint, screenPoint, 0);
    FrameTestHelpers::pumpPendingRequestsForFrameToLoad(webView->mainFrame());
}

TEST_F(WebViewTest, DragDropURL)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "foo.html");
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "bar.html");

    const std::string fooUrl = m_baseURL + "foo.html";
    const std::string barUrl = m_baseURL + "bar.html";

    WebViewImpl* webView = m_webViewHelper.initializeAndLoad(fooUrl);

    ASSERT_TRUE(webView);

    // Drag and drop barUrl and verify that we've navigated to it.
    DragAndDropURL(webView, barUrl);
    EXPECT_EQ(barUrl, webView->mainFrame()->document().url().string().utf8());

    // Drag and drop fooUrl and verify that we've navigated back to it.
    DragAndDropURL(webView, fooUrl);
    EXPECT_EQ(fooUrl, webView->mainFrame()->document().url().string().utf8());

    // Disable navigation on drag-and-drop.
    webView->settingsImpl()->setNavigateOnDragDrop(false);

    // Attempt to drag and drop to barUrl and verify that no navigation has occurred.
    DragAndDropURL(webView, barUrl);
    EXPECT_EQ(fooUrl, webView->mainFrame()->document().url().string().utf8());
}

class ContentDetectorClient : public FrameTestHelpers::TestWebViewClient {
public:
    ContentDetectorClient() { reset(); }

    WebContentDetectionResult detectContentAround(const WebHitTestResult& hitTest) override
    {
        m_contentDetectionRequested = true;
        return m_contentDetectionResult;
    }

    void scheduleContentIntent(const WebURL& url, bool isMainFrame) override
    {
        m_scheduledIntentURL = url;
        m_wasInMainFrame = isMainFrame;
    }

    void cancelScheduledContentIntents() override
    {
        m_pendingIntentsCancelled = true;
    }

    void reset()
    {
        m_contentDetectionRequested = false;
        m_pendingIntentsCancelled = false;
        m_scheduledIntentURL = WebURL();
        m_wasInMainFrame = false;
        m_contentDetectionResult = WebContentDetectionResult();
    }

    bool contentDetectionRequested() const { return m_contentDetectionRequested; }
    bool pendingIntentsCancelled() const { return m_pendingIntentsCancelled; }
    const WebURL& scheduledIntentURL() const { return m_scheduledIntentURL; }
    bool wasInMainFrame() const { return m_wasInMainFrame; }
    void setContentDetectionResult(const WebContentDetectionResult& result) { m_contentDetectionResult = result; }

private:
    bool m_contentDetectionRequested;
    bool m_pendingIntentsCancelled;
    WebURL m_scheduledIntentURL;
    bool m_wasInMainFrame;
    WebContentDetectionResult m_contentDetectionResult;
};

bool WebViewTest::tapElement(WebInputEvent::Type type, Element* element)
{
    if (!element || !element->layoutObject())
        return false;

    DCHECK(m_webViewHelper.webView());
    element->scrollIntoViewIfNeeded();

    // TODO(bokan): Technically incorrect, event positions should be in viewport space. crbug.com/371902.
    IntPoint center = m_webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsToScreen(
        element->layoutObject()->absoluteBoundingBoxRect()).center();

    WebGestureEvent event;
    event.type = type;
    event.sourceDevice = WebGestureDeviceTouchscreen;
    event.x = center.x();
    event.y = center.y();

    m_webViewHelper.webView()->handleInputEvent(event);
    runPendingTasks();
    return true;
}

bool WebViewTest::tapElementById(WebInputEvent::Type type, const WebString& id)
{
    DCHECK(m_webViewHelper.webView());
    Element* element = static_cast<Element*>(m_webViewHelper.webView()->mainFrame()->document().getElementById(id));
    return tapElement(type, element);
}

TEST_F(WebViewTest, DetectContentAroundPosition)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_listeners.html"));

    ContentDetectorClient client;
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "content_listeners.html", true, 0, &client);
    webView->resize(WebSize(500, 300));
    webView->updateAllLifecyclePhases();
    runPendingTasks();

    WebString clickListener = WebString::fromUTF8("clickListener");
    WebString touchstartListener = WebString::fromUTF8("touchstartListener");
    WebString mousedownListener = WebString::fromUTF8("mousedownListener");
    WebString noListener = WebString::fromUTF8("noListener");
    WebString link = WebString::fromUTF8("link");

    // Ensure content detection is not requested for nodes listening to click,
    // mouse or touch events when we do simple taps.
    EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, clickListener));
    EXPECT_FALSE(client.contentDetectionRequested());
    client.reset();

    EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, touchstartListener));
    EXPECT_FALSE(client.contentDetectionRequested());
    client.reset();

    EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, mousedownListener));
    EXPECT_FALSE(client.contentDetectionRequested());
    client.reset();

    // Content detection should work normally without these event listeners.
    // The click listener in the body should be ignored as a special case.
    EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, noListener));
    EXPECT_TRUE(client.contentDetectionRequested());
    EXPECT_FALSE(client.scheduledIntentURL().isValid());

    WebURL intentURL = toKURL(m_baseURL);
    client.setContentDetectionResult(WebContentDetectionResult(WebRange(), WebString(), intentURL));
    EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, noListener));
    EXPECT_TRUE(client.scheduledIntentURL() == intentURL);
    EXPECT_TRUE(client.wasInMainFrame());

    // Tapping elsewhere should cancel the scheduled intent.
    WebGestureEvent event;
    event.type = WebInputEvent::GestureTap;
    event.sourceDevice = WebGestureDeviceTouchscreen;
    webView->handleInputEvent(event);
    runPendingTasks();
    EXPECT_TRUE(client.pendingIntentsCancelled());

    m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
}

TEST_F(WebViewTest, ContentDetectionInIframe)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_listeners_iframe.html"));

    ContentDetectorClient client;
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "content_listeners_iframe.html", true, 0, &client);
    webView->resize(WebSize(500, 300));
    webView->updateAllLifecyclePhases();
    runPendingTasks();

    WebString noListener = WebString::fromUTF8("noListener");
    WebString frameName = WebString::fromUTF8("innerFrame");

    WebURL intentURL = toKURL(m_baseURL);
    client.setContentDetectionResult(WebContentDetectionResult(WebRange(), WebString(), intentURL));
    Element* element = static_cast<Element*>(webView->findFrameByName(frameName)->document().getElementById(noListener));
    EXPECT_TRUE(tapElement(WebInputEvent::GestureTap, element));
    EXPECT_TRUE(client.scheduledIntentURL() == intentURL);
    EXPECT_FALSE(client.wasInMainFrame());

    m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
}

TEST_F(WebViewTest, ClientTapHandling)
{
    TapHandlingWebViewClient client;
    client.reset();
    WebView* webView = m_webViewHelper.initializeAndLoad("about:blank", true, 0, &client);
    WebGestureEvent event;
    event.type = WebInputEvent::GestureTap;
    event.sourceDevice = WebGestureDeviceTouchscreen;
    event.x = 3;
    event.y = 8;
    webView->handleInputEvent(event);
    runPendingTasks();
    EXPECT_EQ(3, client.tapX());
    EXPECT_EQ(8, client.tapY());
    client.reset();
    event.type = WebInputEvent::GestureLongPress;
    event.x = 25;
    event.y = 7;
    webView->handleInputEvent(event);
    runPendingTasks();
    EXPECT_EQ(25, client.longpressX());
    EXPECT_EQ(7, client.longpressY());

    m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
}

TEST_F(WebViewTest, ClientTapHandlingNullWebViewClient)
{
    WebViewImpl* webView = WebViewImpl::create(nullptr);
    WebLocalFrame* localFrame = WebLocalFrame::create(WebTreeScopeType::Document, nullptr);
    webView->setMainFrame(localFrame);
    WebGestureEvent event;
    event.type = WebInputEvent::GestureTap;
    event.sourceDevice = WebGestureDeviceTouchscreen;
    event.x = 3;
    event.y = 8;
    EXPECT_EQ(WebInputEventResult::NotHandled, webView->handleInputEvent(event));
    webView->close();
    // Explicitly close as the frame as no frame client to do so on frameDetached().
    localFrame->close();
}

TEST_F(WebViewTest, LongPressEmptyDiv)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()),
        WebString::fromUTF8("long_press_empty_div.html"));

    WebViewImpl* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "long_press_empty_div.html", true);
    webView->settingsImpl()->setAlwaysShowContextMenuOnTouch(false);
    webView->resize(WebSize(500, 300));
    webView->updateAllLifecyclePhases();
    runPendingTasks();

    WebGestureEvent event;
    event.type = WebInputEvent::GestureLongPress;
    event.sourceDevice = WebGestureDeviceTouchscreen;
    event.x = 250;
    event.y = 150;

    EXPECT_EQ(WebInputEventResult::NotHandled, webView->handleInputEvent(event));
}

TEST_F(WebViewTest, LongPressEmptyDivAlwaysShow)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()),
        WebString::fromUTF8("long_press_empty_div.html"));

    WebViewImpl* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "long_press_empty_div.html", true);
    webView->settingsImpl()->setAlwaysShowContextMenuOnTouch(true);
    webView->resize(WebSize(500, 300));
    webView->updateAllLifecyclePhases();
    runPendingTasks();

    WebGestureEvent event;
    event.type = WebInputEvent::GestureLongPress;
    event.sourceDevice = WebGestureDeviceTouchscreen;
    event.x = 250;
    event.y = 150;

    EXPECT_EQ(WebInputEventResult::HandledSystem, webView->handleInputEvent(event));
}

TEST_F(WebViewTest, LongPressImage)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()),
        WebString::fromUTF8("long_press_image.html"));

    WebViewImpl* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "long_press_image.html", true);
    webView->settingsImpl()->setAlwaysShowContextMenuOnTouch(false);
    webView->resize(WebSize(500, 300));
    webView->updateAllLifecyclePhases();
    runPendingTasks();

    WebGestureEvent event;
    event.type = WebInputEvent::GestureLongPress;
    event.sourceDevice = WebGestureDeviceTouchscreen;
    event.x = 10;
    event.y = 10;

    EXPECT_EQ(WebInputEventResult::HandledSystem, webView->handleInputEvent(event));
}

TEST_F(WebViewTest, LongPressVideo)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()),
        WebString::fromUTF8("long_press_video.html"));

    WebViewImpl* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "long_press_video.html", true);
    webView->settingsImpl()->setAlwaysShowContextMenuOnTouch(false);
    webView->resize(WebSize(500, 300));
    webView->updateAllLifecyclePhases();
    runPendingTasks();

    WebGestureEvent event;
    event.type = WebInputEvent::GestureLongPress;
    event.sourceDevice = WebGestureDeviceTouchscreen;
    event.x = 10;
    event.y = 10;

    EXPECT_EQ(WebInputEventResult::HandledSystem, webView->handleInputEvent(event));
}

TEST_F(WebViewTest, LongPressLink)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()),
        WebString::fromUTF8("long_press_link.html"));

    WebViewImpl* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "long_press_link.html", true);
    webView->settingsImpl()->setAlwaysShowContextMenuOnTouch(false);
    webView->resize(WebSize(500, 300));
    webView->updateAllLifecyclePhases();
    runPendingTasks();

    WebGestureEvent event;
    event.type = WebInputEvent::GestureLongPress;
    event.sourceDevice = WebGestureDeviceTouchscreen;
    event.x = 500;
    event.y = 300;

    EXPECT_EQ(WebInputEventResult::HandledSystem, webView->handleInputEvent(event));
}

TEST_F(WebViewTest, LongPressEmptyEditableSelection)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()),
        WebString::fromUTF8("long_press_empty_editable_selection.html"));

    WebViewImpl* webView = m_webViewHelper.initializeAndLoad(
        m_baseURL + "long_press_empty_editable_selection.html", true);
    webView->settingsImpl()->setAlwaysShowContextMenuOnTouch(false);
    webView->resize(WebSize(500, 300));
    webView->updateAllLifecyclePhases();
    runPendingTasks();

    WebGestureEvent event;
    event.type = WebInputEvent::GestureLongPress;
    event.sourceDevice = WebGestureDeviceTouchscreen;
    event.x = 10;
    event.y = 10;

    EXPECT_EQ(WebInputEventResult::HandledSystem, webView->handleInputEvent(event));
}

TEST_F(WebViewTest, LongPressSelection)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html"));

    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "longpress_selection.html", true);
    webView->resize(WebSize(500, 300));
    webView->updateAllLifecyclePhases();
    runPendingTasks();

    WebString target = WebString::fromUTF8("target");
    WebString onselectstartfalse = WebString::fromUTF8("onselectstartfalse");
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());

    EXPECT_TRUE(tapElementById(WebInputEvent::GestureLongPress, onselectstartfalse));
    EXPECT_EQ("", std::string(frame->selectionAsText().utf8().data()));
    EXPECT_TRUE(tapElementById(WebInputEvent::GestureLongPress, target));
    EXPECT_EQ("testword", std::string(frame->selectionAsText().utf8().data()));
}

#if !OS(MACOSX)
TEST_F(WebViewTest, LongPressEmptyTextarea)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_textarea.html"));

    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "longpress_textarea.html", true);
    webView->resize(WebSize(500, 300));
    webView->updateAllLifecyclePhases();
    runPendingTasks();

    WebString blanklinestextbox = WebString::fromUTF8("blanklinestextbox");
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());

    EXPECT_TRUE(tapElementById(WebInputEvent::GestureLongPress, blanklinestextbox));
    EXPECT_EQ("", std::string(frame->selectionAsText().utf8().data()));
}
#endif

TEST_F(WebViewTest, LongPressImageTextarea)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_image_contenteditable.html"));

    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "longpress_image_contenteditable.html", true);
    webView->resize(WebSize(500, 300));
    webView->updateAllLifecyclePhases();
    runPendingTasks();

    WebString image = WebString::fromUTF8("purpleimage");

    EXPECT_TRUE(tapElementById(WebInputEvent::GestureLongPress, image));
    size_t location, length;
    EXPECT_TRUE(toWebViewImpl(webView)->caretOrSelectionRange(&location, &length));
    EXPECT_EQ(0UL, location);
    EXPECT_EQ(1UL, length);
}

TEST_F(WebViewTest, BlinkCaretAfterLongPress)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("blink_caret_on_typing_after_long_press.html"));

    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "blink_caret_on_typing_after_long_press.html", true);
    webView->resize(WebSize(640, 480));
    webView->updateAllLifecyclePhases();
    runPendingTasks();

    WebString target = WebString::fromUTF8("target");
    WebLocalFrameImpl* mainFrame = toWebLocalFrameImpl(webView->mainFrame());

    EXPECT_TRUE(tapElementById(WebInputEvent::GestureLongPress, target));
    EXPECT_FALSE(mainFrame->frame()->selection().isCaretBlinkingSuspended());
}

TEST_F(WebViewTest, BlinkCaretOnClosingContextMenu)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("form.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "form.html", true);

    webView->setInitialFocus(false);
    runPendingTasks();

    // We suspend caret blinking when pressing with mouse right button.
    // Note that we do not send MouseUp event here since it will be consumed
    // by the context menu once it shows up.
    WebMouseEvent mouseEvent;
    mouseEvent.button = WebMouseEvent::ButtonRight;
    mouseEvent.x = 1;
    mouseEvent.y = 1;
    mouseEvent.clickCount = 1;
    mouseEvent.type = WebInputEvent::MouseDown;
    webView->handleInputEvent(mouseEvent);
    runPendingTasks();

    WebLocalFrameImpl* mainFrame = toWebLocalFrameImpl(webView->mainFrame());
    EXPECT_TRUE(mainFrame->frame()->selection().isCaretBlinkingSuspended());

    // Caret blinking is still suspended after showing context menu.
    webView->showContextMenu();
    EXPECT_TRUE(mainFrame->frame()->selection().isCaretBlinkingSuspended());

    // Caret blinking will be resumed only after context menu is closed.
    webView->didCloseContextMenu();

    EXPECT_FALSE(mainFrame->frame()->selection().isCaretBlinkingSuspended());
}

TEST_F(WebViewTest, SelectionOnReadOnlyInput)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("selection_readonly.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "selection_readonly.html", true);
    webView->resize(WebSize(640, 480));
    webView->updateAllLifecyclePhases();
    runPendingTasks();

    std::string testWord = "This text should be selected.";

    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    EXPECT_EQ(testWord, std::string(frame->selectionAsText().utf8().data()));

    size_t location;
    size_t length;
    EXPECT_TRUE(toWebViewImpl(webView)->caretOrSelectionRange(&location, &length));
    EXPECT_EQ(location, 0UL);
    EXPECT_EQ(length, testWord.length());
}

static void configueCompositingWebView(WebSettings* settings)
{
    settings->setAcceleratedCompositingEnabled(true);
    settings->setPreferCompositingToLCDTextEnabled(true);
}

TEST_F(WebViewTest, ShowPressOnTransformedLink)
{
    OwnPtr<FrameTestHelpers::TestWebViewClient> fakeCompositingWebViewClient = adoptPtr(new FrameTestHelpers::TestWebViewClient());
    FrameTestHelpers::WebViewHelper webViewHelper;
    WebViewImpl* webViewImpl = webViewHelper.initialize(true, nullptr, fakeCompositingWebViewClient.get(), nullptr, &configueCompositingWebView);

    int pageWidth = 640;
    int pageHeight = 480;
    webViewImpl->resize(WebSize(pageWidth, pageHeight));

    WebURL baseURL = URLTestHelpers::toKURL("http://example.com/");
    FrameTestHelpers::loadHTMLString(webViewImpl->mainFrame(), "<a href='http://www.test.com' style='position: absolute; left: 20px; top: 20px; width: 200px; transform:translateZ(0);'>A link to highlight</a>", baseURL);

    WebGestureEvent event;
    event.type = WebInputEvent::GestureShowPress;
    event.sourceDevice = WebGestureDeviceTouchscreen;
    event.x = 20;
    event.y = 20;

    // Just make sure we don't hit any asserts.
    webViewImpl->handleInputEvent(event);
}

class MockAutofillClient : public WebAutofillClient {
public:
    MockAutofillClient()
        : m_ignoreTextChanges(false)
        , m_textChangesFromUserGesture(0)
        , m_textChangesWhileIgnored(0)
        , m_textChangesWhileNotIgnored(0)
        , m_userGestureNotificationsCount(0) {}

    ~MockAutofillClient() override {}

    void setIgnoreTextChanges(bool ignore) override { m_ignoreTextChanges = ignore; }
    void textFieldDidChange(const WebFormControlElement&) override
    {
        if (m_ignoreTextChanges)
            ++m_textChangesWhileIgnored;
        else
            ++m_textChangesWhileNotIgnored;

        if (UserGestureIndicator::processingUserGesture())
            ++m_textChangesFromUserGesture;
    }
    void firstUserGestureObserved() override { ++m_userGestureNotificationsCount; }

    void clearChangeCounts()
    {
        m_textChangesWhileIgnored = 0;
        m_textChangesWhileNotIgnored = 0;
    }

    int textChangesFromUserGesture() { return m_textChangesFromUserGesture; }
    int textChangesWhileIgnored() { return m_textChangesWhileIgnored; }
    int textChangesWhileNotIgnored() { return m_textChangesWhileNotIgnored; }
    int getUserGestureNotificationsCount() { return m_userGestureNotificationsCount; }

private:
    bool m_ignoreTextChanges;
    int m_textChangesFromUserGesture;
    int m_textChangesWhileIgnored;
    int m_textChangesWhileNotIgnored;
    int m_userGestureNotificationsCount;
};


TEST_F(WebViewTest, LosingFocusDoesNotTriggerAutofillTextChange)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
    MockAutofillClient client;
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    frame->setAutofillClient(&client);
    webView->setInitialFocus(false);

    // Set up a composition that needs to be committed.
    WebVector<WebCompositionUnderline> emptyUnderlines;
    frame->setEditableSelectionOffsets(4, 10);
    frame->setCompositionFromExistingText(8, 12, emptyUnderlines);
    WebTextInputInfo info = webView->textInputInfo();
    EXPECT_EQ(4, info.selectionStart);
    EXPECT_EQ(10, info.selectionEnd);
    EXPECT_EQ(8, info.compositionStart);
    EXPECT_EQ(12, info.compositionEnd);

    // Clear the focus and track that the subsequent composition commit does not trigger a
    // text changed notification for autofill.
    client.clearChangeCounts();
    webView->setFocus(false);
    EXPECT_EQ(0, client.textChangesWhileNotIgnored());

    frame->setAutofillClient(0);
}

static void verifySelectionAndComposition(WebView* webView, int selectionStart, int selectionEnd, int compositionStart, int compositionEnd, const char* failMessage)
{
    WebTextInputInfo info = webView->textInputInfo();
    EXPECT_EQ(selectionStart, info.selectionStart) << failMessage;
    EXPECT_EQ(selectionEnd, info.selectionEnd) << failMessage;
    EXPECT_EQ(compositionStart, info.compositionStart) << failMessage;
    EXPECT_EQ(compositionEnd, info.compositionEnd) << failMessage;
}

TEST_F(WebViewTest, CompositionNotCancelledByBackspace)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("composition_not_cancelled_by_backspace.html"));
    MockAutofillClient client;
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "composition_not_cancelled_by_backspace.html");
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    frame->setAutofillClient(&client);
    webView->setInitialFocus(false);

    // Test both input elements.
    for (int i = 0; i < 2; ++i) {
        // Select composition and do sanity check.
        WebVector<WebCompositionUnderline> emptyUnderlines;
        frame->setEditableSelectionOffsets(6, 6);
        EXPECT_TRUE(webView->setComposition("fghij", emptyUnderlines, 0, 5));
        frame->setEditableSelectionOffsets(11, 11);
        verifySelectionAndComposition(webView, 11, 11, 6, 11, "initial case");

        // Press Backspace and verify composition didn't get cancelled. This is to verify the fix
        // for crbug.com/429916.
        WebKeyboardEvent keyEvent;
        keyEvent.domKey = Platform::current()->domKeyEnumFromString("\b");
        keyEvent.windowsKeyCode = VKEY_BACK;
        keyEvent.setKeyIdentifierFromWindowsKeyCode();
        keyEvent.type = WebInputEvent::RawKeyDown;
        webView->handleInputEvent(keyEvent);

        frame->setEditableSelectionOffsets(6, 6);
        EXPECT_TRUE(webView->setComposition("fghi", emptyUnderlines, 0, 4));
        frame->setEditableSelectionOffsets(10, 10);
        verifySelectionAndComposition(webView, 10, 10, 6, 10, "after pressing Backspace");

        keyEvent.type = WebInputEvent::KeyUp;
        webView->handleInputEvent(keyEvent);

        webView->advanceFocus(false);
    }

    frame->setAutofillClient(0);
}

TEST_F(WebViewTest, ConfirmCompositionTriggersAutofillTextChange)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
    MockAutofillClient client;
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    frame->setAutofillClient(&client);
    webView->setInitialFocus(false);

    // Set up a composition that needs to be committed.
    std::string compositionText("testingtext");

    WebVector<WebCompositionUnderline> emptyUnderlines;
    webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 0, compositionText.length());

    WebTextInputInfo info = webView->textInputInfo();
    EXPECT_EQ(0, info.selectionStart);
    EXPECT_EQ((int) compositionText.length(), info.selectionEnd);
    EXPECT_EQ(0, info.compositionStart);
    EXPECT_EQ((int) compositionText.length(), info.compositionEnd);

    client.clearChangeCounts();
    webView->confirmComposition();
    EXPECT_EQ(0, client.textChangesWhileIgnored());
    EXPECT_EQ(1, client.textChangesWhileNotIgnored());

    frame->setAutofillClient(0);
}

TEST_F(WebViewTest, SetCompositionFromExistingTextTriggersAutofillTextChange)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
    MockAutofillClient client;
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html", true);
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    frame->setAutofillClient(&client);
    webView->setInitialFocus(false);

    WebVector<WebCompositionUnderline> emptyUnderlines;

    client.clearChangeCounts();
    frame->setCompositionFromExistingText(8, 12, emptyUnderlines);

    WebTextInputInfo info = webView->textInputInfo();
    EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
    EXPECT_EQ(8, info.compositionStart);
    EXPECT_EQ(12, info.compositionEnd);

    EXPECT_EQ(0, client.textChangesWhileIgnored());
    EXPECT_EQ(0, client.textChangesWhileNotIgnored());

    WebDocument document = webView->mainFrame()->document();
    EXPECT_EQ(WebString::fromUTF8("none"),  document.getElementById("inputEvent").firstChild().nodeValue());

    frame->setAutofillClient(0);
}

class ViewCreatingWebViewClient : public FrameTestHelpers::TestWebViewClient {
public:
    ViewCreatingWebViewClient()
        : m_didFocusCalled(false)
    {
    }

    // WebViewClient methods
    WebView* createView(WebLocalFrame* opener, const WebURLRequest&, const WebWindowFeatures&, const WebString& name, WebNavigationPolicy, bool) override
    {
        return m_webViewHelper.initializeWithOpener(opener, true);
    }

    // WebWidgetClient methods
    void didFocus() override
    {
        m_didFocusCalled = true;
    }

    bool didFocusCalled() const { return m_didFocusCalled; }
    WebView* createdWebView() const { return m_webViewHelper.webView(); }

private:
    FrameTestHelpers::WebViewHelper m_webViewHelper;
    bool m_didFocusCalled;
};

TEST_F(WebViewTest, DoNotFocusCurrentFrameOnNavigateFromLocalFrame)
{
    ViewCreatingWebViewClient client;
    FrameTestHelpers::WebViewHelper m_webViewHelper;
    WebViewImpl* webViewImpl = m_webViewHelper.initialize(true, 0, &client);
    webViewImpl->page()->settings().setJavaScriptCanOpenWindowsAutomatically(true);

    WebURL baseURL = URLTestHelpers::toKURL("http://example.com/");
    FrameTestHelpers::loadHTMLString(webViewImpl->mainFrame(), "<html><body><iframe src=\"about:blank\"></iframe></body></html>", baseURL);

    // Make a request from a local frame.
    WebURLRequest webURLRequestWithTargetStart;
    webURLRequestWithTargetStart.initialize();
    LocalFrame* localFrame = toWebLocalFrameImpl(webViewImpl->mainFrame()->firstChild())->frame();
    FrameLoadRequest requestWithTargetStart(localFrame->document(), webURLRequestWithTargetStart.toResourceRequest(), "_top");
    localFrame->loader().load(requestWithTargetStart);
    EXPECT_FALSE(client.didFocusCalled());

    m_webViewHelper.reset(); // Remove dependency on locally scoped client.
}

TEST_F(WebViewTest, FocusExistingFrameOnNavigate)
{
    ViewCreatingWebViewClient client;
    FrameTestHelpers::WebViewHelper m_webViewHelper;
    WebViewImpl* webViewImpl = m_webViewHelper.initialize(true, 0, &client);
    webViewImpl->page()->settings().setJavaScriptCanOpenWindowsAutomatically(true);
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewImpl->mainFrame());
    frame->setName("_start");

    // Make a request that will open a new window
    WebURLRequest webURLRequest;
    webURLRequest.initialize();
    FrameLoadRequest request(0, webURLRequest.toResourceRequest(), "_blank");
    toLocalFrame(webViewImpl->page()->mainFrame())->loader().load(request);
    ASSERT_TRUE(client.createdWebView());
    EXPECT_FALSE(client.didFocusCalled());

    // Make a request from the new window that will navigate the original window. The original window should be focused.
    WebURLRequest webURLRequestWithTargetStart;
    webURLRequestWithTargetStart.initialize();
    FrameLoadRequest requestWithTargetStart(0, webURLRequestWithTargetStart.toResourceRequest(), "_start");
    toLocalFrame(toWebViewImpl(client.createdWebView())->page()->mainFrame())->loader().load(requestWithTargetStart);
    EXPECT_TRUE(client.didFocusCalled());

    m_webViewHelper.reset(); // Remove dependency on locally scoped client.
}

TEST_F(WebViewTest, DispatchesFocusOutFocusInOnViewToggleFocus)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "focusout_focusin_events.html");
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "focusout_focusin_events.html", true, 0);

    webView->setFocus(true);
    webView->setFocus(false);
    webView->setFocus(true);

    WebElement element = webView->mainFrame()->document().getElementById("message");
    EXPECT_STREQ("focusoutfocusin", element.textContent().utf8().data());
}

TEST_F(WebViewTest, DispatchesDomFocusOutDomFocusInOnViewToggleFocus)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "domfocusout_domfocusin_events.html");
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "domfocusout_domfocusin_events.html", true, 0);

    webView->setFocus(true);
    webView->setFocus(false);
    webView->setFocus(true);

    WebElement element = webView->mainFrame()->document().getElementById("message");
    EXPECT_STREQ("DOMFocusOutDOMFocusIn", element.textContent().utf8().data());
}

static void openDateTimeChooser(WebView* webView, HTMLInputElement* inputElement)
{
    inputElement->focus();

    WebKeyboardEvent keyEvent;
    keyEvent.domKey = Platform::current()->domKeyEnumFromString(" ");
    keyEvent.windowsKeyCode = VKEY_SPACE;
    keyEvent.type = WebInputEvent::RawKeyDown;
    keyEvent.setKeyIdentifierFromWindowsKeyCode();
    webView->handleInputEvent(keyEvent);

    keyEvent.type = WebInputEvent::KeyUp;
    webView->handleInputEvent(keyEvent);
}

// TODO(crbug.com/605112) This test is crashing on Android (Nexus 4) bot.
#if OS(ANDROID)
#define MAYBE_ChooseValueFromDateTimeChooser DISABLED_ChooseValueFromDateTimeChooser
#else
#define MAYBE_ChooseValueFromDateTimeChooser ChooseValueFromDateTimeChooser
#endif
TEST_F(WebViewTest, MAYBE_ChooseValueFromDateTimeChooser)
{
    bool originalMultipleFieldsFlag = RuntimeEnabledFeatures::inputMultipleFieldsUIEnabled();
    RuntimeEnabledFeatures::setInputMultipleFieldsUIEnabled(false);
    DateTimeChooserWebViewClient client;
    std::string url = m_baseURL + "date_time_chooser.html";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "date_time_chooser.html");
    WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true, 0, &client);

    Document* document = webViewImpl->mainFrameImpl()->frame()->document();

    HTMLInputElement* inputElement;

    inputElement = toHTMLInputElement(document->getElementById("date"));
    openDateTimeChooser(webViewImpl, inputElement);
    client.chooserCompletion()->didChooseValue(0);
    client.clearChooserCompletion();
    EXPECT_STREQ("1970-01-01", inputElement->value().utf8().data());

    openDateTimeChooser(webViewImpl, inputElement);
    client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
    client.clearChooserCompletion();
    EXPECT_STREQ("", inputElement->value().utf8().data());

    inputElement = toHTMLInputElement(document->getElementById("datetimelocal"));
    openDateTimeChooser(webViewImpl, inputElement);
    client.chooserCompletion()->didChooseValue(0);
    client.clearChooserCompletion();
    EXPECT_STREQ("1970-01-01T00:00", inputElement->value().utf8().data());

    openDateTimeChooser(webViewImpl, inputElement);
    client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
    client.clearChooserCompletion();
    EXPECT_STREQ("", inputElement->value().utf8().data());

    inputElement = toHTMLInputElement(document->getElementById("month"));
    openDateTimeChooser(webViewImpl, inputElement);
    client.chooserCompletion()->didChooseValue(0);
    client.clearChooserCompletion();
    EXPECT_STREQ("1970-01", inputElement->value().utf8().data());

    openDateTimeChooser(webViewImpl, inputElement);
    client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
    client.clearChooserCompletion();
    EXPECT_STREQ("", inputElement->value().utf8().data());

    inputElement = toHTMLInputElement(document->getElementById("time"));
    openDateTimeChooser(webViewImpl, inputElement);
    client.chooserCompletion()->didChooseValue(0);
    client.clearChooserCompletion();
    EXPECT_STREQ("00:00", inputElement->value().utf8().data());

    openDateTimeChooser(webViewImpl, inputElement);
    client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
    client.clearChooserCompletion();
    EXPECT_STREQ("", inputElement->value().utf8().data());

    inputElement = toHTMLInputElement(document->getElementById("week"));
    openDateTimeChooser(webViewImpl, inputElement);
    client.chooserCompletion()->didChooseValue(0);
    client.clearChooserCompletion();
    EXPECT_STREQ("1970-W01", inputElement->value().utf8().data());

    openDateTimeChooser(webViewImpl, inputElement);
    client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
    client.clearChooserCompletion();
    EXPECT_STREQ("", inputElement->value().utf8().data());

    // Clear the WebViewClient from the webViewHelper to avoid use-after-free in the
    // WebViewHelper destructor.
    m_webViewHelper.reset();
    RuntimeEnabledFeatures::setInputMultipleFieldsUIEnabled(originalMultipleFieldsFlag);
}

TEST_F(WebViewTest, DispatchesFocusBlurOnViewToggle)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "focus_blur_events.html");
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "focus_blur_events.html", true, 0);

    webView->setFocus(true);
    webView->setFocus(false);
    webView->setFocus(true);

    WebElement element = webView->mainFrame()->document().getElementById("message");
    // Expect not to see duplication of events.
    EXPECT_STREQ("blurfocus", element.textContent().utf8().data());
}

TEST_F(WebViewTest, SmartClipData)
{
    static const char kExpectedClipText[] = "\nPrice 10,000,000won";
    static const char kExpectedClipHtml[] =
        "<div id=\"div4\" style=\"padding: 10px; margin: 10px; border: 2px "
        "solid skyblue; float: left; width: 190px; height: 30px; "
        "color: rgb(0, 0, 0); font-family: myahem; font-size: 8px; font-style: "
        "normal; font-variant-ligatures: normal; font-variant-caps: normal; "
        "font-weight: normal; letter-spacing: "
        "normal; line-height: normal; orphans: 2; text-align: start; "
        "text-indent: 0px; text-transform: none; white-space: normal; widows: "
        "2; word-spacing: 0px; -webkit-text-stroke-width: 0px; "
        "text-decoration-style: initial; text-decoration-color: initial;\">Air "
        "conditioner</div><div id=\"div5\" style=\"padding: 10px; margin: "
        "10px; border: 2px solid skyblue; float: left; width: "
        "190px; height: 30px; color: rgb(0, 0, 0); font-family: myahem; "
        "font-size: 8px; font-style: normal; font-variant-ligatures: normal; "
        "font-variant-caps: normal; font-weight: normal; "
        "letter-spacing: normal; line-height: normal; orphans: 2; "
        "text-align: start; text-indent: 0px; text-transform: "
        "none; white-space: normal; widows: 2; word-spacing: 0px; "
        "-webkit-text-stroke-width: 0px; text-decoration-style: initial; "
        "text-decoration-color: initial;\">Price 10,000,000won</div>";
    WebString clipText;
    WebString clipHtml;
    WebRect clipRect;
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("Ahem.ttf"));
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("smartclip.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "smartclip.html");
    webView->resize(WebSize(500, 500));
    webView->updateAllLifecyclePhases();
    WebRect cropRect(300, 125, 152, 50);
    webView->extractSmartClipData(cropRect, clipText, clipHtml, clipRect);
    EXPECT_STREQ(kExpectedClipText, clipText.utf8().c_str());
    EXPECT_STREQ(kExpectedClipHtml, clipHtml.utf8().c_str());
}

TEST_F(WebViewTest, SmartClipDataWithPinchZoom)
{
    static const char kExpectedClipText[] = "\nPrice 10,000,000won";
    static const char kExpectedClipHtml[] =
        "<div id=\"div4\" style=\"padding: 10px; margin: 10px; border: 2px "
        "solid skyblue; float: left; width: 190px; height: 30px; "
        "color: rgb(0, 0, 0); font-family: myahem; font-size: 8px; font-style: "
        "normal; font-variant-ligatures: normal; font-variant-caps: normal; "
        "font-weight: normal; letter-spacing: "
        "normal; line-height: normal; orphans: 2; text-align: start; "
        "text-indent: 0px; text-transform: none; white-space: normal; widows: "
        "2; word-spacing: 0px; -webkit-text-stroke-width: 0px; "
        "text-decoration-style: initial; text-decoration-color: initial;\">Air "
        "conditioner</div><div id=\"div5\" style=\"padding: 10px; margin: "
        "10px; border: 2px solid skyblue; float: left; width: "
        "190px; height: 30px; color: rgb(0, 0, 0); font-family: myahem; "
        "font-size: 8px; font-style: normal; font-variant-ligatures: normal; "
        "font-variant-caps: normal; font-weight: normal; letter-spacing: normal; "
        "line-height: normal; orphans: 2; text-align: start; text-indent: 0px; "
        "text-transform: none; white-space: normal; widows: 2; "
        "word-spacing: 0px; -webkit-text-stroke-width: 0px;"
        " text-decoration-style: initial; text-decoration-color: initial;\">"
        "Price 10,000,000won</div>";
    WebString clipText;
    WebString clipHtml;
    WebRect clipRect;
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("Ahem.ttf"));
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("smartclip.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "smartclip.html");
    webView->resize(WebSize(500, 500));
    webView->updateAllLifecyclePhases();
    webView->setPageScaleFactor(1.5);
    webView->setVisualViewportOffset(WebFloatPoint(167, 100));
    WebRect cropRect(200, 38, 228, 75);
    webView->extractSmartClipData(cropRect, clipText, clipHtml, clipRect);
    EXPECT_STREQ(kExpectedClipText, clipText.utf8().c_str());
    EXPECT_STREQ(kExpectedClipHtml, clipHtml.utf8().c_str());
}

TEST_F(WebViewTest, SmartClipReturnsEmptyStringsWhenUserSelectIsNone)
{
    WebString clipText;
    WebString clipHtml;
    WebRect clipRect;
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("Ahem.ttf"));
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("smartclip_user_select_none.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "smartclip_user_select_none.html");
    webView->resize(WebSize(500, 500));
    webView->updateAllLifecyclePhases();
    WebRect cropRect(0, 0, 100, 100);
    webView->extractSmartClipData(cropRect, clipText, clipHtml, clipRect);
    EXPECT_STREQ("", clipText.utf8().c_str());
    EXPECT_STREQ("", clipHtml.utf8().c_str());
}

TEST_F(WebViewTest, SmartClipDoesNotCrashPositionReversed)
{
    WebString clipText;
    WebString clipHtml;
    WebRect clipRect;
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("Ahem.ttf"));
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("smartclip_reversed_positions.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "smartclip_reversed_positions.html");
    webView->resize(WebSize(500, 500));
    webView->updateAllLifecyclePhases();
    // Left upper corner of the rect will be end position in the DOM hierarchy.
    WebRect cropRect(30, 110, 400, 250);
    // This should not still crash. See crbug.com/589082 for more details.
    webView->extractSmartClipData(cropRect, clipText, clipHtml, clipRect);
}

class CreateChildCounterFrameClient : public FrameTestHelpers::TestWebFrameClient {
public:
    CreateChildCounterFrameClient() : m_count(0) { }
    WebFrame* createChildFrame(WebLocalFrame* parent, WebTreeScopeType, const WebString& name, const WebString& uniqueName, WebSandboxFlags, const WebFrameOwnerProperties&) override;

    int count() const { return m_count; }

private:
    int m_count;
};

WebFrame* CreateChildCounterFrameClient::createChildFrame(WebLocalFrame* parent, WebTreeScopeType scope, const WebString& name, const WebString& uniqueName, WebSandboxFlags sandboxFlags, const WebFrameOwnerProperties& frameOwnerProperties)
{
    ++m_count;
    return TestWebFrameClient::createChildFrame(parent, scope, name, uniqueName, sandboxFlags, frameOwnerProperties);
}

TEST_F(WebViewTest, ChangeDisplayMode)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("display_mode.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "display_mode.html", true);

    std::string content = WebFrameContentDumper::dumpWebViewAsText(webView, 21).utf8();
    EXPECT_EQ("regular-ui", content);

    webView->setDisplayMode(WebDisplayModeMinimalUi);
    content = WebFrameContentDumper::dumpWebViewAsText(webView, 21).utf8();
    EXPECT_EQ("minimal-ui", content);
    m_webViewHelper.reset();
}

TEST_F(WebViewTest, AddFrameInCloseUnload)
{
    CreateChildCounterFrameClient frameClient;
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
    m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload.html", true, &frameClient);
    m_webViewHelper.reset();
    EXPECT_EQ(0, frameClient.count());
}

TEST_F(WebViewTest, AddFrameInCloseURLUnload)
{
    CreateChildCounterFrameClient frameClient;
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
    m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload.html", true, &frameClient);
    m_webViewHelper.webViewImpl()->mainFrame()->dispatchUnloadEvent();
    EXPECT_EQ(0, frameClient.count());
    m_webViewHelper.reset();
}

TEST_F(WebViewTest, AddFrameInNavigateUnload)
{
    CreateChildCounterFrameClient frameClient;
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
    m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload.html", true, &frameClient);
    FrameTestHelpers::loadFrame(m_webViewHelper.webView()->mainFrame(), "about:blank");
    EXPECT_EQ(0, frameClient.count());
    m_webViewHelper.reset();
}

TEST_F(WebViewTest, AddFrameInChildInNavigateUnload)
{
    CreateChildCounterFrameClient frameClient;
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload_wrapper.html"));
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
    m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload_wrapper.html", true, &frameClient);
    FrameTestHelpers::loadFrame(m_webViewHelper.webView()->mainFrame(), "about:blank");
    EXPECT_EQ(1, frameClient.count());
    m_webViewHelper.reset();
}

class TouchEventHandlerWebViewClient : public FrameTestHelpers::TestWebViewClient {
public:
    // WebWidgetClient methods
    void hasTouchEventHandlers(bool state) override
    {
        m_hasTouchEventHandlerCount[state]++;
    }

    // Local methods
    TouchEventHandlerWebViewClient() : m_hasTouchEventHandlerCount()
    {
    }

    int getAndResetHasTouchEventHandlerCallCount(bool state)
    {
        int value = m_hasTouchEventHandlerCount[state];
        m_hasTouchEventHandlerCount[state] = 0;
        return value;
    }

private:
    int m_hasTouchEventHandlerCount[2];
};

// This test verifies that WebWidgetClient::hasTouchEventHandlers is called
// accordingly for various calls to EventHandlerRegistry::did{Add|Remove|
// RemoveAll}EventHandler(..., TouchEvent). Verifying that those calls are made
// correctly is the job of LayoutTests/fast/events/event-handler-count.html.
TEST_F(WebViewTest, HasTouchEventHandlers)
{
    TouchEventHandlerWebViewClient client;
    std::string url = m_baseURL + "has_touch_event_handlers.html";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "has_touch_event_handlers.html");
    WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
    const EventHandlerRegistry::EventHandlerClass touchEvent = EventHandlerRegistry::TouchStartOrMoveEventBlocking;

    // The page is initialized with at least one no-handlers call.
    // In practice we get two such calls because WebViewHelper::initializeAndLoad first
    // initializes and empty frame, and then loads a document into it, so there are two
    // FrameLoader::commitProvisionalLoad calls.
    EXPECT_GE(client.getAndResetHasTouchEventHandlerCallCount(false), 1);
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));

    // Adding the first document handler results in a has-handlers call.
    Document* document = webViewImpl->mainFrameImpl()->frame()->document();
    EventHandlerRegistry* registry = &document->frameHost()->eventHandlerRegistry();
    registry->didAddEventHandler(*document, touchEvent);
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
    EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));

    // Adding another handler has no effect.
    registry->didAddEventHandler(*document, touchEvent);
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));

    // Removing the duplicate handler has no effect.
    registry->didRemoveEventHandler(*document, touchEvent);
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));

    // Removing the final handler results in a no-handlers call.
    registry->didRemoveEventHandler(*document, touchEvent);
    EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));

    // Adding a handler on a div results in a has-handlers call.
    Element* parentDiv = document->getElementById("parentdiv");
    DCHECK(parentDiv);
    registry->didAddEventHandler(*parentDiv, touchEvent);
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
    EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));

    // Adding a duplicate handler on the div, clearing all document handlers
    // (of which there are none) and removing the extra handler on the div
    // all have no effect.
    registry->didAddEventHandler(*parentDiv, touchEvent);
    registry->didRemoveAllEventHandlers(*document);
    registry->didRemoveEventHandler(*parentDiv, touchEvent);
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));

    // Removing the final handler on the div results in a no-handlers call.
    registry->didRemoveEventHandler(*parentDiv, touchEvent);
    EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));

    // Adding two handlers then clearing them in a single call results in a
    // has-handlers then no-handlers call.
    registry->didAddEventHandler(*parentDiv, touchEvent);
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
    EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
    registry->didAddEventHandler(*parentDiv, touchEvent);
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
    registry->didRemoveAllEventHandlers(*parentDiv);
    EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));

    // Adding a handler inside of a child iframe results in a has-handlers call.
    Element* childFrame = document->getElementById("childframe");
    DCHECK(childFrame);
    Document* childDocument = toHTMLIFrameElement(childFrame)->contentDocument();
    Element* childDiv = childDocument->getElementById("childdiv");
    DCHECK(childDiv);
    registry->didAddEventHandler(*childDiv, touchEvent);
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
    EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));

    // Adding and clearing handlers in the parent doc or elsewhere in the child doc
    // has no impact.
    registry->didAddEventHandler(*document, touchEvent);
    registry->didAddEventHandler(*childFrame, touchEvent);
    registry->didAddEventHandler(*childDocument, touchEvent);
    registry->didRemoveAllEventHandlers(*document);
    registry->didRemoveAllEventHandlers(*childFrame);
    registry->didRemoveAllEventHandlers(*childDocument);
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));

    // Removing the final handler inside the child frame results in a no-handlers call.
    registry->didRemoveAllEventHandlers(*childDiv);
    EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));

    // Adding a handler inside the child frame results in a has-handlers call.
    registry->didAddEventHandler(*childDocument, touchEvent);
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
    EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));

    // Adding a handler in the parent document and removing the one in the frame
    // has no effect.
    registry->didAddEventHandler(*childFrame, touchEvent);
    registry->didRemoveEventHandler(*childDocument, touchEvent);
    registry->didRemoveAllEventHandlers(*childDocument);
    registry->didRemoveAllEventHandlers(*document);
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));

    // Now removing the handler in the parent document results in a no-handlers call.
    registry->didRemoveEventHandler(*childFrame, touchEvent);
    EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
    EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));

    // Free the webView before the TouchEventHandlerWebViewClient gets freed.
    m_webViewHelper.reset();
}

// This test checks that deleting nodes which have only non-JS-registered touch
// handlers also removes them from the event handler registry. Note that this
// is different from detaching and re-attaching the same node, which is covered
// by layout tests under fast/events/.
TEST_F(WebViewTest, DeleteElementWithRegisteredHandler)
{
    std::string url = m_baseURL + "simple_div.html";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "simple_div.html");
    WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true);

    Persistent<Document> document = webViewImpl->mainFrameImpl()->frame()->document();
    Element* div = document->getElementById("div");
    EventHandlerRegistry& registry = document->frameHost()->eventHandlerRegistry();

    registry.didAddEventHandler(*div, EventHandlerRegistry::ScrollEvent);
    EXPECT_TRUE(registry.hasEventHandlers(EventHandlerRegistry::ScrollEvent));

    TrackExceptionState exceptionState;
    div->remove(exceptionState);

    // For oilpan we have to force a GC to ensure the event handlers have been removed when
    // checking below. We do a precise GC (collectAllGarbage does not scan the stack)
    // to ensure the div element dies. This is also why the Document is in a Persistent
    // since we want that to stay around.
    ThreadHeap::collectAllGarbage();

    EXPECT_FALSE(registry.hasEventHandlers(EventHandlerRegistry::ScrollEvent));
}

class NonUserInputTextUpdateWebViewClient : public FrameTestHelpers::TestWebViewClient {
public:
    NonUserInputTextUpdateWebViewClient() : m_textIsUpdated(false) { }

    // WebWidgetClient methods
    void didUpdateTextOfFocusedElementByNonUserInput() override
    {
        m_textIsUpdated = true;
    }

    void reset()
    {
        m_textIsUpdated = false;
    }

    bool textIsUpdated() const
    {
        return m_textIsUpdated;
    }

private:
    int m_textIsUpdated;
};

// This test verifies the text input flags are correctly exposed to script.
TEST_F(WebViewTest, TextInputFlags)
{
    NonUserInputTextUpdateWebViewClient client;
    std::string url = m_baseURL + "text_input_flags.html";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "text_input_flags.html");
    WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
    webViewImpl->setInitialFocus(false);

    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewImpl->mainFrame());
    HTMLDocument* document = toHTMLDocument(frame->frame()->document());

    // (A) <input>
    // (A.1) Verifies autocorrect/autocomplete/spellcheck flags are Off and
    // autocapitalize is set to none.
    HTMLInputElement* inputElement = toHTMLInputElement(document->getElementById("input"));
    document->setFocusedElement(inputElement, FocusParams(SelectionBehaviorOnFocus::None, WebFocusTypeNone, nullptr));
    webViewImpl->setFocus(true);
    WebTextInputInfo info1 = webViewImpl->textInputInfo();
    EXPECT_EQ(
        WebTextInputFlagAutocompleteOff | WebTextInputFlagAutocorrectOff | WebTextInputFlagSpellcheckOff | WebTextInputFlagAutocapitalizeNone,
        info1.flags);

    // (A.2) Verifies autocorrect/autocomplete/spellcheck flags are On and
    // autocapitalize is set to sentences.
    inputElement = toHTMLInputElement(document->getElementById("input2"));
    document->setFocusedElement(inputElement, FocusParams(SelectionBehaviorOnFocus::None, WebFocusTypeNone, nullptr));
    webViewImpl->setFocus(true);
    WebTextInputInfo info2 = webViewImpl->textInputInfo();
    EXPECT_EQ(
        WebTextInputFlagAutocompleteOn | WebTextInputFlagAutocorrectOn | WebTextInputFlagSpellcheckOn | WebTextInputFlagAutocapitalizeSentences,
        info2.flags);

    // (B) <textarea> Verifies the default text input flags are
    // WebTextInputFlagAutocapitalizeSentences.
    HTMLTextAreaElement* textAreaElement = toHTMLTextAreaElement(document->getElementById("textarea"));
    document->setFocusedElement(textAreaElement, FocusParams(SelectionBehaviorOnFocus::None, WebFocusTypeNone, nullptr));
    webViewImpl->setFocus(true);
    WebTextInputInfo info3 = webViewImpl->textInputInfo();
    EXPECT_EQ(WebTextInputFlagAutocapitalizeSentences, info3.flags);

    // (C) Verifies the WebTextInputInfo's don't equal.
    EXPECT_FALSE(info1.equals(info2));
    EXPECT_FALSE(info2.equals(info3));

    // Free the webView before freeing the NonUserInputTextUpdateWebViewClient.
    m_webViewHelper.reset();
}

// This test verifies that WebWidgetClient::didUpdateTextOfFocusedElementByNonUserInput is
// called iff value of a focused element is modified via script.
TEST_F(WebViewTest, NonUserInputTextUpdate)
{
    NonUserInputTextUpdateWebViewClient client;
    std::string url = m_baseURL + "non_user_input_text_update.html";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "non_user_input_text_update.html");
    WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
    webViewImpl->setInitialFocus(false);

    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewImpl->mainFrame());
    HTMLDocument* document = toHTMLDocument(frame->frame()->document());

    // (A) <input>
    // (A.1) Focused and value is changed by script.
    client.reset();
    EXPECT_FALSE(client.textIsUpdated());

    HTMLInputElement* inputElement = toHTMLInputElement(document->getElementById("input"));
    document->setFocusedElement(inputElement, FocusParams(SelectionBehaviorOnFocus::None, WebFocusTypeNone, nullptr));
    webViewImpl->setFocus(true);
    EXPECT_EQ(document->focusedElement(), static_cast<Element*>(inputElement));

    // Emulate value change from script.
    inputElement->setValue("testA");
    EXPECT_TRUE(client.textIsUpdated());
    WebTextInputInfo info = webViewImpl->textInputInfo();
    EXPECT_EQ("testA", std::string(info.value.utf8().data()));

    // (A.2) Focused and user input modifies value.
    client.reset();
    EXPECT_FALSE(client.textIsUpdated());

    WebVector<WebCompositionUnderline> emptyUnderlines;
    webViewImpl->setComposition(WebString::fromUTF8("2"), emptyUnderlines, 1, 1);
    webViewImpl->confirmComposition(WebWidget::KeepSelection);
    EXPECT_FALSE(client.textIsUpdated());
    info = webViewImpl->textInputInfo();
    EXPECT_EQ("testA2", std::string(info.value.utf8().data()));

    // (A.3) Unfocused and value is changed by script.
    client.reset();
    EXPECT_FALSE(client.textIsUpdated());
    document->clearFocusedElement();
    webViewImpl->setFocus(false);
    EXPECT_NE(document->focusedElement(), static_cast<Element*>(inputElement));
    inputElement->setValue("testA3");
    EXPECT_FALSE(client.textIsUpdated());

    // (B) <textarea>
    // (B.1) Focused and value is changed by script.
    client.reset();
    EXPECT_FALSE(client.textIsUpdated());
    HTMLTextAreaElement* textAreaElement = toHTMLTextAreaElement(document->getElementById("textarea"));
    document->setFocusedElement(textAreaElement, FocusParams(SelectionBehaviorOnFocus::None, WebFocusTypeNone, nullptr));
    webViewImpl->setFocus(true);
    EXPECT_EQ(document->focusedElement(), static_cast<Element*>(textAreaElement));
    textAreaElement->setValue("testB");
    EXPECT_TRUE(client.textIsUpdated());
    info = webViewImpl->textInputInfo();
    EXPECT_EQ("testB", std::string(info.value.utf8().data()));

    // (B.2) Focused and user input modifies value.
    client.reset();
    EXPECT_FALSE(client.textIsUpdated());
    webViewImpl->setComposition(WebString::fromUTF8("2"), emptyUnderlines, 1, 1);
    webViewImpl->confirmComposition(WebWidget::KeepSelection);
    info = webViewImpl->textInputInfo();
    EXPECT_EQ("testB2", std::string(info.value.utf8().data()));

    // (B.3) Unfocused and value is changed by script.
    client.reset();
    EXPECT_FALSE(client.textIsUpdated());
    document->clearFocusedElement();
    webViewImpl->setFocus(false);
    EXPECT_NE(document->focusedElement(), static_cast<Element*>(textAreaElement));
    inputElement->setValue("testB3");
    EXPECT_FALSE(client.textIsUpdated());

    // Free the webView before freeing the NonUserInputTextUpdateWebViewClient.
    m_webViewHelper.reset();
}

// Check that the WebAutofillClient is correctly notified about first user
// gestures after load, following various input events.
TEST_F(WebViewTest, FirstUserGestureObservedKeyEvent)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("form.html"));
    MockAutofillClient client;
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "form.html", true);
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    frame->setAutofillClient(&client);
    webView->setInitialFocus(false);

    EXPECT_EQ(0, client.getUserGestureNotificationsCount());

    WebKeyboardEvent keyEvent;
    keyEvent.domKey = Platform::current()->domKeyEnumFromString(" ");
    keyEvent.windowsKeyCode = VKEY_SPACE;
    keyEvent.type = WebInputEvent::RawKeyDown;
    keyEvent.setKeyIdentifierFromWindowsKeyCode();
    webView->handleInputEvent(keyEvent);
    keyEvent.type = WebInputEvent::KeyUp;
    webView->handleInputEvent(keyEvent);

    EXPECT_EQ(1, client.getUserGestureNotificationsCount());
    frame->setAutofillClient(0);
}

TEST_F(WebViewTest, FirstUserGestureObservedMouseEvent)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("form.html"));
    MockAutofillClient client;
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "form.html", true);
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    frame->setAutofillClient(&client);
    webView->setInitialFocus(false);

    EXPECT_EQ(0, client.getUserGestureNotificationsCount());

    WebMouseEvent mouseEvent;
    mouseEvent.button = WebMouseEvent::ButtonLeft;
    mouseEvent.x = 1;
    mouseEvent.y = 1;
    mouseEvent.clickCount = 1;
    mouseEvent.type = WebInputEvent::MouseDown;
    webView->handleInputEvent(mouseEvent);
    mouseEvent.type = WebInputEvent::MouseUp;
    webView->handleInputEvent(mouseEvent);

    EXPECT_EQ(1, client.getUserGestureNotificationsCount());
    frame->setAutofillClient(0);
}

TEST_F(WebViewTest, FirstUserGestureObservedGestureTap)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html"));
    MockAutofillClient client;
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "longpress_selection.html", true);
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    frame->setAutofillClient(&client);
    webView->setInitialFocus(false);

    EXPECT_EQ(0, client.getUserGestureNotificationsCount());

    EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, WebString::fromUTF8("target")));

    EXPECT_EQ(1, client.getUserGestureNotificationsCount());
    frame->setAutofillClient(0);
}

TEST_F(WebViewTest, CompositionIsUserGesture)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    MockAutofillClient client;
    frame->setAutofillClient(&client);
    webView->setInitialFocus(false);

    EXPECT_TRUE(webView->setComposition(WebString::fromUTF8(std::string("hello").c_str()), WebVector<WebCompositionUnderline>(), 3, 3));
    EXPECT_EQ(1, client.textChangesFromUserGesture());
    EXPECT_FALSE(UserGestureIndicator::processingUserGesture());
    EXPECT_TRUE(frame->hasMarkedText());

    frame->setAutofillClient(0);
}

TEST_F(WebViewTest, CompareSelectAllToContentAsText)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "longpress_selection.html", true);

    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    frame->executeScript(WebScriptSource(WebString::fromUTF8("document.execCommand('SelectAll', false, null)")));
    std::string actual = frame->selectionAsText().utf8();

    const int kMaxOutputCharacters = 1024;
    std::string expected = WebFrameContentDumper::dumpWebViewAsText(webView, kMaxOutputCharacters).utf8();
    EXPECT_EQ(expected, actual);
}

TEST_F(WebViewTest, AutoResizeSubtreeLayout)
{
    std::string url = m_baseURL + "subtree-layout.html";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "subtree-layout.html");
    WebView* webView = m_webViewHelper.initialize(true);

    webView->enableAutoResizeMode(WebSize(200, 200), WebSize(200, 200));
    loadFrame(webView->mainFrame(), url);

    FrameView* frameView = m_webViewHelper.webViewImpl()->mainFrameImpl()->frameView();

    // Auto-resizing used to DCHECK(needsLayout()) in LayoutBlockFlow::layout. This EXPECT is
    // merely a dummy. The real test is that we don't trigger asserts in debug builds.
    EXPECT_FALSE(frameView->needsLayout());
};

TEST_F(WebViewTest, PreferredSize)
{
    std::string url = m_baseURL + "specify_size.html?100px:100px";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html");
    WebView* webView = m_webViewHelper.initializeAndLoad(url, true);

    WebSize size = webView->contentsPreferredMinimumSize();
    EXPECT_EQ(100, size.width);
    EXPECT_EQ(100, size.height);

    webView->setZoomLevel(WebView::zoomFactorToZoomLevel(2.0));
    size = webView->contentsPreferredMinimumSize();
    EXPECT_EQ(200, size.width);
    EXPECT_EQ(200, size.height);

    // Verify that both width and height are rounded (in this case up)
    webView->setZoomLevel(WebView::zoomFactorToZoomLevel(0.9995));
    size = webView->contentsPreferredMinimumSize();
    EXPECT_EQ(100, size.width);
    EXPECT_EQ(100, size.height);

    // Verify that both width and height are rounded (in this case down)
    webView->setZoomLevel(WebView::zoomFactorToZoomLevel(1.0005));
    size = webView->contentsPreferredMinimumSize();
    EXPECT_EQ(100, size.width);
    EXPECT_EQ(100, size.height);

    url = m_baseURL + "specify_size.html?1.5px:1.5px";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html");
    webView = m_webViewHelper.initializeAndLoad(url, true);

    webView->setZoomLevel(WebView::zoomFactorToZoomLevel(1));
    size = webView->contentsPreferredMinimumSize();
    EXPECT_EQ(2, size.width);
    EXPECT_EQ(2, size.height);
}

TEST_F(WebViewTest, PreferredSizeDirtyLayout)
{
    std::string url = m_baseURL + "specify_size.html?100px:100px";
    URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html");
    WebView* webView = m_webViewHelper.initializeAndLoad(url, true);
    WebElement documentElement = webView->mainFrame()->document().documentElement();

    WebSize size = webView->contentsPreferredMinimumSize();
    EXPECT_EQ(100, size.width);
    EXPECT_EQ(100, size.height);

    documentElement.setAttribute("style", "display: none");

    size = webView->contentsPreferredMinimumSize();
    EXPECT_EQ(0, size.width);
    EXPECT_EQ(0, size.height);
}

class UnhandledTapWebViewClient : public FrameTestHelpers::TestWebViewClient {
public:
    void showUnhandledTapUIIfNeeded(const WebPoint& tappedPosition, const WebNode& tappedNode, bool pageChanged) override
    {
        m_wasCalled = true;
        m_tappedPosition = tappedPosition;
        m_tappedNode = tappedNode;
        m_pageChanged = pageChanged;
    }
    bool getWasCalled() const { return m_wasCalled; }
    int getTappedXPos() const { return m_tappedPosition.x(); }
    int getTappedYPos() const { return m_tappedPosition.y(); }
    bool isTappedNodeNull() const { return m_tappedNode.isNull(); }
    const WebNode& getWebNode() const { return m_tappedNode; }
    bool getPageChanged() const { return m_pageChanged; }
    void reset()
    {
        m_wasCalled = false;
        m_tappedPosition = IntPoint();
        m_tappedNode = WebNode();
        m_pageChanged = false;
    }
private:
    bool m_wasCalled = false;
    IntPoint m_tappedPosition;
    WebNode m_tappedNode;
    bool m_pageChanged = false;
};

TEST_F(WebViewTest, ShowUnhandledTapUIIfNeeded)
{
    std::string testFile = "show_unhandled_tap.html";
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("Ahem.ttf"));
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(testFile));
    UnhandledTapWebViewClient client;
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + testFile, true, 0, &client);
    webView->resize(WebSize(500, 300));
    webView->updateAllLifecyclePhases();
    runPendingTasks();

    // Scroll the bottom into view so we can distinguish window coordinates from document coordinates.
    EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, WebString::fromUTF8("bottom")));
    EXPECT_TRUE(client.getWasCalled());
    EXPECT_EQ(64, client.getTappedXPos());
    EXPECT_EQ(278, client.getTappedYPos());
    EXPECT_FALSE(client.isTappedNodeNull());
    EXPECT_TRUE(client.getWebNode().isTextNode());

    // Test basic tap handling and notification.
    client.reset();
    EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, WebString::fromUTF8("target")));
    EXPECT_TRUE(client.getWasCalled());
    EXPECT_EQ(144, client.getTappedXPos());
    EXPECT_EQ(82, client.getTappedYPos());
    EXPECT_FALSE(client.isTappedNodeNull());
    EXPECT_TRUE(client.getWebNode().isTextNode());
    // Make sure the returned text node has the parent element that was our target.
    EXPECT_EQ(webView->mainFrame()->document().getElementById("target"), client.getWebNode().parentNode());

    // Test correct conversion of coordinates to viewport space under pinch-zoom.
    webView->setPageScaleFactor(2);
    webView->setVisualViewportOffset(WebFloatPoint(50, 20));
    client.reset();
    EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, WebString::fromUTF8("target")));
    EXPECT_TRUE(client.getWasCalled());
    EXPECT_EQ(188, client.getTappedXPos());
    EXPECT_EQ(124, client.getTappedYPos());

    m_webViewHelper.reset(); // Remove dependency on locally scoped client.
}

#define TEST_EACH_MOUSEEVENT(handler, EXPECT) \
frame->executeScript(WebScriptSource("setTest('mousedown-" handler "');")); \
EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, WebString::fromUTF8("target"))); \
EXPECT_##EXPECT(client.getPageChanged()); \
client.reset(); \
frame->executeScript(WebScriptSource("setTest('mouseup-" handler "');")); \
EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, WebString::fromUTF8("target"))); \
EXPECT_##EXPECT(client.getPageChanged()); \
client.reset(); \
frame->executeScript(WebScriptSource("setTest('mousemove-" handler "');")); \
EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, WebString::fromUTF8("target"))); \
EXPECT_##EXPECT(client.getPageChanged()); \
client.reset(); \
frame->executeScript(WebScriptSource("setTest('click-" handler "');")); \
EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, WebString::fromUTF8("target"))); \
EXPECT_##EXPECT(client.getPageChanged());

TEST_F(WebViewTest, ShowUnhandledTapUIIfNeededWithMutateDom)
{
    std::string testFile = "show_unhandled_tap.html";
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("Ahem.ttf"));
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(testFile));
    UnhandledTapWebViewClient client;
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + testFile, true, 0, &client);
    webView->resize(WebSize(500, 300));
    webView->updateAllLifecyclePhases();
    runPendingTasks();
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());

    // Test dom mutation.
    TEST_EACH_MOUSEEVENT("mutateDom", TRUE);

    // Test without any DOM mutation.
    client.reset();
    frame->executeScript(WebScriptSource("setTest('none');"));
    EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, WebString::fromUTF8("target")));
    EXPECT_FALSE(client.getPageChanged());

    m_webViewHelper.reset(); // Remove dependency on locally scoped client.
}

TEST_F(WebViewTest, ShowUnhandledTapUIIfNeededWithMutateStyle)
{
    std::string testFile = "show_unhandled_tap.html";
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("Ahem.ttf"));
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(testFile));
    UnhandledTapWebViewClient client;
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + testFile, true, 0, &client);
    webView->resize(WebSize(500, 300));
    webView->updateAllLifecyclePhases();
    runPendingTasks();
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());

    // Test style mutation.
    TEST_EACH_MOUSEEVENT("mutateStyle", TRUE);

    // Test checkbox:indeterminate style mutation.
    TEST_EACH_MOUSEEVENT("mutateIndeterminate", TRUE);

    // Test click div with :active style but it is not covered for now.
    client.reset();
    EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, WebString::fromUTF8("style_active")));
    EXPECT_FALSE(client.getPageChanged());

    // Test without any style mutation.
    client.reset();
    frame->executeScript(WebScriptSource("setTest('none');"));
    EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, WebString::fromUTF8("target")));
    EXPECT_FALSE(client.getPageChanged());

    m_webViewHelper.reset(); // Remove dependency on locally scoped client.
}

TEST_F(WebViewTest, ShowUnhandledTapUIIfNeededWithPreventDefault)
{
    std::string testFile = "show_unhandled_tap.html";
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("Ahem.ttf"));
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(testFile));
    UnhandledTapWebViewClient client;
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + testFile, true, 0, &client);
    webView->resize(WebSize(500, 300));
    webView->updateAllLifecyclePhases();
    runPendingTasks();
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());

    // Testswallowing.
    TEST_EACH_MOUSEEVENT("preventDefault", FALSE);

    // Test without any preventDefault.
    client.reset();
    frame->executeScript(WebScriptSource("setTest('none');"));
    EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, WebString::fromUTF8("target")));
    EXPECT_TRUE(client.getWasCalled());

    m_webViewHelper.reset(); // Remove dependency on locally scoped client.
}

TEST_F(WebViewTest, StopLoadingIfJavaScriptURLReturnsNoStringResult)
{
    ViewCreatingWebViewClient client;
    FrameTestHelpers::WebViewHelper mainWebView;
    mainWebView.initializeAndLoad("about:blank", true, 0, &client);
    mainWebView.webViewImpl()->page()->settings().setJavaScriptCanOpenWindowsAutomatically(true);

    WebFrame* frame = mainWebView.webView()->mainFrame();
    v8::HandleScope scope(v8::Isolate::GetCurrent());
    v8::Local<v8::Value> v8Value = frame->executeScriptAndReturnValue(WebScriptSource("var win = window.open('javascript:false'); win.document"));
    ASSERT_TRUE(v8Value->IsObject());
    Document* document = V8Document::toImplWithTypeCheck(v8::Isolate::GetCurrent(), v8Value);
    ASSERT_TRUE(document);
    EXPECT_FALSE(document->frame()->isLoading());
}

#if OS(MACOSX)
TEST_F(WebViewTest, WebSubstringUtil)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_editable_populated.html"));
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "content_editable_populated.html");
    webView->settings()->setDefaultFontSize(12);
    webView->resize(WebSize(400, 400));
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    FrameView* frameView = frame->frame()->view();

    WebPoint baselinePoint;
    NSAttributedString* result = WebSubstringUtil::attributedSubstringInRange(frame, 10, 3, &baselinePoint);
    ASSERT_TRUE(!!result);

    WebPoint point(baselinePoint.x, frameView->height() - baselinePoint.y);
    result = WebSubstringUtil::attributedWordAtPoint(webView, point, baselinePoint);
    ASSERT_TRUE(!!result);

    webView->setZoomLevel(3);

    result = WebSubstringUtil::attributedSubstringInRange(frame, 5, 5, &baselinePoint);
    ASSERT_TRUE(!!result);

    point = WebPoint(baselinePoint.x, frameView->height() - baselinePoint.y);
    result = WebSubstringUtil::attributedWordAtPoint(webView, point, baselinePoint);
    ASSERT_TRUE(!!result);
}
#endif

TEST_F(WebViewTest, PasswordFieldEditingIsUserGesture)
{
    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_password.html"));
    MockAutofillClient client;
    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_password.html", true);
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
    frame->setAutofillClient(&client);
    webView->setInitialFocus(false);

    EXPECT_TRUE(webView->confirmComposition(WebString::fromUTF8(std::string("hello").c_str())));
    EXPECT_EQ(1, client.textChangesFromUserGesture());
    EXPECT_FALSE(UserGestureIndicator::processingUserGesture());
    frame->setAutofillClient(0);
}

} // namespace blink
