/*
 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
 * Copyright (c) 2012 Hewlett-Packard Development Company, L.P.
 * Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this program; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#include "config.h"
#include "qquickwebview_p.h"

#include "CoordinatedLayerTreeHostProxy.h"
#include "DownloadProxy.h"
#include "DrawingAreaProxyImpl.h"
#include "PageViewportControllerClientQt.h"
#include "QtDialogRunner.h"
#include "QtDownloadManager.h"
#include "QtWebContext.h"
#include "QtWebError.h"
#include "QtWebIconDatabaseClient.h"
#include "QtWebPageEventHandler.h"
#include "QtWebPagePolicyClient.h"
#include "WebBackForwardList.h"
#include "WebContext.h"
#include "WebFindOptions.h"
#if ENABLE(INSPECTOR_SERVER)
#include "WebInspectorProxy.h"
#include "WebInspectorServer.h"
#endif
#if ENABLE(FULLSCREEN_API)
#include "WebFullScreenManagerProxy.h"
#endif
#include "WebPageGroup.h"
#include "WebPreferences.h"
#include "qglobal.h"
#include "qquicknetworkreply_p.h"
#include "qquicknetworkrequest_p.h"
#include "qquickwebpage_p_p.h"
#include "qquickwebview_p_p.h"
#include "qwebdownloaditem_p_p.h"
#include "qwebiconimageprovider_p.h"
#include "qwebkittest_p.h"
#include "qwebloadrequest_p.h"
#include "qwebnavigationhistory_p.h"
#include "qwebnavigationhistory_p_p.h"
#include "qwebpreferences_p.h"
#include "qwebpreferences_p_p.h"
#include <JavaScriptCore/InitializeThreading.h>
#include <JavaScriptCore/JSBase.h>
#include <JavaScriptCore/JSRetainPtr.h>
#include <QDateTime>
#include <QMap>
#include <QtCore/QFile>
#include <QtQml/QJSValue>
#include <QtQuick/QQuickView>
#include <WKNumber.h>
#include <WKOpenPanelResultListener.h>
#include <WKPageGroup.h>
#include <WKPreferences.h>
#include <WKSerializedScriptValue.h>
#include <WKString.h>
#include <WKStringQt.h>
#include <WKURLQt.h>
#include <WebCore/CoordinatedGraphicsScene.h>
#include <WebCore/IntPoint.h>
#include <WebCore/IntRect.h>
#include <limits>
#include <wtf/Assertions.h>
#include <wtf/MainThread.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>

using namespace WebCore;
using namespace WebKit;

static bool s_flickableViewportEnabled = true;
static const int kAxisLockSampleCount = 5;
static const qreal kAxisLockVelocityThreshold = 300;
static const qreal kAxisLockVelocityDirectionThreshold = 50;

typedef QMap<WKPageRef, QQuickWebViewPrivate*> PageToViewMap;
Q_GLOBAL_STATIC(PageToViewMap, pageToView)

static inline QQuickWebViewPrivate* toQQuickWebViewPrivate(const void* clientInfo)
{
    ASSERT(clientInfo);
    return reinterpret_cast<QQuickWebViewPrivate*>(const_cast<void*>(clientInfo));
}

struct JSCallbackClosure {
    QPointer<QObject> receiver;
    QByteArray method;
    QJSValue value;
};

static inline QString toQString(JSStringRef string)
{
    return QString(reinterpret_cast<const QChar*>(JSStringGetCharactersPtr(string)), JSStringGetLength(string));
}

static inline QJSValue toQJSValue(JSStringRef string)
{
    return QJSValue(toQString(string));
}

static QJSValue buildQJSValue(QJSEngine* engine, JSGlobalContextRef context, JSValueRef value, int depth)
{
    QJSValue var;
    JSValueRef exception = 0;

    if (depth > 10)
        return var;

    switch (JSValueGetType(context, value)) {
    case kJSTypeBoolean:
        var = QJSValue(JSValueToBoolean(context, value));
        break;
    case kJSTypeNumber:
        {
            double number = JSValueToNumber(context, value, &exception);
            if (!exception)
                var = QJSValue(number);
        }
        break;
    case kJSTypeString:
        {
            JSRetainPtr<JSStringRef> string = JSValueToStringCopy(context, value, &exception);
            if (!exception)
                var = toQJSValue(string.get());
        }
        break;
    case kJSTypeObject:
        {
            JSObjectRef obj = JSValueToObject(context, value, &exception);

            JSPropertyNameArrayRef names = JSObjectCopyPropertyNames(context, obj);
            size_t length = JSPropertyNameArrayGetCount(names);

            var = engine->newObject();

            for (size_t i = 0; i < length; ++i) {
                JSRetainPtr<JSStringRef> name = JSPropertyNameArrayGetNameAtIndex(names, i);
                JSValueRef property = JSObjectGetProperty(context, obj, name.get(), &exception);

                if (!exception) {
                    QJSValue value = buildQJSValue(engine, context, property, depth + 1);
                    var.setProperty(toQString(name.get()), value);
                }
            }
        }
        break;
    }
    return var;
}

static void javaScriptCallback(WKSerializedScriptValueRef valueRef, WKErrorRef, void* data)
{
    JSCallbackClosure* closure = reinterpret_cast<JSCallbackClosure*>(data);

    if (closure->method.size())
        QMetaObject::invokeMethod(closure->receiver, closure->method);
    else {
        QJSValue function = closure->value;

        // If a callable function is supplied, we build a JavaScript value accessible
        // in the QML engine, and calls the function with that.
        if (function.isCallable()) {
            QJSValue var;
            if (valueRef) {
                // FIXME: Slow but OK for now.
                JSGlobalContextRef context = JSGlobalContextCreate(0);

                JSValueRef exception = 0;
                JSValueRef value = WKSerializedScriptValueDeserialize(valueRef, context, &exception);
                var = buildQJSValue(function.engine(), context, value, /* depth */ 0);

                JSGlobalContextRelease(context);
            }

            QList<QJSValue> args;
            args.append(var);
            function.call(args);
        }
    }

    delete closure;
}

static QQuickWebViewPrivate* createPrivateObject(QQuickWebView* publicObject)
{
    if (s_flickableViewportEnabled)
        return new QQuickWebViewFlickablePrivate(publicObject);
    return new QQuickWebViewLegacyPrivate(publicObject);
}

QQuickWebViewPrivate* QQuickWebViewPrivate::get(WKPageRef page)
{
    return pageToView()->value(page);
}

QQuickWebViewPrivate::FlickableAxisLocker::FlickableAxisLocker()
    : m_allowedDirection(QQuickFlickable::AutoFlickDirection)
    , m_time(0), m_sampleCount(0)
{
}

QVector2D QQuickWebViewPrivate::FlickableAxisLocker::touchVelocity(const QTouchEvent* event)
{
    static bool touchVelocityAvailable = event->device()->capabilities().testFlag(QTouchDevice::Velocity);
    const QTouchEvent::TouchPoint& touchPoint = event->touchPoints().first();

    if (touchVelocityAvailable)
        return touchPoint.velocity();

    const QLineF movementLine(touchPoint.pos(), m_initialPosition);
    const ulong elapsed = event->timestamp() - m_time;

    if (!elapsed)
        return QVector2D(0, 0);

    // Calculate an approximate velocity vector in the unit of pixel / second.
    return QVector2D(1000 * movementLine.dx() / elapsed, 1000 * movementLine.dy() / elapsed);
}

void QQuickWebViewPrivate::FlickableAxisLocker::update(const QTouchEvent* event)
{
    ASSERT(event->touchPoints().size() == 1);
    const QTouchEvent::TouchPoint& touchPoint = event->touchPoints().first();

    ++m_sampleCount;

    if (m_sampleCount == 1) {
        m_initialPosition = touchPoint.pos();
        m_time = event->timestamp();
        return;
    }

    if (m_sampleCount > kAxisLockSampleCount
            || m_allowedDirection == QQuickFlickable::HorizontalFlick
            || m_allowedDirection == QQuickFlickable::VerticalFlick)
        return;

    QVector2D velocity = touchVelocity(event);

    qreal directionIndicator = qAbs(velocity.x()) - qAbs(velocity.y());

    if (velocity.length() > kAxisLockVelocityThreshold && qAbs(directionIndicator) > kAxisLockVelocityDirectionThreshold)
        m_allowedDirection = (directionIndicator > 0) ? QQuickFlickable::HorizontalFlick : QQuickFlickable::VerticalFlick;
}

void QQuickWebViewPrivate::FlickableAxisLocker::setReferencePosition(const QPointF& position)
{
    m_lockReferencePosition = position;
}

void QQuickWebViewPrivate::FlickableAxisLocker::reset()
{
    m_allowedDirection = QQuickFlickable::AutoFlickDirection;
    m_sampleCount = 0;
}

QPointF QQuickWebViewPrivate::FlickableAxisLocker::adjust(const QPointF& position)
{
    if (m_allowedDirection == QQuickFlickable::HorizontalFlick)
        return QPointF(position.x(), m_lockReferencePosition.y());

    if (m_allowedDirection == QQuickFlickable::VerticalFlick)
        return QPointF(m_lockReferencePosition.x(), position.y());

    return position;
}

QQuickWebViewPrivate::QQuickWebViewPrivate(QQuickWebView* viewport)
    : q_ptr(viewport)
    , experimental(new QQuickWebViewExperimental(viewport, this))
    , context(0)
    , alertDialog(0)
    , confirmDialog(0)
    , promptDialog(0)
    , authenticationDialog(0)
    , certificateVerificationDialog(0)
    , itemSelector(0)
    , proxyAuthenticationDialog(0)
    , filePicker(0)
    , databaseQuotaDialog(0)
    , colorChooser(0)
    , m_betweenLoadCommitAndFirstFrame(false)
    , m_useDefaultContentItemSize(true)
    , m_navigatorQtObjectEnabled(false)
    , m_renderToOffscreenBuffer(false)
    , m_allowAnyHTTPSCertificateForLocalHost(false)
    , m_loadProgress(0)
{
    viewport->setClip(true);
    viewport->setPixelAligned(true);
    QObject::connect(viewport, SIGNAL(visibleChanged()), viewport, SLOT(_q_onVisibleChanged()));
    QObject::connect(viewport, SIGNAL(urlChanged()), viewport, SLOT(_q_onUrlChanged()));
    pageView.reset(new QQuickWebPage(viewport));
}

