/*
 * Copyright (C) 2010 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 "config.h"
#include "WebViewHost.h"

#include "LayoutTestController.h"
#include "TestNavigationController.h"
#include "TestShell.h"
#include "TestWebWorker.h"
#include "WebCString.h"
#include "WebConsoleMessage.h"
#include "WebContextMenuData.h"
#include "WebDataSource.h"
#include "WebDeviceOrientationClientMock.h"
#include "WebDragData.h"
#include "WebElement.h"
#include "WebFrame.h"
#include "WebGeolocationClientMock.h"
#include "WebHistoryItem.h"
#include "WebNode.h"
#include "WebRange.h"
#include "WebRect.h"
#include "WebScreenInfo.h"
#include "WebSize.h"
#include "WebSpeechInputControllerMock.h"
#include "WebStorageNamespace.h"
#include "WebTextCheckingCompletion.h"
#include "WebTextCheckingResult.h"
#include "WebURLRequest.h"
#include "WebURLResponse.h"
#include "WebView.h"
#include "WebWindowFeatures.h"
#include "skia/ext/platform_canvas.h"
#include "webkit/support/webkit_support.h"
#include <wtf/Assertions.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/Vector.h>

using namespace WebCore;
using namespace WebKit;
using namespace std;

static const int screenWidth = 1920;
static const int screenHeight = 1080;
static const int screenUnavailableBorder = 8;

// WebNavigationType debugging strings taken from PolicyDelegate.mm.
static const char* linkClickedString = "link clicked";
static const char* formSubmittedString = "form submitted";
static const char* backForwardString = "back/forward";
static const char* reloadString = "reload";
static const char* formResubmittedString = "form resubmitted";
static const char* otherString = "other";
static const char* illegalString = "illegal value";

static int nextPageID = 1;

// Used to write a platform neutral file:/// URL by only taking the filename
// (e.g., converts "file:///tmp/foo.txt" to just "foo.txt").
static string urlSuitableForTestResult(const string& url)
{
    if (url.empty() || string::npos == url.find("file://"))
        return url;

    size_t pos = url.rfind('/');
    if (pos == string::npos) {
#if OS(WINDOWS)
        pos = url.rfind('\\');
        if (pos == string::npos)
            pos = 0;
#else
        pos = 0;
#endif
    }
    string filename = url.substr(pos + 1);
    if (filename.empty())
        return "file:"; // A WebKit test has this in its expected output.
    return filename;
}

// Used to write a platform neutral file:/// URL by taking the
// filename and its directory. (e.g., converts
// "file:///tmp/foo/bar.txt" to just "bar.txt").
static string descriptionSuitableForTestResult(const string& url)
{
    if (url.empty() || string::npos == url.find("file://"))
        return url;

    size_t pos = url.rfind('/');
    if (pos == string::npos || !pos)
        return "ERROR:" + url;
    pos = url.rfind('/', pos - 1);
    if (pos == string::npos)
        return "ERROR:" + url;

    return url.substr(pos + 1);
}

// Adds a file called "DRTFakeFile" to |data_object| (CF_HDROP).  Use to fake
// dragging a file.
static void addDRTFakeFileToDataObject(WebDragData* dragData)
{
    dragData->appendToFilenames(WebString::fromUTF8("DRTFakeFile"));
}

// Get a debugging string from a WebNavigationType.
static const char* webNavigationTypeToString(WebNavigationType type)
{
    switch (type) {
    case WebKit::WebNavigationTypeLinkClicked:
        return linkClickedString;
    case WebKit::WebNavigationTypeFormSubmitted:
        return formSubmittedString;
    case WebKit::WebNavigationTypeBackForward:
        return backForwardString;
    case WebKit::WebNavigationTypeReload:
        return reloadString;
    case WebKit::WebNavigationTypeFormResubmitted:
        return formResubmittedString;
    case WebKit::WebNavigationTypeOther:
        return otherString;
    }
    return illegalString;
}

static string URLDescription(const GURL& url)
{
    if (url.SchemeIs("file"))
        return url.ExtractFileName();
    return url.possibly_invalid_spec();
}

static void printResponseDescription(const WebURLResponse& response)
{
    if (response.isNull()) {
        fputs("(null)", stdout);
        return;
    }
    string url = response.url().spec();
    printf("<NSURLResponse %s, http status code %d>",
           descriptionSuitableForTestResult(url).c_str(),
           response.httpStatusCode());
}

static void printNodeDescription(const WebNode& node, int exception)
{
    if (exception) {
        fputs("ERROR", stdout);
        return;
    }
    if (node.isNull()) {
        fputs("(null)", stdout);
        return;
    }
    fputs(node.nodeName().utf8().data(), stdout);
    const WebNode& parent = node.parentNode();
    if (!parent.isNull()) {
        fputs(" > ", stdout);
        printNodeDescription(parent, 0);
    }
}

static void printRangeDescription(const WebRange& range)
{
    if (range.isNull()) {
        fputs("(null)", stdout);
        return;
    }
    printf("range from %d of ", range.startOffset());
    int exception = 0;
    WebNode startNode = range.startContainer(exception);
    printNodeDescription(startNode, exception);
    printf(" to %d of ", range.endOffset());
    WebNode endNode = range.endContainer(exception);
    printNodeDescription(endNode, exception);
}

static string editingActionDescription(WebEditingAction action)
{
    switch (action) {
    case WebKit::WebEditingActionTyped:
        return "WebViewInsertActionTyped";
    case WebKit::WebEditingActionPasted:
        return "WebViewInsertActionPasted";
    case WebKit::WebEditingActionDropped:
        return "WebViewInsertActionDropped";
    }
    return "(UNKNOWN ACTION)";
}

static string textAffinityDescription(WebTextAffinity affinity)
{
    switch (affinity) {
    case WebKit::WebTextAffinityUpstream:
        return "NSSelectionAffinityUpstream";
    case WebKit::WebTextAffinityDownstream:
        return "NSSelectionAffinityDownstream";
    }
    return "(UNKNOWN AFFINITY)";
}

// WebViewClient -------------------------------------------------------------

WebView* WebViewHost::createView(WebFrame*, const WebURLRequest&, const WebWindowFeatures&, const WebString&)
{
    if (!layoutTestController()->canOpenWindows())
        return 0;
    return m_shell->createNewWindow(WebURL())->webView();
}

WebWidget* WebViewHost::createPopupMenu(WebPopupType)
{
    return 0;
}

WebWidget* WebViewHost::createPopupMenu(const WebPopupMenuInfo&)
{
    return 0;
}

WebStorageNamespace* WebViewHost::createSessionStorageNamespace(unsigned quota)
{
    return WebKit::WebStorageNamespace::createSessionStorageNamespace(quota);
}

void WebViewHost::didAddMessageToConsole(const WebConsoleMessage& message, const WebString& sourceName, unsigned sourceLine)
{
    // This matches win DumpRenderTree's UIDelegate.cpp.
    string newMessage;
    if (!message.text.isEmpty()) {
        newMessage = message.text.utf8();
        size_t fileProtocol = newMessage.find("file://");
        if (fileProtocol != string::npos) {
            newMessage = newMessage.substr(0, fileProtocol)
                + urlSuitableForTestResult(newMessage.substr(fileProtocol));
        }
    }
    printf("CONSOLE MESSAGE: line %d: %s\n", sourceLine, newMessage.data());
}

void WebViewHost::didStartLoading()
{
    m_shell->setIsLoading(true);
}

void WebViewHost::didStopLoading()
{
    m_shell->setIsLoading(false);
}

// The output from these methods in layout test mode should match that
// expected by the layout tests.  See EditingDelegate.m in DumpRenderTree.

bool WebViewHost::shouldBeginEditing(const WebRange& range)
{
    if (layoutTestController()->shouldDumpEditingCallbacks()) {
        fputs("EDITING DELEGATE: shouldBeginEditingInDOMRange:", stdout);
        printRangeDescription(range);
        fputs("\n", stdout);
    }
    return layoutTestController()->acceptsEditing();
}

bool WebViewHost::shouldEndEditing(const WebRange& range)
{
    if (layoutTestController()->shouldDumpEditingCallbacks()) {
        fputs("EDITING DELEGATE: shouldEndEditingInDOMRange:", stdout);
        printRangeDescription(range);
        fputs("\n", stdout);
    }
    return layoutTestController()->acceptsEditing();
}

bool WebViewHost::shouldInsertNode(const WebNode& node, const WebRange& range, WebEditingAction action)
{
    if (layoutTestController()->shouldDumpEditingCallbacks()) {
        fputs("EDITING DELEGATE: shouldInsertNode:", stdout);
        printNodeDescription(node, 0);
        fputs(" replacingDOMRange:", stdout);
        printRangeDescription(range);
        printf(" givenAction:%s\n", editingActionDescription(action).c_str());
    }
    return layoutTestController()->acceptsEditing();
}

bool WebViewHost::shouldInsertText(const WebString& text, const WebRange& range, WebEditingAction action)
{
    if (layoutTestController()->shouldDumpEditingCallbacks()) {
        printf("EDITING DELEGATE: shouldInsertText:%s replacingDOMRange:", text.utf8().data());
        printRangeDescription(range);
        printf(" givenAction:%s\n", editingActionDescription(action).c_str());
    }
    return layoutTestController()->acceptsEditing();
}

bool WebViewHost::shouldChangeSelectedRange(
    const WebRange& fromRange, const WebRange& toRange, WebTextAffinity affinity, bool stillSelecting)
{
    if (layoutTestController()->shouldDumpEditingCallbacks()) {
        fputs("EDITING DELEGATE: shouldChangeSelectedDOMRange:", stdout);
        printRangeDescription(fromRange);
        fputs(" toDOMRange:", stdout);
        printRangeDescription(toRange);
        printf(" affinity:%s stillSelecting:%s\n",
               textAffinityDescription(affinity).c_str(),
               (stillSelecting ? "TRUE" : "FALSE"));
    }
    return layoutTestController()->acceptsEditing();
}

bool WebViewHost::shouldDeleteRange(const WebRange& range)
{
    if (layoutTestController()->shouldDumpEditingCallbacks()) {
        fputs("EDITING DELEGATE: shouldDeleteDOMRange:", stdout);
        printRangeDescription(range);
        fputs("\n", stdout);
    }
    return layoutTestController()->acceptsEditing();
}

bool WebViewHost::shouldApplyStyle(const WebString& style, const WebRange& range)
{
    if (layoutTestController()->shouldDumpEditingCallbacks()) {
        printf("EDITING DELEGATE: shouldApplyStyle:%s toElementsInDOMRange:", style.utf8().data());
        printRangeDescription(range);
        fputs("\n", stdout);
    }
    return layoutTestController()->acceptsEditing();
}

bool WebViewHost::isSmartInsertDeleteEnabled()
{
    return m_smartInsertDeleteEnabled;
}

bool WebViewHost::isSelectTrailingWhitespaceEnabled()
{
    return m_selectTrailingWhitespaceEnabled;
}

void WebViewHost::didBeginEditing()
{
    if (!layoutTestController()->shouldDumpEditingCallbacks())
        return;
    fputs("EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification\n", stdout);
}

void WebViewHost::didChangeSelection(bool isEmptySelection)
{
    if (layoutTestController()->shouldDumpEditingCallbacks())
        fputs("EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification\n", stdout);
    // No need to update clipboard with the selected text in DRT.
}

void WebViewHost::didChangeContents()
{
    if (!layoutTestController()->shouldDumpEditingCallbacks())
        return;
    fputs("EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification\n", stdout);
}

void WebViewHost::didEndEditing()
{
    if (!layoutTestController()->shouldDumpEditingCallbacks())
        return;
    fputs("EDITING DELEGATE: webViewDidEndEditing:WebViewDidEndEditingNotification\n", stdout);
}

bool WebViewHost::handleCurrentKeyboardEvent()
{
    if (m_editCommandName.empty())
        return false;
    WebFrame* frame = webView()->focusedFrame();
    if (!frame)
        return false;

    return frame->executeCommand(WebString::fromUTF8(m_editCommandName), WebString::fromUTF8(m_editCommandValue));
}

void WebViewHost::spellCheck(const WebString& text, int& misspelledOffset, int& misspelledLength, WebVector<WebString>* optionalSuggestions)
{
    // Check the spelling of the given text.
    m_spellcheck.spellCheckWord(text, &misspelledOffset, &misspelledLength);
}

void WebViewHost::requestCheckingOfText(const WebString& text, WebTextCheckingCompletion* completion)
{
    m_lastRequestedTextCheckingCompletion = completion;
    m_lastRequestedTextCheckString = text;
    postDelayedTask(new HostMethodTask(this, &WebViewHost::finishLastTextCheck), 0);
}

void WebViewHost::finishLastTextCheck()
{
    Vector<WebTextCheckingResult> results;
    // FIXME: Do the grammar check.
    int offset = 0;
    String text(m_lastRequestedTextCheckString.data(), m_lastRequestedTextCheckString.length());
    while (text.length()) {
        int misspelledPosition = 0;
        int misspelledLength = 0;
        m_spellcheck.spellCheckWord(WebString(text.characters(), text.length()), &misspelledPosition, &misspelledLength);
        if (!misspelledLength)
            break;
        results.append(WebTextCheckingResult(WebTextCheckingResult::ErrorSpelling, offset + misspelledPosition, misspelledLength));
        text = text.substring(misspelledPosition + misspelledLength);
        offset += misspelledPosition;
    }

    m_lastRequestedTextCheckingCompletion->didFinishCheckingText(results);
    m_lastRequestedTextCheckingCompletion = 0;
}


WebString WebViewHost::autoCorrectWord(const WebString&)
{
    // Returns an empty string as Mac WebKit ('WebKitSupport/WebEditorClient.mm')
    // does. (If this function returns a non-empty string, WebKit replaces the
    // given misspelled string with the result one. This process executes some
    // editor commands and causes layout-test failures.)
    return WebString();
}

void WebViewHost::runModalAlertDialog(WebFrame*, const WebString& message)
{
    printf("ALERT: %s\n", message.utf8().data());
}

bool WebViewHost::runModalConfirmDialog(WebFrame*, const WebString& message)
{
    printf("CONFIRM: %s\n", message.utf8().data());
    return true;
}

bool WebViewHost::runModalPromptDialog(WebFrame* frame, const WebString& message,
                                       const WebString& defaultValue, WebString*)
{
    printf("PROMPT: %s, default text: %s\n", message.utf8().data(), defaultValue.utf8().data());
    return true;
}

bool WebViewHost::runModalBeforeUnloadDialog(WebFrame*, const WebString&)
{
    return true; // Allow window closure.
}

void WebViewHost::showContextMenu(WebFrame*, const WebContextMenuData& contextMenuData)
{
    m_lastContextMenuData = adoptPtr(new WebContextMenuData(contextMenuData));
}

void WebViewHost::clearContextMenuData()
{
    m_lastContextMenuData.clear();
}

WebContextMenuData* WebViewHost::lastContextMenuData() const
{
    return m_lastContextMenuData.get();
}

void WebViewHost::setStatusText(const WebString& text)
{
    if (!layoutTestController()->shouldDumpStatusCallbacks())
        return;
    // When running tests, write to stdout.
    printf("UI DELEGATE STATUS CALLBACK: setStatusText:%s\n", text.utf8().data());
}

void WebViewHost::startDragging(const WebDragData& data, WebDragOperationsMask mask, const WebImage&, const WebPoint&)
{
    WebDragData mutableDragData = data;
    if (layoutTestController()->shouldAddFileToPasteboard()) {
        // Add a file called DRTFakeFile to the drag&drop clipboard.
        addDRTFakeFileToDataObject(&mutableDragData);
    }

    // When running a test, we need to fake a drag drop operation otherwise
    // Windows waits for real mouse events to know when the drag is over.
    m_shell->eventSender()->doDragDrop(mutableDragData, mask);
}

void WebViewHost::navigateBackForwardSoon(int offset)
{
    navigationController()->goToOffset(offset);
}

int WebViewHost::historyBackListCount()
{
    return navigationController()->lastCommittedEntryIndex();
}

int WebViewHost::historyForwardListCount()
{
    int currentIndex =navigationController()->lastCommittedEntryIndex();
    return navigationController()->entryCount() - currentIndex - 1;
}

void WebViewHost::postAccessibilityNotification(const WebAccessibilityObject& obj, WebAccessibilityNotification notification)
{
    if (notification == WebAccessibilityNotificationFocusedUIElementChanged)
        m_shell->accessibilityController()->setFocusedElement(obj);

    if (m_shell->accessibilityController()->shouldDumpAccessibilityNotifications()) {
        printf("AccessibilityNotification - ");

        switch (notification) {
        case WebAccessibilityNotificationActiveDescendantChanged:
            printf("ActiveDescendantChanged");
            break;
        case WebAccessibilityNotificationCheckedStateChanged:
            printf("CheckedStateChanged");
            break;
        case WebAccessibilityNotificationChildrenChanged:
            printf("ChildrenChanged");
            break;
        case WebAccessibilityNotificationFocusedUIElementChanged:
            printf("FocusedUIElementChanged");
            break;
        case WebAccessibilityNotificationLayoutComplete:
            printf("LayoutComplete");
            break;
        case WebAccessibilityNotificationLoadComplete:
            printf("LoadComplete");
            break;
        case WebAccessibilityNotificationSelectedChildrenChanged:
            printf("SelectedChildrenChanged");
            break;
        case WebAccessibilityNotificationSelectedTextChanged:
            printf("SelectedTextChanged");
            break;
        case WebAccessibilityNotificationValueChanged:
            printf("ValueChanged");
            break;
        case WebAccessibilityNotificationScrolledToAnchor:
            printf("ScrolledToAnchor");
            break;
        case WebAccessibilityNotificationLiveRegionChanged:
            printf("LiveRegionChanged");
            break;
        case WebAccessibilityNotificationMenuListValueChanged:
            printf("MenuListValueChanged");
            break;
        case WebAccessibilityNotificationRowCountChanged:
            printf("RowCountChanged");
            break;
        case WebAccessibilityNotificationRowCollapsed:
            printf("RowCollapsed");
            break;
        case WebAccessibilityNotificationRowExpanded:
            printf("RowExpanded");
            break;
        default:
            break;
        }

        WebKit::WebNode node = obj.node();
        if (!node.isNull() && node.isElementNode()) {
            WebKit::WebElement element = node.to<WebKit::WebElement>();
            if (element.hasAttribute("id"))
                printf(" - id:%s", element.getAttribute("id").utf8().data());
        }

        printf("\n");
    }
}

WebNotificationPresenter* WebViewHost::notificationPresenter()
{
    return m_shell->notificationPresenter();
}

WebKit::WebGeolocationClient* WebViewHost::geolocationClient()
{
    return geolocationClientMock();
}

WebKit::WebGeolocationClientMock* WebViewHost::geolocationClientMock()
{
    if (!m_geolocationClientMock)
        m_geolocationClientMock.set(WebGeolocationClientMock::create());
    return m_geolocationClientMock.get();
}

WebSpeechInputController* WebViewHost::speechInputController(WebKit::WebSpeechInputListener* listener)
{
    if (!m_speechInputControllerMock)
        m_speechInputControllerMock.set(WebSpeechInputControllerMock::create(listener));
    return m_speechInputControllerMock.get();
}

WebDeviceOrientationClientMock* WebViewHost::deviceOrientationClientMock()
{
    if (!m_deviceOrientationClientMock.get())
        m_deviceOrientationClientMock.set(WebDeviceOrientationClientMock::create());
    return m_deviceOrientationClientMock.get();
}

MockSpellCheck* WebViewHost::mockSpellCheck()
{
    return &m_spellcheck;
}

WebDeviceOrientationClient* WebViewHost::deviceOrientationClient()
{
    return deviceOrientationClientMock();
}

// WebWidgetClient -----------------------------------------------------------

void WebViewHost::didInvalidateRect(const WebRect& rect)
{
    updatePaintRect(rect);
}

void WebViewHost::didScrollRect(int, int, const WebRect& clipRect)
{
    // This is used for optimizing painting when the renderer is scrolled. We're
    // currently not doing any optimizations so just invalidate the region.
    didInvalidateRect(clipRect);
}

void WebViewHost::scheduleComposite()
{
    WebSize widgetSize = webWidget()->size();
    WebRect clientRect(0, 0, widgetSize.width, widgetSize.height);
    didInvalidateRect(clientRect);
}

#if ENABLE(REQUEST_ANIMATION_FRAME)
void WebViewHost::scheduleAnimation()
{
    postDelayedTask(new HostMethodTask(this, &WebViewHost::scheduleComposite), 0);
}
#endif

void WebViewHost::didFocus()
{
    m_shell->setFocus(webWidget(), true);
}

void WebViewHost::didBlur()
{
    m_shell->setFocus(webWidget(), false);
}

WebScreenInfo WebViewHost::screenInfo()
{
    // We don't need to set actual values.
    WebScreenInfo info;
    info.depth = 24;
    info.depthPerComponent = 8;
    info.isMonochrome = false;
    info.rect = WebRect(0, 0, screenWidth, screenHeight);
    // Use values different from info.rect for testing.
    info.availableRect = WebRect(screenUnavailableBorder, screenUnavailableBorder,
                                 screenWidth - screenUnavailableBorder * 2,
                                 screenHeight - screenUnavailableBorder * 2);
    return info;
}

void WebViewHost::show(WebNavigationPolicy)
{
    m_hasWindow = true;
    WebSize size = webWidget()->size();
    updatePaintRect(WebRect(0, 0, size.width, size.height));
}



void WebViewHost::closeWidget()
{
    m_hasWindow = false;
    m_shell->closeWindow(this);
    // No more code here, we should be deleted at this point.
}

void WebViewHost::closeWidgetSoon()
{
    postDelayedTask(new HostMethodTask(this, &WebViewHost::closeWidget), 0);
}

void WebViewHost::didChangeCursor(const WebCursorInfo& cursorInfo)
{
    if (!hasWindow())
        return;
    m_currentCursor = cursorInfo;
}

WebRect WebViewHost::windowRect()
{
    return m_windowRect;
}

void WebViewHost::setWindowRect(const WebRect& rect)
{
    m_windowRect = rect;
    const int border2 = TestShell::virtualWindowBorder * 2;
    if (m_windowRect.width <= border2)
        m_windowRect.width = 1 + border2;
    if (m_windowRect.height <= border2)
        m_windowRect.height = 1 + border2;
    int width = m_windowRect.width - border2;
    int height = m_windowRect.height - border2;
    discardBackingStore();
    webWidget()->resize(WebSize(width, height));
    updatePaintRect(WebRect(0, 0, width, height));
}

WebRect WebViewHost::rootWindowRect()
{
    return windowRect();
}

WebRect WebViewHost::windowResizerRect()
{
    // Not necessary.
    return WebRect();
}

void WebViewHost::runModal()
{
    bool oldState = webkit_support::MessageLoopNestableTasksAllowed();
    webkit_support::MessageLoopSetNestableTasksAllowed(true);
    m_inModalLoop = true;
    webkit_support::RunMessageLoop();
    webkit_support::MessageLoopSetNestableTasksAllowed(oldState);
}

// WebFrameClient ------------------------------------------------------------

WebPlugin* WebViewHost::createPlugin(WebFrame* frame, const WebPluginParams& params)
{
    return webkit_support::CreateWebPlugin(frame, params);
}

WebWorker* WebViewHost::createWorker(WebFrame*, WebWorkerClient*)
{
    return new TestWebWorker();
}

WebMediaPlayer* WebViewHost::createMediaPlayer(WebFrame* frame, WebMediaPlayerClient* client)
{
    return webkit_support::CreateMediaPlayer(frame, client);
}

WebApplicationCacheHost* WebViewHost::createApplicationCacheHost(WebFrame* frame, WebApplicationCacheHostClient* client)
{
    return webkit_support::CreateApplicationCacheHost(frame, client);
}

bool WebViewHost::allowPlugins(WebFrame* frame, bool enabledPerSettings)
{
    return enabledPerSettings;
}

bool WebViewHost::allowImages(WebFrame* frame, bool enabledPerSettings)
{
    return enabledPerSettings;
}

void WebViewHost::loadURLExternally(WebFrame*, const WebURLRequest& request, WebNavigationPolicy policy)
{
    ASSERT(policy !=  WebKit::WebNavigationPolicyCurrentTab);
    WebViewHost* another = m_shell->createNewWindow(request.url());
    if (another)
        another->show(policy);
}

WebNavigationPolicy WebViewHost::decidePolicyForNavigation(
    WebFrame*, const WebURLRequest& request,
    WebNavigationType type, const WebNode& originatingNode,
    WebNavigationPolicy defaultPolicy, bool isRedirect)
{
    WebNavigationPolicy result;
    if (!m_policyDelegateEnabled)
        return defaultPolicy;

    printf("Policy delegate: attempt to load %s with navigation type '%s'",
           URLDescription(request.url()).c_str(), webNavigationTypeToString(type));
    if (!originatingNode.isNull()) {
        fputs(" originating from ", stdout);
        printNodeDescription(originatingNode, 0);
    }
    fputs("\n", stdout);
    if (m_policyDelegateIsPermissive)
        result = WebKit::WebNavigationPolicyCurrentTab;
    else
        result = WebKit::WebNavigationPolicyIgnore;

    if (m_policyDelegateShouldNotifyDone)
        layoutTestController()->policyDelegateDone();
    return result;
}

bool WebViewHost::canHandleRequest(WebFrame*, const WebURLRequest& request)
{
    GURL url = request.url();
    // Just reject the scheme used in
    // LayoutTests/http/tests/misc/redirect-to-external-url.html
    return !url.SchemeIs("spaceballs");
}

WebURLError WebViewHost::cannotHandleRequestError(WebFrame*, const WebURLRequest& request)
{
    WebURLError error;
    // A WebKit layout test expects the following values.
    // unableToImplementPolicyWithError() below prints them.
    error.domain = WebString::fromUTF8("WebKitErrorDomain");
    error.reason = 101;
    error.unreachableURL = request.url();
    return error;
}

WebURLError WebViewHost::cancelledError(WebFrame*, const WebURLRequest& request)
{
    return webkit_support::CreateCancelledError(request);
}

void WebViewHost::unableToImplementPolicyWithError(WebFrame* frame, const WebURLError& error)
{
    printf("Policy delegate: unable to implement policy with error domain '%s', "
           "error code %d, in frame '%s'\n",
           error.domain.utf8().data(), error.reason, frame->name().utf8().data());
}

void WebViewHost::willPerformClientRedirect(WebFrame* frame, const WebURL& from, const WebURL& to,
                                            double interval, double fire_time)
{
    if (!m_shell->shouldDumpFrameLoadCallbacks())
        return;
    printFrameDescription(frame);
    printf(" - willPerformClientRedirectToURL: %s \n", to.spec().data());
}

void WebViewHost::didCancelClientRedirect(WebFrame* frame)
{
    if (!m_shell->shouldDumpFrameLoadCallbacks())
        return;
    printFrameDescription(frame);
    fputs(" - didCancelClientRedirectForFrame\n", stdout);
}

void WebViewHost::didCreateDataSource(WebFrame*, WebDataSource* ds)
{
    ds->setExtraData(m_pendingExtraData.leakPtr());
    if (!layoutTestController()->deferMainResourceDataLoad())
        ds->setDeferMainResourceDataLoad(false);
}

void WebViewHost::didStartProvisionalLoad(WebFrame* frame)
{
    if (m_shell->shouldDumpUserGestureInFrameLoadCallbacks())
        printFrameUserGestureStatus(frame, " - in didStartProvisionalLoadForFrame\n");
    if (m_shell->shouldDumpFrameLoadCallbacks()) {
        printFrameDescription(frame);
        fputs(" - didStartProvisionalLoadForFrame\n", stdout);
    }

    if (!m_topLoadingFrame)
        m_topLoadingFrame = frame;

    if (layoutTestController()->stopProvisionalFrameLoads()) {
        printFrameDescription(frame);
        fputs(" - stopping load in didStartProvisionalLoadForFrame callback\n", stdout);
        frame->stopLoading();
    }
    updateAddressBar(frame->view());
}

void WebViewHost::didReceiveServerRedirectForProvisionalLoad(WebFrame* frame)
{
    if (m_shell->shouldDumpFrameLoadCallbacks()) {
        printFrameDescription(frame);
        fputs(" - didReceiveServerRedirectForProvisionalLoadForFrame\n", stdout);
    }
    updateAddressBar(frame->view());
}

void WebViewHost::didFailProvisionalLoad(WebFrame* frame, const WebURLError& error)
{
    if (m_shell->shouldDumpFrameLoadCallbacks()) {
        printFrameDescription(frame);
        fputs(" - didFailProvisionalLoadWithError\n", stdout);
    }

    locationChangeDone(frame);

    // Don't display an error page if we're running layout tests, because
    // DumpRenderTree doesn't.
}

void WebViewHost::didCommitProvisionalLoad(WebFrame* frame, bool isNewNavigation)
{
    if (m_shell->shouldDumpFrameLoadCallbacks()) {
        printFrameDescription(frame);
        fputs(" - didCommitLoadForFrame\n", stdout);
    }
    updateForCommittedLoad(frame, isNewNavigation);
}

void WebViewHost::didClearWindowObject(WebFrame* frame)
{
    m_shell->bindJSObjectsToWindow(frame);
}

void WebViewHost::didReceiveTitle(WebFrame* frame, const WebString& title, WebTextDirection direction)
{
    WebCString title8 = title.utf8();

    if (m_shell->shouldDumpFrameLoadCallbacks()) {
        printFrameDescription(frame);
        printf(" - didReceiveTitle: %s\n", title8.data());
    }

    if (layoutTestController()->shouldDumpTitleChanges())
        printf("TITLE CHANGED: %s\n", title8.data());

    setPageTitle(title);
    layoutTestController()->setTitleTextDirection(direction);
}

void WebViewHost::didFinishDocumentLoad(WebFrame* frame)
{
    if (m_shell->shouldDumpFrameLoadCallbacks()) {
        printFrameDescription(frame);
        fputs(" - didFinishDocumentLoadForFrame\n", stdout);
    } else {
        unsigned pendingUnloadEvents = frame->unloadListenerCount();
        if (pendingUnloadEvents) {
            printFrameDescription(frame);
            printf(" - has %u onunload handler(s)\n", pendingUnloadEvents);
        }
    }
}

void WebViewHost::didHandleOnloadEvents(WebFrame* frame)
{
    if (m_shell->shouldDumpFrameLoadCallbacks()) {
        printFrameDescription(frame);
        fputs(" - didHandleOnloadEventsForFrame\n", stdout);
    }
}

void WebViewHost::didFailLoad(WebFrame* frame, const WebURLError& error)
{
    if (m_shell->shouldDumpFrameLoadCallbacks()) {
        printFrameDescription(frame);
        fputs(" - didFailLoadWithError\n", stdout);
    }
    locationChangeDone(frame);
}

void WebViewHost::didFinishLoad(WebFrame* frame)
{
    if (m_shell->shouldDumpFrameLoadCallbacks()) {
        printFrameDescription(frame);
        fputs(" - didFinishLoadForFrame\n", stdout);
    }
    updateAddressBar(frame->view());
    locationChangeDone(frame);
}

void WebViewHost::didNavigateWithinPage(WebFrame* frame, bool isNewNavigation)
{
    frame->dataSource()->setExtraData(m_pendingExtraData.leakPtr());

    updateForCommittedLoad(frame, isNewNavigation);
}

void WebViewHost::didChangeLocationWithinPage(WebFrame* frame)
{
    if (m_shell->shouldDumpFrameLoadCallbacks()) {
        printFrameDescription(frame);
        fputs(" - didChangeLocationWithinPageForFrame\n", stdout);
    }
}

void WebViewHost::assignIdentifierToRequest(WebFrame*, unsigned identifier, const WebURLRequest& request)
{
     if (!m_shell->shouldDumpResourceLoadCallbacks())
        return;
    ASSERT(!m_resourceIdentifierMap.contains(identifier));
    m_resourceIdentifierMap.set(identifier, descriptionSuitableForTestResult(request.url().spec()));
}

void WebViewHost::removeIdentifierForRequest(unsigned identifier)
{
    m_resourceIdentifierMap.remove(identifier);
}

void WebViewHost::willSendRequest(WebFrame*, unsigned identifier, WebURLRequest& request, const WebURLResponse& redirectResponse)
{
    // Need to use GURL for host() and SchemeIs()
    GURL url = request.url();
    string requestURL = url.possibly_invalid_spec();

    if (layoutTestController()->shouldDumpResourceLoadCallbacks()) {
        GURL mainDocumentURL = request.firstPartyForCookies();
        printResourceDescription(identifier);
        printf(" - willSendRequest <NSURLRequest URL %s, main document URL %s,"
               " http method %s> redirectResponse ",
               descriptionSuitableForTestResult(requestURL).c_str(),
               URLDescription(mainDocumentURL).c_str(),
               request.httpMethod().utf8().data());
        printResponseDescription(redirectResponse);
        fputs("\n", stdout);
    }

    if (!redirectResponse.isNull() && m_blocksRedirects) {
        fputs("Returning null for this redirect\n", stdout);
        // To block the request, we set its URL to an empty one.
        request.setURL(WebURL());
        return;
    }

    if (m_requestReturnNull) {
        // To block the request, we set its URL to an empty one.
        request.setURL(WebURL());
        return;
    }

    string host = url.host();
    // 255.255.255.255 is used in some tests that expect to get back an error.
    if (!host.empty() && (url.SchemeIs("http") || url.SchemeIs("https"))
        && host != "127.0.0.1"
        && host != "255.255.255.255"
        && host != "localhost"
        && !m_shell->allowExternalPages()) {
        printf("Blocked access to external URL %s\n", requestURL.c_str());

        // To block the request, we set its URL to an empty one.
        request.setURL(WebURL());
        return;
    }

    HashSet<String>::const_iterator end = m_clearHeaders.end();
    for (HashSet<String>::const_iterator header = m_clearHeaders.begin(); header != end; ++header)
        request.clearHTTPHeaderField(WebString(header->characters(), header->length()));

    // Set the new substituted URL.
    request.setURL(webkit_support::RewriteLayoutTestsURL(request.url().spec()));
}

void WebViewHost::didReceiveResponse(WebFrame*, unsigned identifier, const WebURLResponse& response)
{
    if (m_shell->shouldDumpResourceLoadCallbacks()) {
        printResourceDescription(identifier);
        fputs(" - didReceiveResponse ", stdout);
        printResponseDescription(response);
        fputs("\n", stdout);
    }
    if (m_shell->shouldDumpResourceResponseMIMETypes()) {
        GURL url = response.url();
        WebString mimeType = response.mimeType();
        printf("%s has MIME type %s\n",
            url.ExtractFileName().c_str(),
            // Simulate NSURLResponse's mapping of empty/unknown MIME types to application/octet-stream
            mimeType.isEmpty() ? "application/octet-stream" : mimeType.utf8().data());
    }
}

void WebViewHost::didFinishResourceLoad(WebFrame*, unsigned identifier)
{
    if (m_shell->shouldDumpResourceLoadCallbacks()) {
        printResourceDescription(identifier);
        fputs(" - didFinishLoading\n", stdout);
    }
    removeIdentifierForRequest(identifier);
}

void WebViewHost::didFailResourceLoad(WebFrame*, unsigned identifier, const WebURLError& error)
{
    if (m_shell->shouldDumpResourceLoadCallbacks()) {
        printResourceDescription(identifier);
        fputs(" - didFailLoadingWithError: ", stdout);
        fputs(webkit_support::MakeURLErrorDescription(error).c_str(), stdout);
        fputs("\n", stdout);
    }
    removeIdentifierForRequest(identifier);
}

void WebViewHost::didDisplayInsecureContent(WebFrame*)
{
    if (m_shell->shouldDumpFrameLoadCallbacks())
        fputs("didDisplayInsecureContent\n", stdout);
}

void WebViewHost::didRunInsecureContent(WebFrame*, const WebSecurityOrigin& origin, const WebURL& insecureURL)
{
    if (m_shell->shouldDumpFrameLoadCallbacks())
        fputs("didRunInsecureContent\n", stdout);
}

bool WebViewHost::allowScript(WebFrame*, bool enabledPerSettings)
{
    return enabledPerSettings;
}

void WebViewHost::openFileSystem(WebFrame* frame, WebFileSystem::Type type, long long size, bool create, WebFileSystemCallbacks* callbacks)
{
    webkit_support::OpenFileSystem(frame, type, size, create, callbacks);
}

// Public functions -----------------------------------------------------------

WebViewHost::WebViewHost(TestShell* shell)
    : m_shell(shell)
    , m_webWidget(0)
    , m_lastRequestedTextCheckingCompletion(0)
{
    reset();
}

WebViewHost::~WebViewHost()
{
    // DevTools frontend page is supposed to be navigated only once and
    // loading another URL in that Page is an error.
    if (m_shell->devToolsWebView() != this) {
        // Navigate to an empty page to fire all the destruction logic for the
        // current page.
        loadURLForFrame(GURL("about:blank"), WebString());
    }

    webWidget()->close();

    if (m_inModalLoop)
        webkit_support::QuitMessageLoop();
}

void WebViewHost::setWebWidget(WebKit::WebWidget* widget)
{
    m_webWidget = widget;
    webView()->setSpellCheckClient(this);
}

WebView* WebViewHost::webView() const
{
    ASSERT(m_webWidget);
    // DRT does not support popup widgets. So m_webWidget is always a WebView.
    return static_cast<WebView*>(m_webWidget);
}

WebWidget* WebViewHost::webWidget() const
{
    ASSERT(m_webWidget);
    return m_webWidget;
}

void WebViewHost::reset()
{
    m_policyDelegateEnabled = false;
    m_policyDelegateIsPermissive = false;
    m_policyDelegateShouldNotifyDone = false;
    m_topLoadingFrame = 0;
    m_pageId = -1;
    m_lastPageIdUpdated = -1;
    m_hasWindow = false;
    m_inModalLoop = false;
    m_smartInsertDeleteEnabled = true;
#if OS(WINDOWS)
    m_selectTrailingWhitespaceEnabled = true;
#else
    m_selectTrailingWhitespaceEnabled = false;
#endif
    m_blocksRedirects = false;
    m_requestReturnNull = false;
    m_isPainting = false;
    m_canvas.clear();

    m_navigationController.set(new TestNavigationController(this));

    m_pendingExtraData.clear();
    m_resourceIdentifierMap.clear();
    m_clearHeaders.clear();
    m_editCommandName.clear();
    m_editCommandValue.clear();

    if (m_geolocationClientMock.get())
        m_geolocationClientMock->resetMock();

    if (m_speechInputControllerMock.get())
        m_speechInputControllerMock->clearResults();

    m_currentCursor = WebCursorInfo();
    m_windowRect = WebRect();
    m_paintRect = WebRect();

    if (m_webWidget) {
        webView()->mainFrame()->setName(WebString());
        webView()->settings()->setMinimumTimerInterval(webkit_support::GetForegroundTabTimerInterval());
    }
}

void WebViewHost::setSelectTrailingWhitespaceEnabled(bool enabled)
{
    m_selectTrailingWhitespaceEnabled = enabled;
    // In upstream WebKit, smart insert/delete is mutually exclusive with select
    // trailing whitespace, however, we allow both because Chromium on Windows
    // allows both.
}

void WebViewHost::setSmartInsertDeleteEnabled(bool enabled)
{
    m_smartInsertDeleteEnabled = enabled;
    // In upstream WebKit, smart insert/delete is mutually exclusive with select
    // trailing whitespace, however, we allow both because Chromium on Windows
    // allows both.
}

void WebViewHost::setCustomPolicyDelegate(bool isCustom, bool isPermissive)
{
    m_policyDelegateEnabled = isCustom;
    m_policyDelegateIsPermissive = isPermissive;
}

void WebViewHost::waitForPolicyDelegate()
{
    m_policyDelegateEnabled = true;
    m_policyDelegateShouldNotifyDone = true;
}

void WebViewHost::setEditCommand(const string& name, const string& value)
{
    m_editCommandName = name;
    m_editCommandValue = value;
}

void WebViewHost::clearEditCommand()
{
    m_editCommandName.clear();
    m_editCommandValue.clear();
}

void WebViewHost::loadURLForFrame(const WebURL& url, const WebString& frameName)
{
    if (!url.isValid())
        return;
    TestShell::resizeWindowForTest(this, url);
    navigationController()->loadEntry(TestNavigationEntry::create(-1, url, WebString(), frameName).get());
}

bool WebViewHost::navigate(const TestNavigationEntry& entry, bool reload)
{
    // Get the right target frame for the entry.
    WebFrame* frame = webView()->mainFrame();
    if (!entry.targetFrame().isEmpty())
        frame = webView()->findFrameByName(entry.targetFrame());

    // TODO(mpcomplete): should we clear the target frame, or should
    // back/forward navigations maintain the target frame?

    // A navigation resulting from loading a javascript URL should not be
    // treated as a browser initiated event.  Instead, we want it to look as if
    // the page initiated any load resulting from JS execution.
    if (!GURL(entry.URL()).SchemeIs("javascript"))
        setPendingExtraData(new TestShellExtraData(entry.pageID()));

    // If we are reloading, then WebKit will use the state of the current page.
    // Otherwise, we give it the state to navigate to.
    if (reload) {
        frame->reload(false);
    } else if (!entry.contentState().isNull()) {
        ASSERT(entry.pageID() != -1);
        frame->loadHistoryItem(entry.contentState());
    } else {
        ASSERT(entry.pageID() == -1);
        frame->loadRequest(WebURLRequest(entry.URL()));
    }

    // In case LoadRequest failed before DidCreateDataSource was called.
    setPendingExtraData(0);

    // Restore focus to the main frame prior to loading new request.
    // This makes sure that we don't have a focused iframe. Otherwise, that
    // iframe would keep focus when the SetFocus called immediately after
    // LoadRequest, thus making some tests fail (see http://b/issue?id=845337
    // for more details).
    webView()->setFocusedFrame(frame);
    m_shell->setFocus(webView(), true);

    return true;
}

// Private functions ----------------------------------------------------------

LayoutTestController* WebViewHost::layoutTestController() const
{
    return m_shell->layoutTestController();
}

void WebViewHost::updateAddressBar(WebView* webView)
{
    WebFrame* mainFrame = webView->mainFrame();
    WebDataSource* dataSource = mainFrame->dataSource();
    if (!dataSource)
        dataSource = mainFrame->provisionalDataSource();
    if (!dataSource)
        return;

    setAddressBarURL(dataSource->request().url());
}

void WebViewHost::locationChangeDone(WebFrame* frame)
{
    if (frame != m_topLoadingFrame)
        return;
    m_topLoadingFrame = 0;
    layoutTestController()->locationChangeDone();
}

void WebViewHost::updateForCommittedLoad(WebFrame* frame, bool isNewNavigation)
{
    // Code duplicated from RenderView::DidCommitLoadForFrame.
    TestShellExtraData* extraData = static_cast<TestShellExtraData*>(frame->dataSource()->extraData());

    if (isNewNavigation) {
        // New navigation.
        updateSessionHistory(frame);
        m_pageId = nextPageID++;
    } else if (extraData && extraData->pendingPageID != -1 && !extraData->requestCommitted) {
        // This is a successful session history navigation!
        updateSessionHistory(frame);
        m_pageId = extraData->pendingPageID;
    }

    // Don't update session history multiple times.
    if (extraData)
        extraData->requestCommitted = true;

    updateURL(frame);
}

void WebViewHost::updateURL(WebFrame* frame)
{
    WebDataSource* ds = frame->dataSource();
    ASSERT(ds);
    const WebURLRequest& request = ds->request();
    RefPtr<TestNavigationEntry> entry(TestNavigationEntry::create());

    // The referrer will be empty on https->http transitions. It
    // would be nice if we could get the real referrer from somewhere.
    entry->setPageID(m_pageId);
    if (ds->hasUnreachableURL())
        entry->setURL(ds->unreachableURL());
    else
        entry->setURL(request.url());

    const WebHistoryItem& historyItem = frame->currentHistoryItem();
    if (!historyItem.isNull())
        entry->setContentState(historyItem);

    navigationController()->didNavigateToEntry(entry.get());
    updateAddressBar(frame->view());
    m_lastPageIdUpdated = max(m_lastPageIdUpdated, m_pageId);
}

void WebViewHost::updateSessionHistory(WebFrame* frame)
{
    // If we have a valid page ID at this point, then it corresponds to the page
    // we are navigating away from.  Otherwise, this is the first navigation, so
    // there is no past session history to record.
    if (m_pageId == -1)
        return;

    TestNavigationEntry* entry = navigationController()->entryWithPageID(m_pageId);
    if (!entry)
        return;

    const WebHistoryItem& historyItem = webView()->mainFrame()->previousHistoryItem();
    if (historyItem.isNull())
        return;

    entry->setContentState(historyItem);
}

void WebViewHost::printFrameDescription(WebFrame* webframe)
{
    string name8 = webframe->name().utf8();
    if (webframe == webView()->mainFrame()) {
        if (!name8.length()) {
            fputs("main frame", stdout);
            return;
        }
        printf("main frame \"%s\"", name8.c_str());
        return;
    }
    if (!name8.length()) {
        fputs("frame (anonymous)", stdout);
        return;
    }
    printf("frame \"%s\"", name8.c_str());
}

void WebViewHost::printFrameUserGestureStatus(WebFrame* webframe, const char* msg)
{
    bool isUserGesture = webframe->isProcessingUserGesture();
    printf("Frame with user gesture \"%s\"%s", isUserGesture ? "true" : "false", msg);
}

void WebViewHost::printResourceDescription(unsigned identifier)
{
    ResourceMap::iterator it = m_resourceIdentifierMap.find(identifier);
    printf("%s", it != m_resourceIdentifierMap.end() ? it->second.c_str() : "<unknown>");
}

void WebViewHost::setPendingExtraData(TestShellExtraData* extraData)
{
    m_pendingExtraData.set(extraData);
}

void WebViewHost::setPageTitle(const WebString&)
{
    // Nothing to do in layout test.
}

void WebViewHost::setAddressBarURL(const WebURL&)
{
    // Nothing to do in layout test.
}

// Painting functions ---------------------------------------------------------

void WebViewHost::updatePaintRect(const WebRect& rect)
{
    // m_paintRect = m_paintRect U rect
    if (rect.isEmpty())
        return;
    if (m_paintRect.isEmpty()) {
        m_paintRect = rect;
        return;
    }
    int left = min(m_paintRect.x, rect.x);
    int top = min(m_paintRect.y, rect.y);
    int right = max(m_paintRect.x + m_paintRect.width, rect.x + rect.width);
    int bottom = max(m_paintRect.y + m_paintRect.height, rect.y + rect.height);
    m_paintRect = WebRect(left, top, right - left, bottom - top);
}

void WebViewHost::paintRect(const WebRect& rect)
{
    ASSERT(!m_isPainting);
    ASSERT(canvas());
    m_isPainting = true;
#if USE(CG)
    webWidget()->paint(skia::BeginPlatformPaint(canvas()), rect);
    skia::EndPlatformPaint(canvas());
#else
    webWidget()->paint(canvas(), rect);
#endif
    m_isPainting = false;
}

void WebViewHost::paintInvalidatedRegion()
{
#if ENABLE(REQUEST_ANIMATION_FRAME)
    webWidget()->animate();
#endif
    webWidget()->layout();
    WebSize widgetSize = webWidget()->size();
    WebRect clientRect(0, 0, widgetSize.width, widgetSize.height);

    // Paint the canvas if necessary.  Allow painting to generate extra rects
    // for the first two calls. This is necessary because some WebCore rendering
    // objects update their layout only when painted.
    // Store the total area painted in total_paint. Then tell the gdk window
    // to update that area after we're done painting it.
    for (int i = 0; i < 3; ++i) {
        // m_paintRect = intersect(m_paintRect , clientRect)
        int left = max(m_paintRect.x, clientRect.x);
        int top = max(m_paintRect.y, clientRect.y);
        int right = min(m_paintRect.x + m_paintRect.width, clientRect.x + clientRect.width);
        int bottom = min(m_paintRect.y + m_paintRect.height, clientRect.y + clientRect.height);
        if (left >= right || top >= bottom)
            m_paintRect = WebRect();
        else
            m_paintRect = WebRect(left, top, right - left, bottom - top);

        if (m_paintRect.isEmpty())
            continue;
        WebRect rect(m_paintRect);
        m_paintRect = WebRect();
        paintRect(rect);
    }
    ASSERT(m_paintRect.isEmpty());
}

SkCanvas* WebViewHost::canvas()
{
    if (m_canvas)
        return m_canvas.get();
    WebSize widgetSize = webWidget()->size();
    resetScrollRect();
    m_canvas.set(skia::CreateBitmapCanvas(
        widgetSize.width, widgetSize.height, true));
    return m_canvas.get();
}

void WebViewHost::resetScrollRect()
{
}

void WebViewHost::discardBackingStore()
{
    m_canvas.clear();
}

// Paints the entire canvas a semi-transparent black (grayish). This is used
// by the layout tests in fast/repaint. The alpha value matches upstream.
void WebViewHost::displayRepaintMask()
{
    canvas()->drawARGB(167, 0, 0, 0);
}
