summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp')
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp479
1 files changed, 326 insertions, 153 deletions
diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp
index 2806ce5d5..ab3045834 100644
--- a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp
+++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp
@@ -1,5 +1,7 @@
/*
* 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
@@ -21,6 +23,7 @@
#include "config.h"
#include "qquickwebview_p.h"
+#include "CoordinatedLayerTreeHostProxy.h"
#include "DownloadProxy.h"
#include "DrawingAreaProxyImpl.h"
#include "PageViewportControllerClientQt.h"
@@ -30,9 +33,10 @@
#include "QtWebError.h"
#include "QtWebIconDatabaseClient.h"
#include "QtWebPageEventHandler.h"
-#include "QtWebPageLoadClient.h"
#include "QtWebPagePolicyClient.h"
#include "WebBackForwardList.h"
+#include "WebContext.h"
+#include "WebFindOptions.h"
#if ENABLE(INSPECTOR_SERVER)
#include "WebInspectorProxy.h"
#include "WebInspectorServer.h"
@@ -42,6 +46,7 @@
#endif
#include "WebPageGroup.h"
#include "WebPreferences.h"
+#include "qglobal.h"
#include "qquicknetworkreply_p.h"
#include "qquicknetworkrequest_p.h"
#include "qquickwebpage_p_p.h"
@@ -58,13 +63,22 @@
#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>
@@ -78,6 +92,15 @@ 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;
@@ -184,6 +207,11 @@ static QQuickWebViewPrivate* createPrivateObject(QQuickWebView* 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)
@@ -259,6 +287,7 @@ QPointF QQuickWebViewPrivate::FlickableAxisLocker::adjust(const QPointF& positio
QQuickWebViewPrivate::QQuickWebViewPrivate(QQuickWebView* viewport)
: q_ptr(viewport)
, experimental(new QQuickWebViewExperimental(viewport, this))
+ , context(0)
, alertDialog(0)
, confirmDialog(0)
, promptDialog(0)
@@ -286,42 +315,78 @@ QQuickWebViewPrivate::QQuickWebViewPrivate(QQuickWebView* 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)
{
- RefPtr<WebPageGroup> pageGroup;
- if (pageGroupRef)
- pageGroup = toImpl(pageGroupRef);
- else
- pageGroup = WebPageGroup::create();
+ 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);
- context = contextRef ? QtWebContext::create(toImpl(contextRef)) : QtWebContext::defaultContext();
- webPageProxy = context->createWebPage(&pageClient, pageGroup.get());
webPageProxy->setUseFixedLayout(s_flickableViewportEnabled);
#if ENABLE(FULLSCREEN_API)
webPageProxy->fullScreenManager()->setWebView(q_ptr);
#endif
- QQuickWebPagePrivate* const pageViewPrivate = pageView.data()->d;
- pageViewPrivate->initialize(webPageProxy.get());
+ 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;
+ loadClient.processDidBecomeUnresponsive = processDidBecomeUnresponsive;
+ loadClient.processDidBecomeResponsive = processDidBecomeResponsive;
+ WKPageSetPageLoaderClient(webPage.get(), &loadClient);
+ }
- pageLoadClient.reset(new QtWebPageLoadClient(toAPI(webPageProxy.get()), q_ptr));
- pagePolicyClient.reset(new QtWebPagePolicyClient(toAPI(webPageProxy.get()), q_ptr));
- pageUIClient.reset(new QtWebPageUIClient(toAPI(webPageProxy.get()), q_ptr));
- navigationHistory = adoptPtr(QWebNavigationHistoryPrivate::createHistory(toAPI(webPageProxy.get())));
+ 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.
- webPageProxy->pageGroup()->preferences()->setAcceleratedCompositingEnabled(true);
+ 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);
- webPageProxy->pageGroup()->preferences()->setFrameFlatteningEnabled(true);
- webPageProxy->pageGroup()->preferences()->setWebGLEnabled(true);
- pageClient.initialize(q_ptr, pageViewPrivate->eventHandler.data(), &undoController);
+ pageClient.initialize(q_ptr, pageEventHandler.data(), &undoController);
webPageProxy->initializeWebPage();
webPageProxy->registerApplicationScheme(ASCIILiteral("qrc"));
@@ -330,109 +395,160 @@ void QQuickWebViewPrivate::initialize(WKContextRef contextRef, WKPageGroupRef pa
q_ptr->setFlag(QQuickItem::ItemAcceptsDrops, true);
}
-void QQuickWebViewPrivate::loadDidStop()
+void QQuickWebViewPrivate::didStartProvisionalLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef, const void* clientInfo)
{
- Q_Q(QQuickWebView);
- ASSERT(!q->loading());
- QWebLoadRequest loadRequest(q->url(), QQuickWebView::LoadStoppedStatus);
+ 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::setTransparentBackground(bool enable)
+void QQuickWebViewPrivate::didReceiveServerRedirectForProvisionalLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef, const void* clientInfo)
{
- webPageProxy->setDrawsTransparentBackground(enable);
-}
+ if (!WKFrameIsMainFrame(frame))
+ return;
-bool QQuickWebViewPrivate::transparentBackground() const
-{
- return webPageProxy->drawsTransparentBackground();
+ toQQuickWebViewPrivate(clientInfo)->q_func()->emitUrlChangeIfNeeded();
}
-void QQuickWebViewPrivate::provisionalLoadDidStart(const WTF::String& url)
+void QQuickWebViewPrivate::didFailLoad(WKPageRef, WKFrameRef frame, WKErrorRef errorRef, WKTypeRef, const void* clientInfo)
{
- Q_Q(QQuickWebView);
+ if (!WKFrameIsMainFrame(frame))
+ return;
- q->emitUrlChangeIfNeeded();
+ QQuickWebView* const q = toQQuickWebViewPrivate(clientInfo)->q_func();
+ ASSERT(!q->loading());
- QWebLoadRequest loadRequest(QString(url), QQuickWebView::LoadStartedStatus);
- emit q->loadingChanged(&loadRequest);
-}
+ QtWebError error(errorRef);
+ if (error.isCancellation()) {
+ QWebLoadRequest loadRequest(q->url(), QQuickWebView::LoadStoppedStatus);
+ emit q->loadingChanged(&loadRequest);
+ return;
+ }
-void QQuickWebViewPrivate::didReceiveServerRedirectForProvisionalLoad(const WTF::String&)
-{
- Q_Q(QQuickWebView);
+ 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::loadDidCommit()
+void QQuickWebViewPrivate::didCommitLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef, const void* clientInfo)
{
- Q_Q(QQuickWebView);
- ASSERT(q->loading());
+ if (!WKFrameIsMainFrame(frame))
+ return;
+ QQuickWebViewPrivate* d = toQQuickWebViewPrivate(clientInfo);
+
+ PageViewportController* pageViewportController = d->viewportController();
+ if (pageViewportController)
+ pageViewportController->didCommitLoad();
- m_betweenLoadCommitAndFirstFrame = true;
+ QQuickWebView* const q = d->q_func();
+ ASSERT(q->loading());
+ d->m_betweenLoadCommitAndFirstFrame = true;
emit q->navigationHistoryChanged();
emit q->titleChanged();
}
-void QQuickWebViewPrivate::didSameDocumentNavigation()
+void QQuickWebViewPrivate::didFinishLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef, const void* clientInfo)
{
- Q_Q(QQuickWebView);
+ 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::titleDidChange()
+void QQuickWebViewPrivate::didReceiveTitleForFrame(WKPageRef, WKStringRef title, WKFrameRef frame, WKTypeRef, const void* clientInfo)
{
- Q_Q(QQuickWebView);
-
- emit q->titleChanged();
+ if (!WKFrameIsMainFrame(frame))
+ return;
+ emit toQQuickWebViewPrivate(clientInfo)->q_func()->titleChanged();
}
-void QQuickWebViewPrivate::loadProgressDidChange(int loadProgress)
+void QQuickWebViewPrivate::didStartProgress(WKPageRef, const void* clientInfo)
{
- Q_Q(QQuickWebView);
+ toQQuickWebViewPrivate(clientInfo)->loadProgressDidChange(0);
+}
- m_loadProgress = loadProgress;
+void QQuickWebViewPrivate::didChangeProgress(WKPageRef page, const void* clientInfo)
+{
+ toQQuickWebViewPrivate(clientInfo)->loadProgressDidChange(WKPageGetEstimatedProgress(page) * 100);
+}
- emit q->loadProgressChanged();
+void QQuickWebViewPrivate::didFinishProgress(WKPageRef, const void* clientInfo)
+{
+ toQQuickWebViewPrivate(clientInfo)->loadProgressDidChange(100);
}
-void QQuickWebViewPrivate::backForwardListDidChange()
+void QQuickWebViewPrivate::didChangeBackForwardList(WKPageRef, WKBackForwardListItemRef, WKArrayRef, const void *clientInfo)
{
- navigationHistory->d->reset();
+ toQQuickWebViewPrivate(clientInfo)->navigationHistory->d->reset();
}
-void QQuickWebViewPrivate::loadDidSucceed()
+void QQuickWebViewPrivate::setTransparentBackground(bool enable)
{
- Q_Q(QQuickWebView);
- ASSERT(!q->loading());
+ webPageProxy->setDrawsTransparentBackground(enable);
+}
- QWebLoadRequest loadRequest(q->url(), QQuickWebView::LoadSucceededStatus);
- emit q->loadingChanged(&loadRequest);
+bool QQuickWebViewPrivate::transparentBackground() const
+{
+ return webPageProxy->drawsTransparentBackground();
}
-void QQuickWebViewPrivate::loadDidFail(const QtWebError& error)
+void QQuickWebViewPrivate::loadProgressDidChange(int loadProgress)
{
Q_Q(QQuickWebView);
- ASSERT(!q->loading());
- QWebLoadRequest loadRequest(error.url(), QQuickWebView::LoadFailedStatus, error.description(), static_cast<QQuickWebView::ErrorDomain>(error.type()), error.errorCode());
- emit q->loadingChanged(&loadRequest);
+ m_loadProgress = loadProgress;
+
+ emit q->loadProgressChanged();
}
void QQuickWebViewPrivate::handleMouseEvent(QMouseEvent* event)
{
switch (event->type()) {
case QEvent::MouseButtonPress:
- pageView->eventHandler()->handleMousePressEvent(event);
+ pageEventHandler->handleMousePressEvent(event);
break;
case QEvent::MouseMove:
- pageView->eventHandler()->handleMouseMoveEvent(event);
+ pageEventHandler->handleMouseMoveEvent(event);
break;
case QEvent::MouseButtonRelease:
- pageView->eventHandler()->handleMouseReleaseEvent(event);
+ pageEventHandler->handleMouseReleaseEvent(event);
break;
case QEvent::MouseButtonDblClick:
// If a MouseButtonDblClick was received then we got a MouseButtonPress before.
@@ -475,7 +591,7 @@ void QQuickWebViewPrivate::processDidCrash()
QUrl url(KURL(WebCore::ParsedURLString, webPageProxy->urlAtProcessExit()));
qWarning("WARNING: The web process experienced a crash on '%s'.", qPrintable(url.toString(QUrl::RemoveUserInfo)));
- pageView->eventHandler()->resetGestureRecognizers();
+ pageEventHandler->resetGestureRecognizers();
// Check if loading was ongoing, when process crashed.
if (m_loadProgress > 0 && m_loadProgress < 100) {
@@ -494,29 +610,27 @@ void QQuickWebViewPrivate::didRelaunchProcess()
qWarning("WARNING: The web process has been successfully restarted.");
- webPageProxy->drawingArea()->setSize(viewSize(), IntSize());
+ if (DrawingAreaProxy *drawingArea = webPageProxy->drawingArea()) {
+ drawingArea->setSize(viewSize(), IntSize(), IntSize());
- updateViewportSize();
- updateUserScripts();
- updateSchemeDelegates();
+ updateViewportSize();
+ updateUserScripts();
+ updateSchemeDelegates();
+ }
emit q->experimental()->didRelaunchProcess();
}
-void QQuickWebViewPrivate::processDidBecomeUnresponsive()
+void QQuickWebViewPrivate::processDidBecomeUnresponsive(WKPageRef, const void* clientInfo)
{
- Q_Q(QQuickWebView);
-
- qWarning("WARNING: The web process has become unresponsive.");
+ QQuickWebView* q = toQQuickWebViewPrivate(clientInfo)->q_ptr;
emit q->experimental()->processDidBecomeUnresponsive();
}
-void QQuickWebViewPrivate::processDidBecomeResponsive()
+void QQuickWebViewPrivate::processDidBecomeResponsive(WKPageRef, const void* clientInfo)
{
- Q_Q(QQuickWebView);
-
- qWarning("WARNING: The web process has become responsive.");
+ QQuickWebView* q = toQQuickWebViewPrivate(clientInfo)->q_ptr;
emit q->experimental()->processDidBecomeResponsive();
}
@@ -537,7 +651,7 @@ void QQuickWebViewPrivate::handleDownloadRequest(DownloadProxy* download)
downloadItem->d->downloadProxy = download;
q->connect(downloadItem->d, SIGNAL(receivedResponse(QWebDownloadItem*)), q, SLOT(_q_onReceivedResponseFromDownload(QWebDownloadItem*)));
- QtWebContext::downloadManager()->addDownload(download, downloadItem);
+ QtWebContext::defaultContext()->downloadManager()->addDownload(toAPI(download), downloadItem);
}
void QQuickWebViewPrivate::_q_onVisibleChanged()
@@ -552,7 +666,7 @@ void QQuickWebViewPrivate::_q_onUrlChanged()
void QQuickWebViewPrivate::_q_onIconChangedForPageURL(const QString& pageUrl)
{
- if (pageUrl != QString(m_currentUrl))
+ if (pageUrl != m_currentUrl)
return;
updateIcon();
@@ -572,7 +686,7 @@ void QQuickWebViewPrivate::updateIcon()
if (!provider)
return;
- WTF::String iconUrl = provider->iconURLForPageURLInContext(m_currentUrl, context.get());
+ QUrl iconUrl = provider->iconURLForPageURLInContext(m_currentUrl, context);
if (iconUrl == m_iconUrl)
return;
@@ -748,10 +862,13 @@ 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;
- context->setNavigatorQtObjectEnabled(webPageProxy.get(), enabled);
+
+ static WKStringRef messageName = WKStringCreateWithUTF8CString("SetNavigatorQtObjectEnabled");
+ WKRetainPtr<WKBooleanRef> wkEnabled = adoptWK(WKBooleanCreate(enabled));
+ WKPagePostMessageToInjectedBundle(webPage.get(), messageName, wkEnabled.get());
}
-static QString readUserScript(const QUrl& url)
+static WKRetainPtr<WKStringRef> readUserScript(const QUrl& url)
{
QString path;
if (url.isLocalFile())
@@ -760,26 +877,27 @@ static QString readUserScript(const QUrl& url)
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 QString();
+ 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 QString();
+ return 0;
}
- QString contents = QString::fromUtf8(file.readAll());
+ QByteArray contents = file.readAll();
if (contents.isEmpty())
qWarning("QQuickWebView: Ignoring '%s' as user script because file is empty.", qPrintable(url.toString()));
- return contents;
+ return adoptWK(WKStringCreateWithUTF8CString(contents.constData()));
}
void QQuickWebViewPrivate::updateUserScripts()
{
- Vector<String> scripts;
- scripts.reserveCapacity(userScripts.size());
+ // 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);
@@ -788,13 +906,11 @@ void QQuickWebViewPrivate::updateUserScripts()
continue;
}
- QString contents = readUserScript(url);
- if (contents.isEmpty())
+ WKRetainPtr<WKStringRef> contents = readUserScript(url);
+ if (!contents || WKStringIsEmpty(contents.get()))
continue;
- scripts.append(String(contents));
+ WKPageGroupAddUserScript(pageGroup.get(), contents.get(), /*baseURL*/ 0, /*whitelistedURLPatterns*/ 0, /*blacklistedURLPatterns*/ 0, kWKInjectInTopFrameOnly, kWKInjectAtDocumentEnd);
}
-
- webPageProxy->setUserScripts(scripts);
}
void QQuickWebViewPrivate::updateSchemeDelegates()
@@ -835,14 +951,32 @@ WebCore::IntSize QQuickWebViewPrivate::viewSize() const
\sa postMessage
*/
-void QQuickWebViewPrivate::didReceiveMessageFromNavigatorQtObject(const String& message)
+void QQuickWebViewPrivate::didReceiveMessageFromNavigatorQtObject(WKStringRef message)
{
QVariantMap variantMap;
- variantMap.insert(QLatin1String("data"), QString(message));
+ 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)
{
@@ -865,23 +999,25 @@ void QQuickWebViewLegacyPrivate::updateViewportSize()
pageView->setContentsSize(viewportSize);
- // 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.
- webPageProxy->drawingArea()->setSize(viewportSize.toSize(), 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.
- webPageProxy->drawingArea()->setVisibleContentsRect(FloatRect(FloatPoint(), FloatSize(viewportSize)), 1, FloatPoint());
+ 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 webPageProxy->pageZoomFactor();
+ return WKPageGetPageZoomFactor(webPage.get());
}
void QQuickWebViewLegacyPrivate::setZoomFactor(qreal factor)
{
- webPageProxy->setPageZoomFactor(factor);
+ WKPageSetPageZoomFactor(webPage.get(), factor);
}
QQuickWebViewFlickablePrivate::QQuickWebViewFlickablePrivate(QQuickWebView* viewport)
@@ -901,7 +1037,7 @@ void QQuickWebViewFlickablePrivate::onComponentComplete()
Q_Q(QQuickWebView);
m_pageViewportControllerClient.reset(new PageViewportControllerClientQt(q, pageView.data()));
m_pageViewportController.reset(new PageViewportController(webPageProxy.get(), m_pageViewportControllerClient.data()));
- pageView->eventHandler()->setViewportController(m_pageViewportControllerClient.data());
+ pageEventHandler->setViewportController(m_pageViewportControllerClient.data());
// Trigger setting of correct visibility flags after everything was allocated and initialized.
_q_onVisibleChanged();
@@ -927,15 +1063,6 @@ void QQuickWebViewFlickablePrivate::pageDidRequestScroll(const QPoint& pos)
m_pageViewportController->pageDidRequestScroll(pos);
}
-void QQuickWebViewFlickablePrivate::handleMouseEvent(QMouseEvent* event)
-{
- if (!pageView->eventHandler())
- return;
-
- // FIXME: Update the axis locker for mouse events as well.
- pageView->eventHandler()->handleInputEvent(event);
-}
-
QQuickWebViewExperimental::QQuickWebViewExperimental(QQuickWebView *webView, QQuickWebViewPrivate* webViewPrivate)
: QObject(webView)
, q_ptr(webView)
@@ -1045,7 +1172,9 @@ bool QQuickWebViewExperimental::flickableViewportEnabled()
void QQuickWebViewExperimental::postMessage(const QString& message)
{
Q_D(QQuickWebView);
- d->context->postMessageToNavigatorQtObject(d->webPageProxy.get(), message);
+ static WKStringRef messageName = WKStringCreateWithUTF8CString("MessageToNavigatorQtObject");
+ WKRetainPtr<WKStringRef> contents = adoptWK(WKStringCreateWithQString(message));
+ WKPagePostMessageToInjectedBundle(d->webPage.get(), messageName, contents.get());
}
QQmlComponent* QQuickWebViewExperimental::alertDialog() const
@@ -1214,16 +1343,19 @@ void QQuickWebViewExperimental::setColorChooser(QQmlComponent* colorChooser)
QString QQuickWebViewExperimental::userAgent() const
{
Q_D(const QQuickWebView);
- return d->webPageProxy->userAgent();
+ WKRetainPtr<WKStringRef> ua = adoptWK(WKPageCopyCustomUserAgent(d->webPage.get()));
+ return WKStringCopyQString(ua.get());
}
void QQuickWebViewExperimental::setUserAgent(const QString& userAgent)
{
Q_D(QQuickWebView);
- if (userAgent == QString(d->webPageProxy->userAgent()))
+ WKRetainPtr<WKStringRef> newUserAgent = adoptWK(WKStringCreateWithQString(userAgent));
+ WKRetainPtr<WKStringRef> currentUserAgent = adoptWK(WKPageCopyCustomUserAgent(d->webPage.get()));
+ if (WKStringIsEqual(newUserAgent.get(), currentUserAgent.get()))
return;
- d->webPageProxy->setUserAgent(userAgent);
+ WKPageSetCustomUserAgent(d->webPage.get(), newUserAgent.get());
emit userAgentChanged();
}
@@ -1290,7 +1422,31 @@ void QQuickWebViewExperimental::evaluateJavaScript(const QString& script, const
closure->receiver = this;
closure->value = value;
- d_ptr->webPageProxy.get()->runJavaScriptInMainFrame(script, ScriptValueCallback::create(closure, javaScriptCallback));
+ 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
@@ -1420,8 +1576,8 @@ QQuickWebPage* QQuickWebViewExperimental::page()
}
/*!
- \page qtwebkit-index.html
- \title Qt WebKit
+ \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
@@ -1514,7 +1670,7 @@ QQuickWebPage* QQuickWebView::page()
void QQuickWebView::goBack()
{
Q_D(QQuickWebView);
- d->webPageProxy->goBack();
+ WKPageGoBack(d->webPage.get());
}
/*!
@@ -1526,7 +1682,7 @@ void QQuickWebView::goBack()
void QQuickWebView::goForward()
{
Q_D(QQuickWebView);
- d->webPageProxy->goForward();
+ WKPageGoForward(d->webPage.get());
}
/*!
@@ -1537,7 +1693,7 @@ void QQuickWebView::goForward()
void QQuickWebView::stop()
{
Q_D(QQuickWebView);
- d->webPageProxy->stopLoading();
+ WKPageStopLoading(d->webPage.get());
}
/*!
@@ -1562,8 +1718,7 @@ void QQuickWebView::reload()
return;
}
- const bool reloadFromOrigin = true;
- d->webPageProxy->reload(reloadFromOrigin);
+ WKPageReloadFromOrigin(d->webPage.get());
}
/*!
@@ -1592,7 +1747,8 @@ void QQuickWebView::setUrl(const QUrl& url)
if (url.isEmpty())
return;
- d->webPageProxy->loadURL(url.toString());
+ WKRetainPtr<WKURLRef> u = adoptWK(WKURLCreateWithQUrl(url));
+ WKPageLoadURL(d->webPage.get(), u.get());
emitUrlChangeIfNeeded();
}
@@ -1601,7 +1757,7 @@ void QQuickWebView::emitUrlChangeIfNeeded()
{
Q_D(QQuickWebView);
- WTF::String activeUrl = d->webPageProxy->activeURL();
+ QString activeUrl = d->webPageProxy->activeURL();
if (activeUrl != d->m_currentUrl) {
d->m_currentUrl = activeUrl;
emit urlChanged();
@@ -1629,7 +1785,7 @@ void QQuickWebView::emitUrlChangeIfNeeded()
QUrl QQuickWebView::icon() const
{
Q_D(const QQuickWebView);
- return QUrl(d->m_iconUrl);
+ return d->m_iconUrl;
}
/*!
@@ -1653,7 +1809,7 @@ int QQuickWebView::loadProgress() const
bool QQuickWebView::canGoBack() const
{
Q_D(const QQuickWebView);
- return d->webPageProxy->canGoBack();
+ return WKPageCanGoBack(d->webPage.get());
}
/*!
@@ -1665,7 +1821,7 @@ bool QQuickWebView::canGoBack() const
bool QQuickWebView::canGoForward() const
{
Q_D(const QQuickWebView);
- return d->webPageProxy->canGoForward();
+ return WKPageCanGoForward(d->webPage.get());
}
/*!
@@ -1676,8 +1832,8 @@ bool QQuickWebView::canGoForward() const
bool QQuickWebView::loading() const
{
Q_D(const QQuickWebView);
- RefPtr<WebKit::WebFrameProxy> mainFrame = d->webPageProxy->mainFrame();
- return mainFrame && !(WebFrameProxy::LoadStateFinished == mainFrame->loadState());
+ WKFrameRef mainFrame = WKPageGetMainFrame(d->webPage.get());
+ return mainFrame && !(kWKFrameLoadStateFinished == WKFrameGetFrameLoadState(mainFrame));
}
/*!
@@ -1728,7 +1884,8 @@ QRectF QQuickWebView::mapRectFromWebContent(const QRectF& rectInCSSCoordinates)
QString QQuickWebView::title() const
{
Q_D(const QQuickWebView);
- return d->webPageProxy->pageTitle();
+ WKRetainPtr<WKStringRef> t = adoptWK(WKPageCopyTitle(d->webPage.get()));
+ return WKStringCopyQString(t.get());
}
QVariant QQuickWebView::inputMethodQuery(Qt::InputMethodQuery property) const
@@ -1827,25 +1984,25 @@ void QQuickWebView::componentComplete()
void QQuickWebView::keyPressEvent(QKeyEvent* event)
{
Q_D(QQuickWebView);
- d->pageView->eventHandler()->handleKeyPressEvent(event);
+ d->pageEventHandler->handleKeyPressEvent(event);
}
void QQuickWebView::keyReleaseEvent(QKeyEvent* event)
{
Q_D(QQuickWebView);
- d->pageView->eventHandler()->handleKeyReleaseEvent(event);
+ d->pageEventHandler->handleKeyReleaseEvent(event);
}
void QQuickWebView::inputMethodEvent(QInputMethodEvent* event)
{
Q_D(QQuickWebView);
- d->pageView->eventHandler()->handleInputMethodEvent(event);
+ d->pageEventHandler->handleInputMethodEvent(event);
}
void QQuickWebView::focusInEvent(QFocusEvent* event)
{
Q_D(QQuickWebView);
- d->pageView->eventHandler()->handleFocusInEvent(event);
+ d->pageEventHandler->handleFocusInEvent(event);
}
void QQuickWebView::itemChange(ItemChange change, const ItemChangeData &value)
@@ -1854,7 +2011,7 @@ void QQuickWebView::itemChange(ItemChange change, const ItemChangeData &value)
if (change == ItemActiveFocusHasChanged) {
bool focus = value.boolValue;
if (!focus)
- d->pageView->eventHandler()->handleFocusLost();
+ d->pageEventHandler->handleFocusLost();
}
QQuickFlickable::itemChange(change, value);
}
@@ -1874,7 +2031,7 @@ void QQuickWebView::touchEvent(QTouchEvent* event)
d->axisLocker.reset();
forceActiveFocus();
- d->pageView->eventHandler()->handleTouchEvent(event);
+ d->pageEventHandler->handleTouchEvent(event);
}
void QQuickWebView::mousePressEvent(QMouseEvent* event)
@@ -1906,50 +2063,50 @@ void QQuickWebView::mouseDoubleClickEvent(QMouseEvent* event)
void QQuickWebView::wheelEvent(QWheelEvent* event)
{
Q_D(QQuickWebView);
- d->pageView->eventHandler()->handleWheelEvent(event);
+ d->pageEventHandler->handleWheelEvent(event);
}
void QQuickWebView::hoverEnterEvent(QHoverEvent* event)
{
Q_D(QQuickWebView);
// Map HoverEnter to Move, for WebKit the distinction doesn't matter.
- d->pageView->eventHandler()->handleHoverMoveEvent(event);
+ d->pageEventHandler->handleHoverMoveEvent(event);
}
void QQuickWebView::hoverMoveEvent(QHoverEvent* event)
{
Q_D(QQuickWebView);
- d->pageView->eventHandler()->handleHoverMoveEvent(event);
+ d->pageEventHandler->handleHoverMoveEvent(event);
}
void QQuickWebView::hoverLeaveEvent(QHoverEvent* event)
{
Q_D(QQuickWebView);
- d->pageView->eventHandler()->handleHoverLeaveEvent(event);
+ d->pageEventHandler->handleHoverLeaveEvent(event);
}
void QQuickWebView::dragMoveEvent(QDragMoveEvent* event)
{
Q_D(QQuickWebView);
- d->pageView->eventHandler()->handleDragMoveEvent(event);
+ d->pageEventHandler->handleDragMoveEvent(event);
}
void QQuickWebView::dragEnterEvent(QDragEnterEvent* event)
{
Q_D(QQuickWebView);
- d->pageView->eventHandler()->handleDragEnterEvent(event);
+ d->pageEventHandler->handleDragEnterEvent(event);
}
void QQuickWebView::dragLeaveEvent(QDragLeaveEvent* event)
{
Q_D(QQuickWebView);
- d->pageView->eventHandler()->handleDragLeaveEvent(event);
+ d->pageEventHandler->handleDragLeaveEvent(event);
}
void QQuickWebView::dropEvent(QDropEvent* event)
{
Q_D(QQuickWebView);
- d->pageView->eventHandler()->handleDropEvent(event);
+ d->pageEventHandler->handleDropEvent(event);
}
bool QQuickWebView::event(QEvent* ev)
@@ -1961,7 +2118,7 @@ bool QQuickWebView::event(QEvent* ev)
WKPageRef QQuickWebView::pageRef() const
{
Q_D(const QQuickWebView);
- return toAPI(d->webPageProxy.get());
+ return d->webPage.get();
}
QPointF QQuickWebView::contentPos() const
@@ -2028,10 +2185,14 @@ void QQuickWebView::handleFlickableMouseRelease(const QPointF& position, qint64
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())
- d->webPageProxy->loadAlternateHTMLString(html, baseUrl.toString(), unreachableUrl.toString());
+ WKPageLoadAlternateHTMLString(d->webPage.get(), htmlRef.get(), baseUrlRef.get(), unreachableUrlRef.get());
else
- d->webPageProxy->loadHTMLString(html, baseUrl.toString());
+ WKPageLoadHTMLString(d->webPage.get(), htmlRef.get(), baseUrlRef.get());
}
qreal QQuickWebView::zoomFactor() const
@@ -2055,7 +2216,8 @@ void QQuickWebView::runJavaScriptInMainFrame(const QString &script, QObject *rec
closure->receiver = receiver;
closure->method = method;
- d->webPageProxy.get()->runJavaScriptInMainFrame(script, ScriptValueCallback::create(closure, javaScriptCallback));
+ WKRetainPtr<WKStringRef> scriptString = adoptWK(WKStringCreateWithQString(script));
+ WKPageRunJavaScriptInMainFrame(d->webPage.get(), scriptString.get(), closure, javaScriptCallback);
}
bool QQuickWebView::allowAnyHTTPSCertificateForLocalHost() const
@@ -2070,6 +2232,17 @@ void QQuickWebView::setAllowAnyHTTPSCertificateForLocalHost(bool allow)
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)