QQuickWebViewPrivate::~QQuickWebViewPrivate()
{
    webPageProxy->close();
    pageToView()->remove(webPage.get());
}

// Note: we delay this initialization to make sure that QQuickWebView has its d-ptr in-place.
void QQuickWebViewPrivate::initialize(WKContextRef contextRef, WKPageGroupRef pageGroupRef)
{
    pageGroup = pageGroupRef;
    if (!pageGroup)
        pageGroup = adoptWK(WKPageGroupCreateWithIdentifier(0));

    context = contextRef ? QtWebContext::create(contextRef) : QtWebContext::defaultContext();
    webPageProxy = toImpl(context->context())->createWebPage(&pageClient, toImpl(pageGroup.get()));
    webPage = toAPI(webPageProxy.get());
    pageToView()->insert(webPage.get(), this);

    webPageProxy->setUseFixedLayout(s_flickableViewportEnabled);
#if ENABLE(FULLSCREEN_API)
    webPageProxy->fullScreenManager()->setWebView(q_ptr);
#endif

    pageEventHandler.reset(new QtWebPageEventHandler(webPage.get(), pageView.data(), q_ptr));

    {
        WKPageFindClient findClient;
        memset(&findClient, 0, sizeof(WKPageFindClient));
        findClient.version = kWKPageFindClientCurrentVersion;
        findClient.clientInfo = this;
        findClient.didFindString = didFindString;
        findClient.didFailToFindString = didFailToFindString;
        WKPageSetPageFindClient(webPage.get(), &findClient);
    }

    {
        WKPageLoaderClient loadClient;
        memset(&loadClient, 0, sizeof(WKPageLoaderClient));
        loadClient.version = kWKPageLoaderClientCurrentVersion;
        loadClient.clientInfo = this;
        loadClient.didStartProvisionalLoadForFrame = didStartProvisionalLoadForFrame;
        loadClient.didReceiveServerRedirectForProvisionalLoadForFrame = didReceiveServerRedirectForProvisionalLoadForFrame;
        loadClient.didFailProvisionalLoadWithErrorForFrame = didFailLoad;
        loadClient.didCommitLoadForFrame = didCommitLoadForFrame;
        loadClient.didFinishLoadForFrame = didFinishLoadForFrame;
        loadClient.didFailLoadWithErrorForFrame = didFailLoad;
        loadClient.didSameDocumentNavigationForFrame = didSameDocumentNavigationForFrame;
        loadClient.didReceiveTitleForFrame = didReceiveTitleForFrame;
        loadClient.didStartProgress = didStartProgress;
        loadClient.didChangeProgress = didChangeProgress;
        loadClient.didFinishProgress = didFinishProgress;
        loadClient.didChangeBackForwardList = didChangeBackForwardList;
        WKPageSetPageLoaderClient(webPage.get(), &loadClient);
    }

    pagePolicyClient.reset(new QtWebPagePolicyClient(webPage.get(), q_ptr));
    pageUIClient.reset(new QtWebPageUIClient(webPage.get(), q_ptr));
    navigationHistory = adoptPtr(QWebNavigationHistoryPrivate::createHistory(webPage.get()));

    QtWebIconDatabaseClient* iconDatabase = context->iconDatabase();
    QObject::connect(iconDatabase, SIGNAL(iconChangedForPageURL(QString)), q_ptr, SLOT(_q_onIconChangedForPageURL(QString)));

    // Any page setting should preferrable be set before creating the page.
    WKPreferencesRef preferencesRef = WKPageGroupGetPreferences(pageGroup.get());
    WKPreferencesSetAcceleratedCompositingEnabled(preferencesRef, true);
    bool showDebugVisuals = qgetenv("WEBKIT_SHOW_COMPOSITING_DEBUG_VISUALS") == "1";
    WKPreferencesSetCompositingBordersVisible(preferencesRef, showDebugVisuals);
    WKPreferencesSetCompositingRepaintCountersVisible(preferencesRef, showDebugVisuals);
    WKPreferencesSetFrameFlatteningEnabled(preferencesRef, true);
    WKPreferencesSetWebGLEnabled(preferencesRef, true);
    webPageProxy->pageGroup()->preferences()->setForceCompositingMode(true);

    pageClient.initialize(q_ptr, pageEventHandler.data(), &undoController);
    webPageProxy->initializeWebPage();
    webPageProxy->registerApplicationScheme(ASCIILiteral("qrc"));

    q_ptr->setAcceptedMouseButtons(Qt::MouseButtonMask);
    q_ptr->setAcceptHoverEvents(true);
    q_ptr->setFlag(QQuickItem::ItemAcceptsDrops, true);
}

void QQuickWebViewPrivate::didStartProvisionalLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef, const void* clientInfo)
{
    if (!WKFrameIsMainFrame(frame))
        return;

    WKRetainPtr<WKURLRef> url  = adoptWK(WKFrameCopyProvisionalURL(frame));

    QQuickWebView* const q = toQQuickWebViewPrivate(clientInfo)->q_func();

    q->emitUrlChangeIfNeeded();
    QWebLoadRequest loadRequest(WKURLCopyQUrl(url.get()), QQuickWebView::LoadStartedStatus);
    emit q->loadingChanged(&loadRequest);
}

void QQuickWebViewPrivate::didReceiveServerRedirectForProvisionalLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef, const void* clientInfo)
{
    if (!WKFrameIsMainFrame(frame))
        return;

    toQQuickWebViewPrivate(clientInfo)->q_func()->emitUrlChangeIfNeeded();
}

void QQuickWebViewPrivate::didFailLoad(WKPageRef, WKFrameRef frame, WKErrorRef errorRef, WKTypeRef, const void* clientInfo)
{
    if (!WKFrameIsMainFrame(frame))
        return;

    QQuickWebView* const q = toQQuickWebViewPrivate(clientInfo)->q_func();
    ASSERT(!q->loading());

    QtWebError error(errorRef);
    if (error.isCancellation()) {
        QWebLoadRequest loadRequest(q->url(), QQuickWebView::LoadStoppedStatus);
        emit q->loadingChanged(&loadRequest);
        return;
    }

    int errorCode = error.errorCode();
    if (errorCode == kWKErrorCodeFrameLoadInterruptedByPolicyChange && errorCode == kWKErrorCodePlugInWillHandleLoad) {
        QWebLoadRequest loadRequest(q->url(), QQuickWebView::LoadSucceededStatus);
        q->emitUrlChangeIfNeeded();
        emit q->loadingChanged(&loadRequest);
        return;
    }

    // We set the unreachable url unconditionally so that the current
    // active url of the webview when the loadingChanged signal is
    // emitted reflects the failed url, not the previously committed
    // url. This also ensures that if the user does not do a loadHtml
    // with an error page and and unreachable url as a reponse to the
    // failed load, we can still detect the failed url for reloads.
    // We need to find a way to do this via the C API or find another
    // way to do this.
    toImpl(frame)->setUnreachableURL(error.url());
    q->emitUrlChangeIfNeeded();
    QWebLoadRequest loadRequest(error.url(), QQuickWebView::LoadFailedStatus, error.description(), static_cast<QQuickWebView::ErrorDomain>(error.type()), errorCode);
    emit q->loadingChanged(&loadRequest);
}

void QQuickWebViewPrivate::didCommitLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef, const void* clientInfo)
{
    if (!WKFrameIsMainFrame(frame))
        return;
    QQuickWebViewPrivate* d = toQQuickWebViewPrivate(clientInfo);

    PageViewportController* pageViewportController = d->viewportController();
    if (pageViewportController)
        pageViewportController->didCommitLoad();

    QQuickWebView* const q = d->q_func();
    ASSERT(q->loading());
    d->m_betweenLoadCommitAndFirstFrame = true;
    emit q->navigationHistoryChanged();
    emit q->titleChanged();
}

void QQuickWebViewPrivate::didFinishLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef, const void* clientInfo)
{
    if (!WKFrameIsMainFrame(frame))
        return;

    QQuickWebView* const q = toQQuickWebViewPrivate(clientInfo)->q_func();
    ASSERT(!q->loading());

    QWebLoadRequest loadRequest(q->url(), QQuickWebView::LoadSucceededStatus);
    emit q->loadingChanged(&loadRequest);
}

void QQuickWebViewPrivate::didSameDocumentNavigationForFrame(WKPageRef, WKFrameRef frame, WKSameDocumentNavigationType type, WKTypeRef userData, const void* clientInfo)
{
    if (!WKFrameIsMainFrame(frame))
        return;
    QQuickWebView* const q = toQQuickWebViewPrivate(clientInfo)->q_func();
    q->emitUrlChangeIfNeeded();
    emit q->navigationHistoryChanged();
}

void QQuickWebViewPrivate::didReceiveTitleForFrame(WKPageRef, WKStringRef title, WKFrameRef frame, WKTypeRef, const void* clientInfo)
{
    if (!WKFrameIsMainFrame(frame))
        return;
    emit toQQuickWebViewPrivate(clientInfo)->q_func()->titleChanged();
}

void QQuickWebViewPrivate::didStartProgress(WKPageRef, const void* clientInfo)
{
    toQQuickWebViewPrivate(clientInfo)->loadProgressDidChange(0);
}

void QQuickWebViewPrivate::didChangeProgress(WKPageRef page, const void* clientInfo)
{
    toQQuickWebViewPrivate(clientInfo)->loadProgressDidChange(WKPageGetEstimatedProgress(page) * 100);
}

void QQuickWebViewPrivate::didFinishProgress(WKPageRef, const void* clientInfo)
{
    toQQuickWebViewPrivate(clientInfo)->loadProgressDidChange(100);
}

void QQuickWebViewPrivate::didChangeBackForwardList(WKPageRef, WKBackForwardListItemRef, WKArrayRef, const void *clientInfo)
{
    toQQuickWebViewPrivate(clientInfo)->navigationHistory->d->reset();
}

void QQuickWebViewPrivate::setTransparentBackground(bool enable)
{
    webPageProxy->setDrawsTransparentBackground(enable);
}

bool QQuickWebViewPrivate::transparentBackground() const
{
    return webPageProxy->drawsTransparentBackground();
}

void QQuickWebViewPrivate::loadProgressDidChange(int loadProgress)
{
    Q_Q(QQuickWebView);

    m_loadProgress = loadProgress;

    emit q->loadProgressChanged();
}

void QQuickWebViewPrivate::handleMouseEvent(QMouseEvent* event)
{
    switch (event->type()) {
    case QEvent::MouseButtonPress:
        pageEventHandler->handleMousePressEvent(event);
        break;
    case QEvent::MouseMove:
        pageEventHandler->handleMouseMoveEvent(event);
        break;
    case QEvent::MouseButtonRelease:
        pageEventHandler->handleMouseReleaseEvent(event);
        break;
    case QEvent::MouseButtonDblClick:
        // If a MouseButtonDblClick was received then we got a MouseButtonPress before.
        // WebCore will build double-clicks out of press events.
        event->accept();
        break;
    default:
        ASSERT_NOT_REACHED();
        break;
    }
}

void QQuickWebViewPrivate::setNeedsDisplay()
{
    Q_Q(QQuickWebView);
    if (renderToOffscreenBuffer()) {
        // This is used only to mantain the rendering synchronisation between the UI and
        // the web process when running tests even if the render loop is not active.
        QImage dummyImage(1, 1, QImage::Format_ARGB32);
        QPainter painter(&dummyImage);
        q->page()->d->paint(&painter);
        return;
    }
    q->page()->update();
}

void QQuickWebViewPrivate::didRenderFrame()
{
    Q_Q(QQuickWebView);
    if (m_betweenLoadCommitAndFirstFrame) {
        emit q->experimental()->loadVisuallyCommitted();
        m_betweenLoadCommitAndFirstFrame = false;
    }
}

void QQuickWebViewPrivate::processDidCrash()
{
    Q_Q(QQuickWebView);

    QUrl url(KURL(WebCore::ParsedURLString, webPageProxy->urlAtProcessExit()));
    qWarning("WARNING: The web process experienced a crash on '%s'.", qPrintable(url.toString(QUrl::RemoveUserInfo)));

    pageEventHandler->resetGestureRecognizers();

    // Check if loading was ongoing, when process crashed.
    if (m_loadProgress > 0 && m_loadProgress < 100) {
        QWebLoadRequest loadRequest(url, QQuickWebView::LoadFailedStatus, QLatin1String("The web process crashed."), QQuickWebView::InternalErrorDomain, 0);

        loadProgressDidChange(100);
        emit q->loadingChanged(&loadRequest);
    }
}

void QQuickWebViewPrivate::didRelaunchProcess()
{
    qWarning("WARNING: The web process has been successfully restarted.");

    if (DrawingAreaProxy *drawingArea = webPageProxy->drawingArea()) {
        drawingArea->setSize(viewSize(), IntSize(), IntSize());

        updateViewportSize();
        updateUserScripts();
        updateSchemeDelegates();
    }
}

PassOwnPtr<DrawingAreaProxy> QQuickWebViewPrivate::createDrawingAreaProxy()
{
    return DrawingAreaProxyImpl::create(webPageProxy.get());
}

void QQuickWebViewPrivate::handleDownloadRequest(DownloadProxy* download)
{
    Q_Q(QQuickWebView);
    // This function is responsible for hooking up a DownloadProxy to our API layer
    // by creating a QWebDownloadItem. It will then wait for the QWebDownloadItem to be
    // ready (filled with the ResourceResponse information) so we can pass it through to
    // our WebViews.
    QWebDownloadItem* downloadItem = new QWebDownloadItem();
    downloadItem->d->downloadProxy = download;

    q->connect(downloadItem->d, SIGNAL(receivedResponse(QWebDownloadItem*)), q, SLOT(_q_onReceivedResponseFromDownload(QWebDownloadItem*)));
    QtWebContext::defaultContext()->downloadManager()->addDownload(toAPI(download), downloadItem);
}

void QQuickWebViewPrivate::_q_onVisibleChanged()
{
    webPageProxy->viewStateDidChange(WebPageProxy::ViewIsVisible);
}

void QQuickWebViewPrivate::_q_onUrlChanged()
{
    updateIcon();
}

void QQuickWebViewPrivate::_q_onIconChangedForPageURL(const QString& pageUrl)
{
    if (pageUrl != m_currentUrl)
        return;

    updateIcon();
}

/* Called either when the url changes, or when the icon for the current page changes */
void QQuickWebViewPrivate::updateIcon()
{
    Q_Q(QQuickWebView);

    QQuickView* view = qobject_cast<QQuickView*>(q->window());
    if (!view)
        return;

    QWebIconImageProvider* provider = static_cast<QWebIconImageProvider*>(
                view->engine()->imageProvider(QWebIconImageProvider::identifier()));
    if (!provider)
        return;

    QUrl iconUrl = provider->iconURLForPageURLInContext(m_currentUrl, context);

    if (iconUrl == m_iconUrl)
        return;

    m_iconUrl = iconUrl;
    emit q->iconChanged();
}

void QQuickWebViewPrivate::_q_onReceivedResponseFromDownload(QWebDownloadItem* downloadItem)
{
    // Now that our downloadItem has everything we need we can emit downloadRequested.
    if (!downloadItem)
        return;

    Q_Q(QQuickWebView);
    QQmlEngine::setObjectOwnership(downloadItem, QQmlEngine::JavaScriptOwnership);
    emit q->experimental()->downloadRequested(downloadItem);
}

void QQuickWebViewPrivate::runJavaScriptAlert(const QString& alertText)
{
    Q_Q(QQuickWebView);
    QtDialogRunner dialogRunner(q);
    if (!dialogRunner.initForAlert(alertText))
        return;

    dialogRunner.run();
}

bool QQuickWebViewPrivate::runJavaScriptConfirm(const QString& message)
{
    Q_Q(QQuickWebView);
    QtDialogRunner dialogRunner(q);
    if (!dialogRunner.initForConfirm(message))
        return true;

    dialogRunner.run();

    return dialogRunner.wasAccepted();
}

QString QQuickWebViewPrivate::runJavaScriptPrompt(const QString& message, const QString& defaultValue, bool& ok)
{
    Q_Q(QQuickWebView);
    QtDialogRunner dialogRunner(q);
    if (!dialogRunner.initForPrompt(message, defaultValue)) {
        ok = true;
        return defaultValue;
    }

    dialogRunner.run();

    ok = dialogRunner.wasAccepted();
    return dialogRunner.result();
}

void QQuickWebViewPrivate::handleAuthenticationRequiredRequest(const QString& hostname, const QString& realm, const QString& prefilledUsername, QString& username, QString& password)
{
    Q_Q(QQuickWebView);
    QtDialogRunner dialogRunner(q);
    if (!dialogRunner.initForAuthentication(hostname, realm, prefilledUsername))
        return;

    dialogRunner.run();

    username = dialogRunner.username();
    password = dialogRunner.password();
}

void QQuickWebViewPrivate::handleProxyAuthenticationRequiredRequest(const QString& hostname, uint16_t port, const QString& prefilledUsername, QString& username, QString& password)
{
    Q_Q(QQuickWebView);
    QtDialogRunner dialogRunner(q);
    if (!dialogRunner.initForProxyAuthentication(hostname, port, prefilledUsername))
        return;

    dialogRunner.run();

    username = dialogRunner.username();
    password = dialogRunner.password();
}

bool QQuickWebViewPrivate::handleCertificateVerificationRequest(const QString& hostname)
{
    Q_Q(QQuickWebView);

    if (m_allowAnyHTTPSCertificateForLocalHost
        && (hostname == QStringLiteral("127.0.0.1") || hostname == QStringLiteral("localhost")))
        return true;

    QtDialogRunner dialogRunner(q);
    if (!dialogRunner.initForCertificateVerification(hostname))
        return false;

    dialogRunner.run();

    return dialogRunner.wasAccepted();
}

void QQuickWebViewPrivate::chooseFiles(WKOpenPanelResultListenerRef listenerRef, const QStringList& selectedFileNames, QtWebPageUIClient::FileChooserType type)
{
    Q_Q(QQuickWebView);

    QtDialogRunner dialogRunner(q);
    if (!dialogRunner.initForFilePicker(selectedFileNames, (type == QtWebPageUIClient::MultipleFilesSelection)))
        return;

    dialogRunner.run();

    if (dialogRunner.wasAccepted()) {
        QStringList selectedPaths = dialogRunner.filePaths();

        Vector<RefPtr<APIObject> > wkFiles(selectedPaths.size());
        for (unsigned i = 0; i < selectedPaths.size(); ++i)
            wkFiles[i] = WebURL::create(QUrl::fromLocalFile(selectedPaths.at(i)).toString());            

        WKOpenPanelResultListenerChooseFiles(listenerRef, toAPI(ImmutableArray::adopt(wkFiles).leakRef()));
    } else
        WKOpenPanelResultListenerCancel(listenerRef);

}

quint64 QQuickWebViewPrivate::exceededDatabaseQuota(const QString& databaseName, const QString& displayName, WKSecurityOriginRef securityOrigin, quint64 currentQuota, quint64 currentOriginUsage, quint64 currentDatabaseUsage, quint64 expectedUsage)
{
    Q_Q(QQuickWebView);
    QtDialogRunner dialogRunner(q);
    if (!dialogRunner.initForDatabaseQuotaDialog(databaseName, displayName, securityOrigin, currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage))
        return 0;

    dialogRunner.run();

    return dialogRunner.wasAccepted() ? dialogRunner.databaseQuota() : 0;
}

/* The 'WebView' attached property allows items spawned by the webView to
   refer back to the originating webView through 'WebView.view', similar
   to how ListView.view and GridView.view is exposed to items. */
QQuickWebViewAttached::QQuickWebViewAttached(QObject* object)
    : QObject(object)
    , m_view(0)
{
}

void QQuickWebViewAttached::setView(QQuickWebView* view)
{
    if (m_view == view)
        return;
    m_view = view;
    emit viewChanged();
}

QQuickWebViewAttached* QQuickWebView::qmlAttachedProperties(QObject* object)
{
    return new QQuickWebViewAttached(object);
}



void QQuickWebViewPrivate::addAttachedPropertyTo(QObject* object)
{
    Q_Q(QQuickWebView);
    QQuickWebViewAttached* attached = static_cast<QQuickWebViewAttached*>(qmlAttachedPropertiesObject<QQuickWebView>(object));
    attached->setView(q);
}

bool QQuickWebViewPrivate::navigatorQtObjectEnabled() const
{
    return m_navigatorQtObjectEnabled;
}

void QQuickWebViewPrivate::setNavigatorQtObjectEnabled(bool enabled)
{
    ASSERT(enabled != m_navigatorQtObjectEnabled);
    // FIXME: Currently we have to keep this information in both processes and the setting is asynchronous.
    m_navigatorQtObjectEnabled = enabled;

    static WKStringRef messageName = WKStringCreateWithUTF8CString("SetNavigatorQtObjectEnabled");
    WKRetainPtr<WKBooleanRef> wkEnabled = adoptWK(WKBooleanCreate(enabled));
    WKPagePostMessageToInjectedBundle(webPage.get(), messageName, wkEnabled.get());
}

static WKRetainPtr<WKStringRef> readUserScript(const QUrl& url)
{
    QString path;
    if (url.isLocalFile())
        path = url.toLocalFile();
    else if (url.scheme() == QLatin1String("qrc"))
        path = QStringLiteral(":") + url.path();
    else {
        qWarning("QQuickWebView: Couldn't open '%s' as user script because only file:/// and qrc:/// URLs are supported.", qPrintable(url.toString()));
        return 0;
    }

    QFile file(path);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning("QQuickWebView: Couldn't open '%s' as user script due to error '%s'.", qPrintable(url.toString()), qPrintable(file.errorString()));
        return 0;
    }

    QByteArray contents = file.readAll();
    if (contents.isEmpty())
        qWarning("QQuickWebView: Ignoring '%s' as user script because file is empty.", qPrintable(url.toString()));

    return adoptWK(WKStringCreateWithUTF8CString(contents.constData()));
}

void QQuickWebViewPrivate::updateUserScripts()
{
    // This feature works per-WebView because we keep an unique page group for
    // each Page/WebView pair we create.
    WKPageGroupRemoveAllUserScripts(pageGroup.get());

    for (unsigned i = 0; i < userScripts.size(); ++i) {
        const QUrl& url = userScripts.at(i);
        if (!url.isValid()) {
            qWarning("QQuickWebView: Couldn't open '%s' as user script because URL is invalid.", qPrintable(url.toString()));
            continue;
        }

        WKRetainPtr<WKStringRef> contents = readUserScript(url);
        if (!contents || WKStringIsEmpty(contents.get()))
            continue;
        WKPageGroupAddUserScript(pageGroup.get(), contents.get(), /*baseURL*/ 0, /*whitelistedURLPatterns*/ 0, /*blacklistedURLPatterns*/ 0, kWKInjectInTopFrameOnly, kWKInjectAtDocumentEnd);
    }
}

void QQuickWebViewPrivate::updateSchemeDelegates()
{
    webPageProxy->registerApplicationScheme(ASCIILiteral("qrc"));

    QQmlListProperty<QQuickUrlSchemeDelegate> schemes = experimental->schemeDelegates();
    for (int i = 0, numSchemes = experimental->schemeDelegates_Count(&schemes); i < numSchemes; ++i) {
        QQuickUrlSchemeDelegate* scheme = experimental->schemeDelegates_At(&schemes, i);
        webPageProxy->registerApplicationScheme(scheme->scheme());
    }
}

QPointF QQuickWebViewPrivate::contentPos() const
{
    Q_Q(const QQuickWebView);
    return QPointF(q->contentX(), q->contentY());
}

void QQuickWebViewPrivate::setContentPos(const QPointF& pos)
{
    Q_Q(QQuickWebView);
    q->setContentX(pos.x());
    q->setContentY(pos.y());
}

WebCore::IntSize QQuickWebViewPrivate::viewSize() const
{
    return WebCore::IntSize(pageView->width(), pageView->height());
}

/*!
    \internal

    \qmlsignal WebViewExperimental::onMessageReceived(var message)

    \brief Emitted when JavaScript code executing on the web page calls navigator.qt.postMessage().

    \sa postMessage
*/
void QQuickWebViewPrivate::didReceiveMessageFromNavigatorQtObject(WKStringRef message)
{
    QVariantMap variantMap;
    variantMap.insert(QLatin1String("data"), WKStringCopyQString(message));
    variantMap.insert(QLatin1String("origin"), q_ptr->url());
    emit q_ptr->experimental()->messageReceived(variantMap);
}

CoordinatedGraphicsScene* QQuickWebViewPrivate::coordinatedGraphicsScene()
{
    if (webPageProxy && webPageProxy->drawingArea() && webPageProxy->drawingArea()->coordinatedLayerTreeHostProxy())
        return webPageProxy->drawingArea()->coordinatedLayerTreeHostProxy()->coordinatedGraphicsScene();

    return 0;
}

float QQuickWebViewPrivate::deviceScaleFactor()
{
    return webPageProxy->deviceScaleFactor();
}

void QQuickWebViewPrivate::setIntrinsicDeviceScaleFactor(float scaleFactor)
{
    webPageProxy->setIntrinsicDeviceScaleFactor(scaleFactor);
}

QQuickWebViewLegacyPrivate::QQuickWebViewLegacyPrivate(QQuickWebView* viewport)
    : QQuickWebViewPrivate(viewport)
{
}

void QQuickWebViewLegacyPrivate::initialize(WKContextRef contextRef, WKPageGroupRef pageGroupRef)
{
    QQuickWebViewPrivate::initialize(contextRef, pageGroupRef);

    // Trigger setting of correct visibility flags after everything was allocated and initialized.
    _q_onVisibleChanged();
}

void QQuickWebViewLegacyPrivate::updateViewportSize()
{
    Q_Q(QQuickWebView);
    QSizeF viewportSize = q->boundingRect().size();
    if (viewportSize.isEmpty())
        return;

    pageView->setContentsSize(viewportSize);

    if (DrawingAreaProxy *drawingArea = webPageProxy->drawingArea()) {
        // The fixed layout is handled by the FrameView and the drawing area doesn't behave differently
        // whether its fixed or not. We still need to tell the drawing area which part of it
        // has to be rendered on tiles, and in desktop mode it's all of it.
        drawingArea->setSize(viewportSize.toSize(), IntSize(), IntSize());
        // The backing store scale factor should already be set to the device pixel ratio
        // of the underlying window, thus we set the effective scale to 1 here.
        drawingArea->setVisibleContentsRect(FloatRect(FloatPoint(), FloatSize(viewportSize)), FloatPoint());
    }
}

qreal QQuickWebViewLegacyPrivate::zoomFactor() const
{
    return WKPageGetPageZoomFactor(webPage.get());
}

void QQuickWebViewLegacyPrivate::setZoomFactor(qreal factor)
{
    WKPageSetPageZoomFactor(webPage.get(), factor);
}

QQuickWebViewFlickablePrivate::QQuickWebViewFlickablePrivate(QQuickWebView* viewport)
    : QQuickWebViewPrivate(viewport)
{
}

void QQuickWebViewFlickablePrivate::initialize(WKContextRef contextRef, WKPageGroupRef pageGroupRef)
{
    QQuickWebViewPrivate::initialize(contextRef, pageGroupRef);
}

void QQuickWebViewFlickablePrivate::onComponentComplete()
{
    QQuickWebViewPrivate::onComponentComplete();

    Q_Q(QQuickWebView);
    m_pageViewportControllerClient.reset(new PageViewportControllerClientQt(q, pageView.data()));
    m_pageViewportController.reset(new PageViewportController(webPageProxy.get(), m_pageViewportControllerClient.data()));
    pageEventHandler->setViewportController(m_pageViewportControllerClient.data());

    // Trigger setting of correct visibility flags after everything was allocated and initialized.
    _q_onVisibleChanged();
}

void QQuickWebViewFlickablePrivate::didChangeViewportProperties(const WebCore::ViewportAttributes& newAttributes)
{
    if (m_pageViewportController)
        m_pageViewportController->didChangeViewportAttributes(newAttributes);
}

void QQuickWebViewFlickablePrivate::updateViewportSize()
{
    Q_Q(QQuickWebView);

    if (m_pageViewportController)
        m_pageViewportController->didChangeViewportSize(FloatSize(q->width(), q->height()));
}

void QQuickWebViewFlickablePrivate::pageDidRequestScroll(const QPoint& pos)
{
    if (m_pageViewportController)
        m_pageViewportController->pageDidRequestScroll(pos);
}

QQuickWebViewExperimental::QQuickWebViewExperimental(QQuickWebView *webView, QQuickWebViewPrivate* webViewPrivate)
    : QObject(webView)
    , q_ptr(webView)
    , d_ptr(webViewPrivate)
    , schemeParent(new QObject(this))
    , m_test(new QWebKitTest(webViewPrivate, this))
{
}

QQuickWebViewExperimental::~QQuickWebViewExperimental()
{
}

void QQuickWebViewExperimental::setRenderToOffscreenBuffer(bool enable)
{
    Q_D(QQuickWebView);
    d->setRenderToOffscreenBuffer(enable);
}

bool QQuickWebViewExperimental::renderToOffscreenBuffer() const
{
    Q_D(const QQuickWebView);
    return d->renderToOffscreenBuffer();
}

bool QQuickWebViewExperimental::transparentBackground() const
{
    Q_D(const QQuickWebView);
    return d->transparentBackground();
}
void QQuickWebViewExperimental::setTransparentBackground(bool enable)
{
    Q_D(QQuickWebView);
    d->setTransparentBackground(enable);
}

bool QQuickWebViewExperimental::useDefaultContentItemSize() const
{
    Q_D(const QQuickWebView);
    return d->m_useDefaultContentItemSize;
}

void QQuickWebViewExperimental::setUseDefaultContentItemSize(bool enable)
{
    Q_D(QQuickWebView);
    d->m_useDefaultContentItemSize = enable;
}

/*!
    \internal

    \qmlproperty int WebViewExperimental::preferredMinimumContentsWidth
    \brief Minimum contents width when not overriden by the page itself.

    Unless the page defines how contents should be laid out, using e.g.
    the viewport meta tag, it is laid out given the width of the viewport
    (in CSS units).

    This setting can be used to enforce a minimum width when the page
    does not define a width itself. This is useful for laying out pages
    designed for big screens, commonly knows as desktop pages, on small
    devices.

    The default value is 0, but the value of 980 is recommented for small
    screens as it provides a good trade off between legitable pages and
    non-broken content.
 */
int QQuickWebViewExperimental::preferredMinimumContentsWidth() const
{
    Q_D(const QQuickWebView);
    return d->webPageProxy->pageGroup()->preferences()->layoutFallbackWidth();
}

void QQuickWebViewExperimental::setPreferredMinimumContentsWidth(int width)
{
    Q_D(QQuickWebView);
    WebPreferences* webPreferences = d->webPageProxy->pageGroup()->preferences();

    if (width == webPreferences->layoutFallbackWidth())
        return;

    webPreferences->setLayoutFallbackWidth(width);
    emit preferredMinimumContentsWidthChanged();
}

void QQuickWebViewExperimental::setFlickableViewportEnabled(bool enable)
{
    s_flickableViewportEnabled = enable;
}

bool QQuickWebViewExperimental::flickableViewportEnabled()
{
    return s_flickableViewportEnabled;
}

/*!
    \internal

    \qmlmethod void WebViewExperimental::postMessage(string message)

    \brief Post a message to an onmessage function registered with the navigator.qt object
           by JavaScript code executing on the page.

    \sa onMessageReceived
*/

void QQuickWebViewExperimental::postMessage(const QString& message)
{
    Q_D(QQuickWebView);
    static WKStringRef messageName = WKStringCreateWithUTF8CString("MessageToNavigatorQtObject");
    WKRetainPtr<WKStringRef> contents = adoptWK(WKStringCreateWithQString(message));
    WKPagePostMessageToInjectedBundle(d->webPage.get(), messageName, contents.get());
}

QQmlComponent* QQuickWebViewExperimental::alertDialog() const
{
    Q_D(const QQuickWebView);
    return d->alertDialog;
}

void QQuickWebViewExperimental::setAlertDialog(QQmlComponent* alertDialog)
{
    Q_D(QQuickWebView);
    if (d->alertDialog == alertDialog)
        return;
    d->alertDialog = alertDialog;
    emit alertDialogChanged();
}

QQmlComponent* QQuickWebViewExperimental::confirmDialog() const
{
    Q_D(const QQuickWebView);
    return d->confirmDialog;
}

void QQuickWebViewExperimental::setConfirmDialog(QQmlComponent* confirmDialog)
{
    Q_D(QQuickWebView);
    if (d->confirmDialog == confirmDialog)
        return;
    d->confirmDialog = confirmDialog;
    emit confirmDialogChanged();
}

QWebNavigationHistory* QQuickWebViewExperimental::navigationHistory() const
{
    return d_ptr->navigationHistory.get();
}

QQmlComponent* QQuickWebViewExperimental::promptDialog() const
{
    Q_D(const QQuickWebView);
    return d->promptDialog;
}

QWebPreferences* QQuickWebViewExperimental::preferences() const
{
    QQuickWebViewPrivate* const d = d_ptr;
    if (!d->preferences)
        d->preferences = adoptPtr(QWebPreferencesPrivate::createPreferences(d));
    return d->preferences.get();
}

void QQuickWebViewExperimental::setPromptDialog(QQmlComponent* promptDialog)
{
    Q_D(QQuickWebView);
    if (d->promptDialog == promptDialog)
        return;
    d->promptDialog = promptDialog;
    emit promptDialogChanged();
}

QQmlComponent* QQuickWebViewExperimental::authenticationDialog() const
{
    Q_D(const QQuickWebView);
    return d->authenticationDialog;
}

void QQuickWebViewExperimental::setAuthenticationDialog(QQmlComponent* authenticationDialog)
{
    Q_D(QQuickWebView);
    if (d->authenticationDialog == authenticationDialog)
        return;
    d->authenticationDialog = authenticationDialog;
    emit authenticationDialogChanged();
}

QQmlComponent* QQuickWebViewExperimental::proxyAuthenticationDialog() const
{
    Q_D(const QQuickWebView);
    return d->proxyAuthenticationDialog;
}

void QQuickWebViewExperimental::setProxyAuthenticationDialog(QQmlComponent* proxyAuthenticationDialog)
{
    Q_D(QQuickWebView);
    if (d->proxyAuthenticationDialog == proxyAuthenticationDialog)
        return;
    d->proxyAuthenticationDialog = proxyAuthenticationDialog;
    emit proxyAuthenticationDialogChanged();
}
QQmlComponent* QQuickWebViewExperimental::certificateVerificationDialog() const
{
    Q_D(const QQuickWebView);
    return d->certificateVerificationDialog;
}

void QQuickWebViewExperimental::setCertificateVerificationDialog(QQmlComponent* certificateVerificationDialog)
{
    Q_D(QQuickWebView);
    if (d->certificateVerificationDialog == certificateVerificationDialog)
        return;
    d->certificateVerificationDialog = certificateVerificationDialog;
    emit certificateVerificationDialogChanged();
}

QQmlComponent* QQuickWebViewExperimental::itemSelector() const
{
    Q_D(const QQuickWebView);
    return d->itemSelector;
}

void QQuickWebViewExperimental::setItemSelector(QQmlComponent* itemSelector)
{
    Q_D(QQuickWebView);
    if (d->itemSelector == itemSelector)
        return;
    d->itemSelector = itemSelector;
    emit itemSelectorChanged();
}

QQmlComponent* QQuickWebViewExperimental::filePicker() const
{
    Q_D(const QQuickWebView);
    return d->filePicker;
}

void QQuickWebViewExperimental::setFilePicker(QQmlComponent* filePicker)
{
    Q_D(QQuickWebView);
    if (d->filePicker == filePicker)
        return;
    d->filePicker = filePicker;
    emit filePickerChanged();
}

QQmlComponent* QQuickWebViewExperimental::databaseQuotaDialog() const
{
    Q_D(const QQuickWebView);
    return d->databaseQuotaDialog;
}

void QQuickWebViewExperimental::setDatabaseQuotaDialog(QQmlComponent* databaseQuotaDialog)
{
    Q_D(QQuickWebView);
    if (d->databaseQuotaDialog == databaseQuotaDialog)
        return;
    d->databaseQuotaDialog = databaseQuotaDialog;
    emit databaseQuotaDialogChanged();
}

QQmlComponent* QQuickWebViewExperimental::colorChooser() const
{
    Q_D(const QQuickWebView);
    return d->colorChooser;
}

void QQuickWebViewExperimental::setColorChooser(QQmlComponent* colorChooser)
{
    Q_D(QQuickWebView);
    if (d->colorChooser == colorChooser)
        return;

    d->colorChooser = colorChooser;
    emit colorChooserChanged();
}

QString QQuickWebViewExperimental::userAgent() const
{
    Q_D(const QQuickWebView);
    WKRetainPtr<WKStringRef> ua = adoptWK(WKPageCopyCustomUserAgent(d->webPage.get()));
    return WKStringCopyQString(ua.get());
}

void QQuickWebViewExperimental::setUserAgent(const QString& userAgent)
{
    Q_D(QQuickWebView);
    WKRetainPtr<WKStringRef> newUserAgent = adoptWK(WKStringCreateWithQString(userAgent));
    WKRetainPtr<WKStringRef> currentUserAgent = adoptWK(WKPageCopyCustomUserAgent(d->webPage.get()));
    if (WKStringIsEqual(newUserAgent.get(), currentUserAgent.get()))
        return;

    WKPageSetCustomUserAgent(d->webPage.get(), newUserAgent.get());
    emit userAgentChanged();
}

/*!
    \internal

    \qmlproperty int WebViewExperimental::deviceWidth
    \brief The device width used by the viewport calculations.

    The value used when calculation the viewport, eg. what is used for 'device-width' when
    used in the viewport meta tag. If unset (zero or negative width), the width of the
    actual viewport is used instead.
*/

int QQuickWebViewExperimental::deviceWidth() const
{
    Q_D(const QQuickWebView);
    return d->webPageProxy->pageGroup()->preferences()->deviceWidth();
}

void QQuickWebViewExperimental::setDeviceWidth(int value)
{
    Q_D(QQuickWebView);
    d->webPageProxy->pageGroup()->preferences()->setDeviceWidth(qMax(0, value));
    emit deviceWidthChanged();
}

/*!
    \internal

    \qmlproperty int WebViewExperimental::deviceHeight
    \brief The device width used by the viewport calculations.

    The value used when calculation the viewport, eg. what is used for 'device-height' when
    used in the viewport meta tag. If unset (zero or negative height), the height of the
    actual viewport is used instead.
*/

int QQuickWebViewExperimental::deviceHeight() const
{
    Q_D(const QQuickWebView);
    return d->webPageProxy->pageGroup()->preferences()->deviceHeight();
}

void QQuickWebViewExperimental::setDeviceHeight(int value)
{
    Q_D(QQuickWebView);
    d->webPageProxy->pageGroup()->preferences()->setDeviceHeight(qMax(0, value));
    emit deviceHeightChanged();
}

/*!
    \internal

    \qmlmethod void WebViewExperimental::evaluateJavaScript(string script [, function(result)])

    \brief Evaluates the specified JavaScript and, if supplied, calls a function with the result.
*/

void QQuickWebViewExperimental::evaluateJavaScript(const QString& script, const QJSValue& value)
{
    JSCallbackClosure* closure = new JSCallbackClosure;

    closure->receiver = this;
    closure->value = value;

    WKRetainPtr<WKStringRef> scriptString = adoptWK(WKStringCreateWithQString(script));
    WKPageRunJavaScriptInMainFrame(d_ptr->webPage.get(), scriptString.get(), closure, javaScriptCallback);
}

void QQuickWebViewExperimental::findText(const QString& string, FindFlags options)
{
    Q_D(QQuickWebView);
    if (string.isEmpty()) {
        WKPageHideFindUI(d->webPage.get());
        return;
    }

    WKFindOptions wkOptions = kWKFindOptionsCaseInsensitive;
    if (options & FindCaseSensitively)
        wkOptions = wkOptions & ~kWKFindOptionsCaseInsensitive;
    if (options & FindBackward)
        wkOptions |= kWKFindOptionsBackwards;
    if (options & FindWrapsAroundDocument)
        wkOptions |= kWKFindOptionsWrapAround;
    if (options & FindHighlightAllOccurrences)
        wkOptions |= kWKFindOptionsShowHighlight;

    WKRetainPtr<WKStringRef> str = adoptWK(WKStringCreateWithQString(string));

    WKPageFindString(d->webPage.get(), str.get(), wkOptions, std::numeric_limits<unsigned>::max() - 1);
}

QList<QUrl> QQuickWebViewExperimental::userScripts() const
{
    Q_D(const QQuickWebView);
    return d->userScripts;
}

void QQuickWebViewExperimental::setUserScripts(const QList<QUrl>& userScripts)
{
    Q_D(QQuickWebView);
    if (d->userScripts == userScripts)
        return;
    d->userScripts = userScripts;
    d->updateUserScripts();
    emit userScriptsChanged();
}

QUrl QQuickWebViewExperimental::remoteInspectorUrl() const
{
#if ENABLE(INSPECTOR_SERVER)
    return QUrl(WebInspectorServer::shared().inspectorUrlForPageID(d_ptr->webPageProxy->inspector()->remoteInspectionPageID()));
#else
    return QUrl();
#endif
}

QQuickUrlSchemeDelegate* QQuickWebViewExperimental::schemeDelegates_At(QQmlListProperty<QQuickUrlSchemeDelegate>* property, int index)
{
    const QObjectList children = property->object->children();
    if (index < children.count())
        return static_cast<QQuickUrlSchemeDelegate*>(children.at(index));
    return 0;
}

void QQuickWebViewExperimental::schemeDelegates_Append(QQmlListProperty<QQuickUrlSchemeDelegate>* property, QQuickUrlSchemeDelegate *scheme)
{
    if (!scheme->scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive)) {
        qWarning("WARNING: The qrc scheme is reserved to be handled internally. The handler will be ignored.");
        delete scheme;
        return;
    }

    QObject* schemeParent = property->object;
    scheme->setParent(schemeParent);
    QQuickWebViewExperimental* webViewExperimental = qobject_cast<QQuickWebViewExperimental*>(property->object->parent());
    if (!webViewExperimental)
        return;
    scheme->reply()->setWebViewExperimental(webViewExperimental);
    QQuickWebViewPrivate* d = webViewExperimental->d_func();
    d->webPageProxy->registerApplicationScheme(scheme->scheme());
}

int QQuickWebViewExperimental::schemeDelegates_Count(QQmlListProperty<QQuickUrlSchemeDelegate>* property)
{
    return property->object->children().count();
}

void QQuickWebViewExperimental::schemeDelegates_Clear(QQmlListProperty<QQuickUrlSchemeDelegate>* property)
{
    const QObjectList children = property->object->children();
    for (int index = 0; index < children.count(); index++) {
        QObject* child = children.at(index);
        child->setParent(0);
        delete child;
    }
}

QQmlListProperty<QQuickUrlSchemeDelegate> QQuickWebViewExperimental::schemeDelegates()
{
    return QQmlListProperty<QQuickUrlSchemeDelegate>(schemeParent, 0,
            QQuickWebViewExperimental::schemeDelegates_Append,
            QQuickWebViewExperimental::schemeDelegates_Count,
            QQuickWebViewExperimental::schemeDelegates_At,
            QQuickWebViewExperimental::schemeDelegates_Clear);
}

void QQuickWebViewExperimental::invokeApplicationSchemeHandler(PassRefPtr<QtRefCountedNetworkRequestData> request)
{
    RefPtr<QtRefCountedNetworkRequestData> req = request;
    if (req->data().m_scheme.startsWith("qrc", false)) {
        QQuickQrcSchemeDelegate qrcDelegate(QUrl(QString(req->data().m_urlString)));
        qrcDelegate.request()->setNetworkRequestData(req);
        qrcDelegate.reply()->setNetworkRequestData(req);
        qrcDelegate.reply()->setWebViewExperimental(this);
        qrcDelegate.readResourceAndSend();
        return;
    }

    const QObjectList children = schemeParent->children();
    for (int index = 0; index < children.count(); index++) {
        QQuickUrlSchemeDelegate* delegate = qobject_cast<QQuickUrlSchemeDelegate*>(children.at(index));
        if (!delegate)
            continue;
        if (!delegate->scheme().compare(QString(req->data().m_scheme), Qt::CaseInsensitive)) {
            delegate->request()->setNetworkRequestData(req);
            delegate->reply()->setNetworkRequestData(req);
            emit delegate->receivedRequest();
            return;
        }
    }
}

void QQuickWebViewExperimental::sendApplicationSchemeReply(QQuickNetworkReply* reply)
{
    d_ptr->webPageProxy->sendApplicationSchemeReply(reply);
}

void QQuickWebViewExperimental::goForwardTo(int index)
{
    d_ptr->navigationHistory->d->goForwardTo(index);
}

void QQuickWebViewExperimental::goBackTo(int index)
{
    d_ptr->navigationHistory->d->goBackTo(index);
}

QWebKitTest* QQuickWebViewExperimental::test()
{
    return m_test;
}

QQuickWebPage* QQuickWebViewExperimental::page()
{
    return q_ptr->page();
}

/*!
    \page index.html
    \title QtWebKit: QML WebView version 3.0

    The WebView API allows QML applications to render regions of dynamic
    web content. A \e{WebView} component may share the screen with other
    QML components or encompass the full screen as specified within the
    QML application.

    QML WebView version 3.0 is incompatible with previous QML \l
    {QtWebKit1::WebView} {WebView} API versions.  It allows an
    application to load pages into the WebView, either by URL or with
    an HTML string, and navigate within session history.  By default,
    links to different pages load within the same WebView, but applications
    may intercept requests to delegate links to other functions.

    This sample QML application loads a web page, responds to session
    history context, and intercepts requests for external links:

    \code
    import QtQuick 2.0
    import QtWebKit 3.0

    Page {
        WebView {
            id: webview
            url: "http://qt-project.org"
            width: parent.width
            height: parent.height
            onNavigationRequested: {
                // detect URL scheme prefix, most likely an external link
                var schemaRE = /^\w+:/;
                if (schemaRE.test(request.url)) {
                    request.action = WebView.AcceptRequest;
                } else {
                    request.action = WebView.IgnoreRequest;
                    // delegate request.url here
                }
            }
        }
    }
    \endcode

    \section1 Examples

    There are several Qt WebKit examples located in the
    \l{Qt WebKit Examples} page.

*/


/*!
    \qmltype WebView
    \instantiates QQuickWebView
    \inqmlmodule QtWebKit 3.0
    \brief A WebView renders web content within a QML application
*/

QQuickWebView::QQuickWebView(QQuickItem* parent)
    : QQuickFlickable(parent)
    , d_ptr(createPrivateObject(this))
{
    Q_D(QQuickWebView);
    d->initialize();
}

QQuickWebView::QQuickWebView(WKContextRef contextRef, WKPageGroupRef pageGroupRef, QQuickItem* parent)
    : QQuickFlickable(parent)
    , d_ptr(createPrivateObject(this))
{
    Q_D(QQuickWebView);
    d->initialize(contextRef, pageGroupRef);
}

QQuickWebView::~QQuickWebView()
{
}

QQuickWebPage* QQuickWebView::page()
{
    Q_D(QQuickWebView);
    return d->pageView.data();
}

/*!
    \qmlmethod void WebView::goBack()

    Go backward within the browser's session history, if possible.
    (Equivalent to the \c{window.history.back()} DOM method.)

    \sa WebView::canGoBack
*/
void QQuickWebView::goBack()
{
    Q_D(QQuickWebView);
    WKPageGoBack(d->webPage.get());
}

/*!
    \qmlmethod void WebView::goForward()

    Go forward within the browser's session history, if possible.
    (Equivalent to the \c{window.history.forward()} DOM method.)
*/
void QQuickWebView::goForward()
{
    Q_D(QQuickWebView);
    WKPageGoForward(d->webPage.get());
}

/*!
    \qmlmethod void WebView::stop()

    Stop loading the current page.
*/
void QQuickWebView::stop()
{
    Q_D(QQuickWebView);
    WKPageStopLoading(d->webPage.get());
}

/*!
    \qmlmethod void WebView::reload()

    Reload the current page. (Equivalent to the
    \c{window.location.reload()} DOM method.)
*/
void QQuickWebView::reload()
{
    Q_D(QQuickWebView);

    WebFrameProxy* mainFrame = d->webPageProxy->mainFrame();
    if (mainFrame && !mainFrame->unreachableURL().isEmpty() && mainFrame->url() != blankURL()) {
        // We are aware of the unreachable url on the UI process side, but since we haven't
        // loaded alternative/subsitute data for it (an error page eg.) WebCore doesn't know
        // about the unreachable url yet. If we just do a reload at this point WebCore will try to
        // reload the currently committed url instead of the unrachable url. To work around this
        // we override the reload here by doing a manual load.
        d->webPageProxy->loadURL(mainFrame->unreachableURL());
        // FIXME: We should make WebCore aware of the unreachable url regardless of substitute-loads
        return;
    }

    WKPageReloadFromOrigin(d->webPage.get());
}

/*!
    \qmlproperty url WebView::url

    The location of the currently displaying HTML page. This writable
    property offers the main interface to load a page into a web view.
    It functions the same as the \c{window.location} DOM property.

    \sa WebView::loadHtml()
*/
QUrl QQuickWebView::url() const
{
    Q_D(const QQuickWebView);

    // FIXME: Enable once we are sure this should not trigger
    // Q_ASSERT(d->m_currentUrl == d->webPageProxy->activeURL());

    return QUrl(d->m_currentUrl);
}

void QQuickWebView::setUrl(const QUrl& url)
{
    Q_D(QQuickWebView);

    if (url.isEmpty())
        return;

    WKRetainPtr<WKURLRef> u = adoptWK(WKURLCreateWithQUrl(url));
    WKPageLoadURL(d->webPage.get(), u.get());
    emitUrlChangeIfNeeded();
}

// Make sure we don't emit urlChanged unless it actually changed
void QQuickWebView::emitUrlChangeIfNeeded()
{
    Q_D(QQuickWebView);

    QString activeUrl = d->webPageProxy->activeURL();
    if (activeUrl != d->m_currentUrl) {
        d->m_currentUrl = activeUrl;
        emit urlChanged();
    }
}

/*!
    \qmlproperty url WebView::icon

    The location of the currently displaying Web site icon, also known as favicon
    or shortcut icon. This read-only URL corresponds to the image used within a
    mobile browser application to represent a bookmarked page on the device's home
    screen.

    This example uses the \c{icon} property to build an \c{Image} element:

    \code
    Image {
        id: appIcon
        source: webView.icon != "" ? webView.icon : "fallbackFavIcon.png";
        ...
    }
    \endcode
*/
QUrl QQuickWebView::icon() const
{
    Q_D(const QQuickWebView);
    return d->m_iconUrl;
}

/*!
    \qmlproperty int WebView::loadProgress

    The amount of the page that has been loaded, expressed as an integer
    percentage in the range from \c{0} to \c{100}.
*/
int QQuickWebView::loadProgress() const
{
    Q_D(const QQuickWebView);
    return d->loadProgress();
}

/*!
    \qmlproperty bool WebView::canGoBack

    Returns \c{true} if there are prior session history entries, \c{false}
    otherwise.
*/
bool QQuickWebView::canGoBack() const
{
    Q_D(const QQuickWebView);
    return WKPageCanGoBack(d->webPage.get());
}

/*!
    \qmlproperty bool WebView::canGoForward

    Returns \c{true} if there are subsequent session history entries,
    \c{false} otherwise.
*/
bool QQuickWebView::canGoForward() const
{
    Q_D(const QQuickWebView);
    return WKPageCanGoForward(d->webPage.get());
}

/*!
    \qmlproperty bool WebView::loading

    Returns \c{true} if the HTML page is currently loading, \c{false} otherwise.
*/
bool QQuickWebView::loading() const
{
    Q_D(const QQuickWebView);
    WKFrameRef mainFrame = WKPageGetMainFrame(d->webPage.get());
    return mainFrame && !(kWKFrameLoadStateFinished == WKFrameGetFrameLoadState(mainFrame));
}

/*!
    \internal
 */

QPointF QQuickWebView::mapToWebContent(const QPointF& pointInViewCoordinates) const
{
    Q_D(const QQuickWebView);
    return d->pageView->transformFromItem().map(pointInViewCoordinates);
}

/*!
    \internal
 */

QRectF QQuickWebView::mapRectToWebContent(const QRectF& rectInViewCoordinates) const
{
    Q_D(const QQuickWebView);
    return d->pageView->transformFromItem().mapRect(rectInViewCoordinates);
}

/*!
    \internal
 */

QPointF QQuickWebView::mapFromWebContent(const QPointF& pointInCSSCoordinates) const
{
    Q_D(const QQuickWebView);
    return d->pageView->transformToItem().map(pointInCSSCoordinates);
}

/*!
    \internal
 */
QRectF QQuickWebView::mapRectFromWebContent(const QRectF& rectInCSSCoordinates) const
{
    Q_D(const QQuickWebView);
    return d->pageView->transformToItem().mapRect(rectInCSSCoordinates);
}

/*!
    \qmlproperty string WebView::title

    The title of the currently displaying HTML page, a read-only value
    that reflects the contents of the \c{<title>} tag.
*/
QString QQuickWebView::title() const
{
    Q_D(const QQuickWebView);
    WKRetainPtr<WKStringRef> t = adoptWK(WKPageCopyTitle(d->webPage.get()));
    return WKStringCopyQString(t.get());
}

QVariant QQuickWebView::inputMethodQuery(Qt::InputMethodQuery property) const
{
    Q_D(const QQuickWebView);
    const EditorState& state = d->webPageProxy->editorState();

    switch(property) {
    case Qt::ImCursorRectangle:
        return QRectF(state.cursorRect);
    case Qt::ImFont:
        return QVariant();
    case Qt::ImCursorPosition:
        return QVariant(static_cast<int>(state.cursorPosition));
    case Qt::ImAnchorPosition:
        return QVariant(static_cast<int>(state.anchorPosition));
    case Qt::ImSurroundingText:
        return QString(state.surroundingText);
    case Qt::ImCurrentSelection:
        return QString(state.selectedText);
    case Qt::ImMaximumTextLength:
        return QVariant(); // No limit.
    case Qt::ImHints:
        return int(Qt::InputMethodHints(state.inputMethodHints));
    default:
        // Rely on the base implementation for ImEnabled, ImHints and ImPreferredLanguage.
        return QQuickFlickable::inputMethodQuery(property);
    }
}

/*!
    internal

    The experimental module consisting on experimental API which will break
    from version to version.
*/
QQuickWebViewExperimental* QQuickWebView::experimental() const
{
    Q_D(const QQuickWebView);
    return d->experimental;
}

/*!
    \internal
*/
void QQuickWebView::platformInitialize()
{
    JSC::initializeThreading();
    WTF::initializeMainThread();
}

bool QQuickWebView::childMouseEventFilter(QQuickItem* item, QEvent* event)
{
    if (!isVisible() || !isEnabled())
        return false;

    // This function is used by MultiPointTouchArea and PinchArea to filter
    // touch events, thus to hinder the canvas from sending synthesized
    // mouse events to the Flickable implementation we need to reimplement
    // childMouseEventFilter to ignore touch and mouse events.

    switch (event->type()) {
    case QEvent::MouseButtonPress:
    case QEvent::MouseMove:
    case QEvent::MouseButtonRelease:
    case QEvent::TouchBegin:
    case QEvent::TouchUpdate:
    case QEvent::TouchEnd:
        // Force all mouse and touch events through the default propagation path.
        return false;
    default:
        ASSERT(event->type() == QEvent::UngrabMouse);
        break;
    }

    return QQuickFlickable::childMouseEventFilter(item, event);
}

void QQuickWebView::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry)
{
    Q_D(QQuickWebView);
    QQuickFlickable::geometryChanged(newGeometry, oldGeometry);
    if (newGeometry.size() != oldGeometry.size())
        d->updateViewportSize();
}

void QQuickWebView::componentComplete()
{
    Q_D(QQuickWebView);
    QQuickFlickable::componentComplete();

    d->onComponentComplete();
    d->updateViewportSize();
}

void QQuickWebView::keyPressEvent(QKeyEvent* event)
{
    Q_D(QQuickWebView);
    d->pageEventHandler->handleKeyPressEvent(event);
}

void QQuickWebView::keyReleaseEvent(QKeyEvent* event)
{
    Q_D(QQuickWebView);
    d->pageEventHandler->handleKeyReleaseEvent(event);
}

void QQuickWebView::inputMethodEvent(QInputMethodEvent* event)
{
    Q_D(QQuickWebView);
    d->pageEventHandler->handleInputMethodEvent(event);
}

void QQuickWebView::focusInEvent(QFocusEvent* event)
{
    Q_D(QQuickWebView);
    d->pageEventHandler->handleFocusInEvent(event);
}

void QQuickWebView::itemChange(ItemChange change, const ItemChangeData &value)
{
    Q_D(QQuickWebView);
    if (change == ItemActiveFocusHasChanged) {
        bool focus = value.boolValue;
        if (!focus)
            d->pageEventHandler->handleFocusLost();
    }
    QQuickFlickable::itemChange(change, value);
}

void QQuickWebView::touchEvent(QTouchEvent* event)
{
    Q_D(QQuickWebView);

    bool lockingDisabled = flickableDirection() != AutoFlickDirection
                           || event->touchPoints().size() != 1
                           || width() >= contentWidth()
                           || height() >= contentHeight();

    if (!lockingDisabled)
        d->axisLocker.update(event);
    else
        d->axisLocker.reset();

    forceActiveFocus();
    d->pageEventHandler->handleTouchEvent(event);
}

void QQuickWebView::mousePressEvent(QMouseEvent* event)
{
    Q_D(QQuickWebView);
    forceActiveFocus();
    d->handleMouseEvent(event);
}

void QQuickWebView::mouseMoveEvent(QMouseEvent* event)
{
    Q_D(QQuickWebView);
    d->handleMouseEvent(event);
}

void QQuickWebView::mouseReleaseEvent(QMouseEvent* event)
{
    Q_D(QQuickWebView);
    d->handleMouseEvent(event);
}

void QQuickWebView::mouseDoubleClickEvent(QMouseEvent* event)
{
    Q_D(QQuickWebView);
    forceActiveFocus();
    d->handleMouseEvent(event);
}

void QQuickWebView::wheelEvent(QWheelEvent* event)
{
    Q_D(QQuickWebView);
    d->pageEventHandler->handleWheelEvent(event);
}

void QQuickWebView::hoverEnterEvent(QHoverEvent* event)
{
    Q_D(QQuickWebView);
    // Map HoverEnter to Move, for WebKit the distinction doesn't matter.
    d->pageEventHandler->handleHoverMoveEvent(event);
}

void QQuickWebView::hoverMoveEvent(QHoverEvent* event)
{
    Q_D(QQuickWebView);
    d->pageEventHandler->handleHoverMoveEvent(event);
}

void QQuickWebView::hoverLeaveEvent(QHoverEvent* event)
{
    Q_D(QQuickWebView);
    d->pageEventHandler->handleHoverLeaveEvent(event);
}

void QQuickWebView::dragMoveEvent(QDragMoveEvent* event)
{
    Q_D(QQuickWebView);
    d->pageEventHandler->handleDragMoveEvent(event);
}

void QQuickWebView::dragEnterEvent(QDragEnterEvent* event)
{
    Q_D(QQuickWebView);
    d->pageEventHandler->handleDragEnterEvent(event);
}

void QQuickWebView::dragLeaveEvent(QDragLeaveEvent* event)
{
    Q_D(QQuickWebView);
    d->pageEventHandler->handleDragLeaveEvent(event);
}

void QQuickWebView::dropEvent(QDropEvent* event)
{
    Q_D(QQuickWebView);
    d->pageEventHandler->handleDropEvent(event);
}

bool QQuickWebView::event(QEvent* ev)
{
    // Re-implemented for possible future use without breaking binary compatibility.
    return QQuickFlickable::event(ev);
}

WKPageRef QQuickWebView::pageRef() const
{
    Q_D(const QQuickWebView);
    return d->webPage.get();
}

QPointF QQuickWebView::contentPos() const
{
    Q_D(const QQuickWebView);
    return d->contentPos();
}

void QQuickWebView::setContentPos(const QPointF& pos)
{
    Q_D(QQuickWebView);

    if (pos == contentPos())
        return;

    d->setContentPos(pos);
}

void QQuickWebView::handleFlickableMousePress(const QPointF& position, qint64 eventTimestampMillis)
{
    Q_D(QQuickWebView);
    d->axisLocker.setReferencePosition(position);
    QMouseEvent mouseEvent(QEvent::MouseButtonPress, position, Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
    mouseEvent.setTimestamp(eventTimestampMillis);
    QQuickFlickable::mousePressEvent(&mouseEvent);
}

void QQuickWebView::handleFlickableMouseMove(const QPointF& position, qint64 eventTimestampMillis)
{
    Q_D(QQuickWebView);
    QMouseEvent mouseEvent(QEvent::MouseMove, d->axisLocker.adjust(position), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
    mouseEvent.setTimestamp(eventTimestampMillis);
    QQuickFlickable::mouseMoveEvent(&mouseEvent);
}

void QQuickWebView::handleFlickableMouseRelease(const QPointF& position, qint64 eventTimestampMillis)
{
    Q_D(QQuickWebView);
    QMouseEvent mouseEvent(QEvent::MouseButtonRelease, d->axisLocker.adjust(position), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
    d->axisLocker.reset();
    mouseEvent.setTimestamp(eventTimestampMillis);
    QQuickFlickable::mouseReleaseEvent(&mouseEvent);
}

/*!
    \qmlmethod void WebView::loadHtml(string html, url baseUrl, url unreachableUrl)
    \brief Loads the specified \a html as the content of the web view.

    (This method offers a lower-level alternative to the \c{url} property,
    which references HTML pages via URL.)

    External objects such as stylesheets or images referenced in the HTML
    document are located relative to \a baseUrl. For example if provided \a html
    was originally retrieved from \c http://www.example.com/documents/overview.html
    and that was the base url, then an image referenced with the relative url \c diagram.png
    would be looked for at \c{http://www.example.com/documents/diagram.png}.

    If an \a unreachableUrl is passed it is used as the url for the loaded
    content. This is typically used to display error pages for a failed
    load.

    \sa WebView::url
*/
void QQuickWebView::loadHtml(const QString& html, const QUrl& baseUrl, const QUrl& unreachableUrl)
{
    Q_D(QQuickWebView);
    WKRetainPtr<WKStringRef> htmlRef = adoptWK(WKStringCreateWithQString(html));
    WKRetainPtr<WKURLRef> baseUrlRef = adoptWK(WKURLCreateWithQUrl(baseUrl));
    WKRetainPtr<WKURLRef> unreachableUrlRef = adoptWK(WKURLCreateWithQUrl(unreachableUrl));

    if (unreachableUrl.isValid())
        WKPageLoadAlternateHTMLString(d->webPage.get(), htmlRef.get(), baseUrlRef.get(), unreachableUrlRef.get());
    else
        WKPageLoadHTMLString(d->webPage.get(), htmlRef.get(), baseUrlRef.get());
}

qreal QQuickWebView::zoomFactor() const
{
    Q_D(const QQuickWebView);
    return d->zoomFactor();
}

void QQuickWebView::setZoomFactor(qreal factor)
{

    Q_D(QQuickWebView);
    d->setZoomFactor(factor);
}

void QQuickWebView::runJavaScriptInMainFrame(const QString &script, QObject *receiver, const char *method)
{
    Q_D(QQuickWebView);

    JSCallbackClosure* closure = new JSCallbackClosure;
    closure->receiver = receiver;
    closure->method = method;

    WKRetainPtr<WKStringRef> scriptString = adoptWK(WKStringCreateWithQString(script));
    WKPageRunJavaScriptInMainFrame(d->webPage.get(), scriptString.get(), closure, javaScriptCallback);
}

bool QQuickWebView::allowAnyHTTPSCertificateForLocalHost() const
{
    Q_D(const QQuickWebView);
    return d->m_allowAnyHTTPSCertificateForLocalHost;
}

void QQuickWebView::setAllowAnyHTTPSCertificateForLocalHost(bool allow)
{
    Q_D(QQuickWebView);
    d->m_allowAnyHTTPSCertificateForLocalHost = allow;
}

void QQuickWebViewPrivate::didFindString(WKPageRef, WKStringRef, unsigned matchCount, const void* clientInfo)
{
    QQuickWebView* q = toQQuickWebViewPrivate(clientInfo)->q_ptr;
    emit q->experimental()->textFound(matchCount);
}

void QQuickWebViewPrivate::didFailToFindString(WKPageRef page, WKStringRef string, const void* clientInfo)
{
    QQuickWebViewPrivate::didFindString(page, string, 0, clientInfo);
}

/*!
    \qmlsignal WebView::onLoadingChanged(loadRequest)

    Occurs when any page load begins, ends, or fails. Various read-only
    parameters are available on the \a loadRequest:

    \list

    \li \c{url}: the location of the resource that is loading.

    \li \c{status}: Reflects one of three load states:
       \c{LoadStartedStatus}, \c{LoadSucceededStatus}, or
       \c{LoadFailedStatus}. See \c{WebView::LoadStatus}.

    \li \c{errorString}: description of load error.

    \li \c{errorCode}: HTTP error code.

    \li \c{errorDomain}: high-level error types, one of
    \c{NetworkErrorDomain}, \c{HttpErrorDomain}, \c{InternalErrorDomain},
    \c{DownloadErrorDomain}, or \c{NoErrorDomain}.  See
    \l{WebView::ErrorDomain}.

    \endlist

    \sa WebView::loading
*/

/*!
    \qmlsignal WebView::onLinkHovered(hoveredUrl, hoveredTitle)

    Within a mouse-driven interface, this signal is emitted when a mouse
    pointer passes over a link, corresponding to the \c{mouseover} DOM
    event.  (May also occur in touch interfaces for \c{mouseover} events
    that are not cancelled with \c{preventDefault()}.)  The \a{hoveredUrl}
    provides the link's location, and the \a{hoveredTitle} is any avalable
    link text.
*/

/*!
    \qmlsignal WebView::onNavigationRequested(request)

    Occurs for various kinds of navigation.  If the application listens
    for this signal, it must set the \c{request.action} to either of the
    following \l{WebView::NavigationRequestAction} enum values:

    \list

    \li \c{AcceptRequest}: Allow navigation to external pages within the
    web view. This represents the default behavior when no listener is
    active.

    \li \c{IgnoreRequest}: Suppress navigation to new pages within the web
    view.  (The listener may then delegate navigation externally to
    the browser application.)

    \endlist

    The \a{request} also provides the following read-only values:

    \list

    \li \c{url}: The location of the requested page.

    \li \c{navigationType}: contextual information, one of
    \c{LinkClickedNavigation}, \c{BackForwardNavigation},
    \c{ReloadNavigation}, \c{FormSubmittedNavigation},
    \c{FormResubmittedNavigation}, or \c{OtherNavigation} enum values.
    See \l{WebView::NavigationType}.

    \li \c{keyboardModifiers}: potential states for \l{Qt::KeyboardModifier}.

    \li \c{mouseButton}: potential states for \l{Qt::MouseButton}.

    \endlist
*/

/*!
    \qmlproperty enumeration WebView::ErrorDomain

    Details various high-level error types.

    \table

    \header
    \li Constant
    \li Description

    \row
    \li InternalErrorDomain
    \li Content fails to be interpreted by Qt WebKit.

    \row
    \li NetworkErrorDomain
    \li Error results from faulty network connection.

    \row
    \li HttpErrorDomain
    \li Error is produced by server.

    \row
    \li DownloadErrorDomain
    \li Error in saving file.

    \row
    \li NoErrorDomain
    \li Unspecified fallback error.

    \endtable
*/

/*!
    \qmlproperty enumeration WebView::NavigationType

    Distinguishes context for various navigation actions.

    \table

    \header
    \li Constant
    \li Description

    \row
    \li LinkClickedNavigation
    \li Navigation via link.

    \row
    \li FormSubmittedNavigation
    \li Form data is posted.

    \row
    \li BackForwardNavigation
    \li Navigation back and forth within session history.

    \row
    \li ReloadNavigation
    \li The current page is reloaded.

    \row
    \li FormResubmittedNavigation
    \li Form data is re-posted.

    \row
    \li OtherNavigation
    \li Unspecified fallback method of navigation.

    \endtable
*/

/*!
    \qmlproperty enumeration WebView::LoadStatus

    Reflects a page's load status.

    \table

    \header
    \li Constant
    \li Description

    \row
    \li LoadStartedStatus
    \li Page is currently loading.

    \row
    \li LoadSucceededStatus
    \li Page has successfully loaded, and is not currently loading.

    \row
    \li LoadFailedStatus
    \li Page has failed to load, and is not currently loading.

    \endtable
*/

/*!
    \qmlproperty enumeration WebView::NavigationRequestAction

    Specifies a policy when navigating a link to an external page.

    \table

    \header
    \li Constant
    \li Description

    \row
    \li AcceptRequest
    \li Allow navigation to external pages within the web view.

    \row
    \li IgnoreRequest
    \li Suppress navigation to new pages within the web view.

    \endtable
*/

#include "moc_qquickwebview_p.cpp"
