summaryrefslogtreecommitdiffstats
path: root/src/webengine/api/qquickwebengineview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/webengine/api/qquickwebengineview.cpp')
-rw-r--r--src/webengine/api/qquickwebengineview.cpp467
1 files changed, 387 insertions, 80 deletions
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index a35cfc3c3..bc58e2526 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
**
@@ -10,15 +10,15 @@
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
+** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
@@ -26,7 +26,7 @@
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
+** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
@@ -37,17 +37,27 @@
#include "qquickwebengineview_p.h"
#include "qquickwebengineview_p_p.h"
+#include "browser_context_adapter.h"
#include "certificate_error_controller.h"
#include "javascript_dialog_controller.h"
#include "qquickwebenginehistory_p.h"
+#include "qquickwebenginecertificateerror_p.h"
#include "qquickwebengineloadrequest_p.h"
#include "qquickwebenginenavigationrequest_p.h"
#include "qquickwebenginenewviewrequest_p.h"
+#include "qquickwebengineprofile_p.h"
+#include "qquickwebengineprofile_p_p.h"
#include "qquickwebenginesettings_p.h"
-#include "qquickwebenginesettings_p_p.h"
+#include "qquickwebenginescript_p_p.h"
+
+#ifdef ENABLE_QML_TESTSUPPORT_API
+#include "qquickwebenginetestsupport_p.h"
+#endif
+
#include "render_widget_host_view_qt_delegate_quick.h"
#include "render_widget_host_view_qt_delegate_quickwindow.h"
#include "ui_delegates_manager.h"
+#include "user_script_controller_host.h"
#include "web_contents_adapter.h"
#include "web_engine_error.h"
#include "web_engine_settings.h"
@@ -58,6 +68,7 @@
#include <QQmlContext>
#include <QQmlEngine>
#include <QQmlProperty>
+#include <QQmlWebChannel>
#include <QScreen>
#include <QStringBuilder>
#include <QUrl>
@@ -66,6 +77,7 @@
#endif // QT_NO_ACCESSIBILITY
QT_BEGIN_NAMESPACE
+using namespace QtWebEngineCore;
#ifndef QT_NO_ACCESSIBILITY
static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *object)
@@ -77,14 +89,17 @@ static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *obje
#endif // QT_NO_ACCESSIBILITY
QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
- : adapter(new WebContentsAdapter)
+ : adapter(0)
, e(new QQuickWebEngineViewExperimental(this))
, v(new QQuickWebEngineViewport(this))
, m_history(new QQuickWebEngineHistory(this))
- , m_settings(new QQuickWebEngineSettings)
+ , m_profile(QQuickWebEngineProfile::defaultProfile())
+ , m_settings(new QQuickWebEngineSettings(m_profile->settings()))
+#ifdef ENABLE_QML_TESTSUPPORT_API
+ , m_testSupport(0)
+#endif
, contextMenuExtraItems(0)
, loadProgress(0)
- , inspectable(false)
, m_isFullScreen(false)
, isLoading(false)
, devicePixelRatio(QGuiApplication::primaryScreen()->devicePixelRatio())
@@ -217,10 +232,23 @@ void QQuickWebEngineViewPrivate::javascriptDialog(QSharedPointer<JavaScriptDialo
ui()->showDialog(dialog);
}
-void QQuickWebEngineViewPrivate::allowCertificateError(const QExplicitlySharedDataPointer<CertificateErrorController> &errorController)
+void QQuickWebEngineViewPrivate::allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController)
+{
+ Q_Q(QQuickWebEngineView);
+
+ QQuickWebEngineCertificateError *quickController = new QQuickWebEngineCertificateError(errorController);
+ QQmlEngine::setObjectOwnership(quickController, QQmlEngine::JavaScriptOwnership);
+ Q_EMIT q->certificateError(quickController);
+ if (!quickController->deferred() && !quickController->answered())
+ quickController->rejectCertificate();
+ else
+ m_certificateErrorControllers.append(errorController);
+}
+
+void QQuickWebEngineViewPrivate::runGeolocationPermissionRequest(const QUrl &url)
{
- // ### Implement a way to export this to QML
- Q_UNUSED(errorController);
+ Q_Q(QQuickWebEngineView);
+ Q_EMIT q->featurePermissionRequested(url, QQuickWebEngineView::Geolocation);
}
void QQuickWebEngineViewPrivate::runFileChooser(FileChooserMode mode, const QString &defaultFileName, const QStringList &acceptedMimeTypes)
@@ -282,11 +310,20 @@ qreal QQuickWebEngineViewPrivate::dpiScale() const
return m_dpiScale;
}
-void QQuickWebEngineViewPrivate::loadStarted(const QUrl &provisionalUrl)
+void QQuickWebEngineViewPrivate::loadStarted(const QUrl &provisionalUrl, bool isErrorPage)
{
Q_Q(QQuickWebEngineView);
+ if (isErrorPage) {
+#ifdef ENABLE_QML_TESTSUPPORT_API
+ if (m_testSupport)
+ m_testSupport->errorPage()->loadStarted(provisionalUrl);
+#endif
+ return;
+ }
+
isLoading = true;
m_history->reset();
+ m_certificateErrorControllers.clear();
QQuickWebEngineLoadRequest loadRequest(provisionalUrl, QQuickWebEngineView::LoadStartedStatus);
Q_EMIT q->loadingChanged(&loadRequest);
}
@@ -305,9 +342,18 @@ Q_STATIC_ASSERT(static_cast<int>(WebEngineError::NoErrorDomain) == static_cast<i
Q_STATIC_ASSERT(static_cast<int>(WebEngineError::CertificateErrorDomain) == static_cast<int>(QQuickWebEngineView::CertificateErrorDomain));
Q_STATIC_ASSERT(static_cast<int>(WebEngineError::DnsErrorDomain) == static_cast<int>(QQuickWebEngineView::DnsErrorDomain));
-void QQuickWebEngineViewPrivate::loadFinished(bool success, const QUrl &url, int errorCode, const QString &errorDescription)
+void QQuickWebEngineViewPrivate::loadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode, const QString &errorDescription)
{
Q_Q(QQuickWebEngineView);
+
+ if (isErrorPage) {
+#ifdef ENABLE_QML_TESTSUPPORT_API
+ if (m_testSupport)
+ m_testSupport->errorPage()->loadFinished(success, url);
+#endif
+ return;
+ }
+
isLoading = false;
m_history->reset();
if (errorCode == WebEngineError::UserAbortedError) {
@@ -339,8 +385,16 @@ void QQuickWebEngineViewPrivate::focusContainer()
q->forceActiveFocus();
}
+void QQuickWebEngineViewPrivate::unhandledKeyEvent(QKeyEvent *event)
+{
+ Q_Q(QQuickWebEngineView);
+ if (q->parentItem())
+ q->window()->sendEvent(q->parentItem(), event);
+}
+
void QQuickWebEngineViewPrivate::adoptNewWindow(WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &)
{
+ Q_Q(QQuickWebEngineView);
QQuickWebEngineNewViewRequest request;
// This increases the ref-count of newWebContents and will tell Chromium
// to start loading it and possibly return it to its parent page window.open().
@@ -349,9 +403,11 @@ void QQuickWebEngineViewPrivate::adoptNewWindow(WebContentsAdapter *newWebConten
switch (disposition) {
case WebContentsAdapterClient::NewForegroundTabDisposition:
- case WebContentsAdapterClient::NewBackgroundTabDisposition:
request.m_destination = QQuickWebEngineView::NewViewInTab;
break;
+ case WebContentsAdapterClient::NewBackgroundTabDisposition:
+ request.m_destination = QQuickWebEngineView::NewViewInBackgroundTab;
+ break;
case WebContentsAdapterClient::NewPopupDisposition:
request.m_destination = QQuickWebEngineView::NewViewInDialog;
break;
@@ -362,7 +418,7 @@ void QQuickWebEngineViewPrivate::adoptNewWindow(WebContentsAdapter *newWebConten
Q_UNREACHABLE();
}
- emit e->newViewRequested(&request);
+ Q_EMIT q->newViewRequested(&request);
}
void QQuickWebEngineViewPrivate::close()
@@ -372,33 +428,44 @@ void QQuickWebEngineViewPrivate::close()
void QQuickWebEngineViewPrivate::requestFullScreen(bool fullScreen)
{
- Q_EMIT e->fullScreenRequested(fullScreen);
+ Q_Q(QQuickWebEngineView);
+ QQuickWebEngineFullScreenRequest request(this, fullScreen);
+ Q_EMIT q->fullScreenRequested(request);
}
bool QQuickWebEngineViewPrivate::isFullScreen() const
{
- return e->isFullScreen();
+ return m_isFullScreen;
}
void QQuickWebEngineViewPrivate::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID)
{
Q_Q(QQuickWebEngineView);
- Q_UNUSED(level);
Q_EMIT q->javaScriptConsoleMessage(static_cast<QQuickWebEngineView::JavaScriptConsoleMessageLevel>(level), message, lineNumber, sourceID);
}
void QQuickWebEngineViewPrivate::runMediaAccessPermissionRequest(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags requestFlags)
{
- if (!requestFlags)
- return;
- QQuickWebEngineViewExperimental::Feature feature;
- if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture) && requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
- feature = QQuickWebEngineViewExperimental::MediaAudioVideoDevices;
- else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture))
- feature = QQuickWebEngineViewExperimental::MediaAudioDevices;
- else // WebContentsAdapterClient::MediaVideoCapture
- feature = QQuickWebEngineViewExperimental::MediaVideoDevices;
- Q_EMIT e->featurePermissionRequested(securityOrigin, feature);
+ Q_Q(QQuickWebEngineView);
+ if (!requestFlags)
+ return;
+ QQuickWebEngineView::Feature feature;
+ if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture) && requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
+ feature = QQuickWebEngineView::MediaAudioVideoCapture;
+ else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture))
+ feature = QQuickWebEngineView::MediaAudioCapture;
+ else // WebContentsAdapterClient::MediaVideoCapture
+ feature = QQuickWebEngineView::MediaVideoCapture;
+ Q_EMIT q->featurePermissionRequested(securityOrigin, feature);
+}
+
+void QQuickWebEngineViewPrivate::runMouseLockPermissionRequest(const QUrl &securityOrigin)
+{
+
+ Q_UNUSED(securityOrigin);
+
+ // TODO: Add mouse lock support
+ adapter->grantMouseLockPermission(false);
}
#ifndef QT_NO_ACCESSIBILITY
@@ -409,9 +476,14 @@ QObject *QQuickWebEngineViewPrivate::accessibilityParentObject()
}
#endif // QT_NO_ACCESSIBILITY
+BrowserContextAdapter *QQuickWebEngineViewPrivate::browserContextAdapter()
+{
+ return m_profile->d_ptr->browserContext();
+}
+
WebEngineSettings *QQuickWebEngineViewPrivate::webEngineSettings() const
{
- return m_settings->d_func()->coreSettings.data();
+ return m_settings->d_ptr.data();
}
void QQuickWebEngineViewPrivate::setDevicePixelRatio(qreal devicePixelRatio)
@@ -480,6 +552,11 @@ void QQuickWebEngineViewPrivate::adoptWebContents(WebContentsAdapter *webContent
return;
}
+ if (webContents->browserContextAdapter() && browserContextAdapter() != webContents->browserContextAdapter()) {
+ qWarning("Can not adopt content from a different WebEngineProfile.");
+ return;
+ }
+
Q_Q(QQuickWebEngineView);
// This throws away the WebContentsAdapter that has been used until now.
// All its states, particularly the loading URL, are replaced by the adopted WebContentsAdapter.
@@ -503,7 +580,6 @@ QQuickWebEngineView::QQuickWebEngineView(QQuickItem *parent)
{
Q_D(QQuickWebEngineView);
d->e->q_ptr = d->q_ptr = this;
- d->adapter->initialize(d);
this->setActiveFocusOnTab(true);
this->setFlag(QQuickItem::ItemIsFocusScope);
@@ -517,10 +593,23 @@ QQuickWebEngineView::~QQuickWebEngineView()
{
}
+void QQuickWebEngineViewPrivate::ensureContentsAdapter()
+{
+ if (!adapter) {
+ adapter = new WebContentsAdapter();
+ adapter->initialize(this);
+ if (explicitUrl.isValid())
+ adapter->load(explicitUrl);
+ // push down the page's user scripts
+ Q_FOREACH (QQuickWebEngineScript *script, m_userScripts)
+ script->d_func()->bind(browserContextAdapter()->userScriptController(), adapter.data());
+ }
+}
+
QUrl QQuickWebEngineView::url() const
{
Q_D(const QQuickWebEngineView);
- return d->explicitUrl.isValid() ? d->explicitUrl : d->adapter->activeUrl();
+ return d->explicitUrl.isValid() ? d->explicitUrl : (d->adapter ? d->adapter->activeUrl() : QUrl());
}
void QQuickWebEngineView::setUrl(const QUrl& url)
@@ -530,7 +619,10 @@ void QQuickWebEngineView::setUrl(const QUrl& url)
Q_D(QQuickWebEngineView);
d->explicitUrl = url;
- d->adapter->load(url);
+ if (d->adapter)
+ d->adapter->load(url);
+ if (!qmlEngine(this))
+ d->ensureContentsAdapter();
}
QUrl QQuickWebEngineView::icon() const
@@ -542,33 +634,125 @@ QUrl QQuickWebEngineView::icon() const
void QQuickWebEngineView::loadHtml(const QString &html, const QUrl &baseUrl)
{
Q_D(QQuickWebEngineView);
- d->adapter->setContent(html.toUtf8(), QStringLiteral("text/html;charset=UTF-8"), baseUrl);
+ d->explicitUrl = QUrl();
+ if (!qmlEngine(this))
+ d->ensureContentsAdapter();
+ if (d->adapter)
+ d->adapter->setContent(html.toUtf8(), QStringLiteral("text/html;charset=UTF-8"), baseUrl);
}
void QQuickWebEngineView::goBack()
{
Q_D(QQuickWebEngineView);
+ if (!d->adapter)
+ return;
d->adapter->navigateToOffset(-1);
}
void QQuickWebEngineView::goForward()
{
Q_D(QQuickWebEngineView);
+ if (!d->adapter)
+ return;
d->adapter->navigateToOffset(1);
}
void QQuickWebEngineView::reload()
{
Q_D(QQuickWebEngineView);
+ if (!d->adapter)
+ return;
d->adapter->reload();
}
+void QQuickWebEngineView::reloadAndBypassCache()
+{
+ Q_D(QQuickWebEngineView);
+ if (!d->adapter)
+ return;
+ d->adapter->reloadAndBypassCache();
+}
+
void QQuickWebEngineView::stop()
{
Q_D(QQuickWebEngineView);
+ if (!d->adapter)
+ return;
d->adapter->stop();
}
+void QQuickWebEngineView::setZoomFactor(qreal arg)
+{
+ Q_D(QQuickWebEngineView);
+ if (!d->adapter)
+ return;
+ qreal oldFactor = d->adapter->currentZoomFactor();
+ d->adapter->setZoomFactor(arg);
+ if (qFuzzyCompare(oldFactor, d->adapter->currentZoomFactor()))
+ return;
+
+ emit zoomFactorChanged(arg);
+}
+
+QQuickWebEngineProfile *QQuickWebEngineView::profile() const
+{
+ Q_D(const QQuickWebEngineView);
+ return d->m_profile;
+}
+
+void QQuickWebEngineView::setProfile(QQuickWebEngineProfile *profile)
+{
+ Q_D(QQuickWebEngineView);
+ d->setProfile(profile);
+}
+
+QQuickWebEngineSettings *QQuickWebEngineView::settings() const
+{
+ Q_D(const QQuickWebEngineView);
+ return d->m_settings.data();
+}
+
+QQmlListProperty<QQuickWebEngineScript> QQuickWebEngineView::userScripts()
+{
+ Q_D(QQuickWebEngineView);
+ return QQmlListProperty<QQuickWebEngineScript>(this, d,
+ d->userScripts_append,
+ d->userScripts_count,
+ d->userScripts_at,
+ d->userScripts_clear);
+}
+
+void QQuickWebEngineViewPrivate::setProfile(QQuickWebEngineProfile *profile)
+{
+ if (profile == m_profile)
+ return;
+ m_profile = profile;
+ m_settings->setParentSettings(profile->settings());
+
+ if (adapter && adapter->browserContext() != browserContextAdapter()->browserContext()) {
+ // When the profile changes we need to create a new WebContentAdapter and reload the active URL.
+ QUrl activeUrl = adapter->activeUrl();
+ adapter = 0;
+ ensureContentsAdapter();
+ if (!explicitUrl.isValid() && activeUrl.isValid())
+ adapter->load(activeUrl);
+ }
+}
+
+#ifdef ENABLE_QML_TESTSUPPORT_API
+QQuickWebEngineTestSupport *QQuickWebEngineView::testSupport() const
+{
+ Q_D(const QQuickWebEngineView);
+ return d->m_testSupport;
+}
+
+void QQuickWebEngineView::setTestSupport(QQuickWebEngineTestSupport *testSupport)
+{
+ Q_D(QQuickWebEngineView);
+ d->m_testSupport = testSupport;
+}
+#endif
+
void QQuickWebEngineViewPrivate::didRunJavaScript(quint64 requestId, const QVariant &result)
{
Q_Q(QQuickWebEngineView);
@@ -585,6 +769,20 @@ void QQuickWebEngineViewPrivate::didFindText(quint64 requestId, int matchCount)
args.append(QJSValue(matchCount));
callback.call(args);
}
+void QQuickWebEngineViewPrivate::showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText)
+{
+ ui()->showMessageBubble(anchor, mainText, subText);
+}
+
+void QQuickWebEngineViewPrivate::hideValidationMessage()
+{
+ ui()->hideMessageBubble();
+}
+
+void QQuickWebEngineViewPrivate::moveValidationMessage(const QRect &anchor)
+{
+ ui()->moveMessageBubble(anchor);
+}
bool QQuickWebEngineView::isLoading() const
{
@@ -601,24 +799,32 @@ int QQuickWebEngineView::loadProgress() const
QString QQuickWebEngineView::title() const
{
Q_D(const QQuickWebEngineView);
+ if (!d->adapter)
+ return QString();
return d->adapter->pageTitle();
}
bool QQuickWebEngineView::canGoBack() const
{
Q_D(const QQuickWebEngineView);
+ if (!d->adapter)
+ return false;
return d->adapter->canGoBack();
}
bool QQuickWebEngineView::canGoForward() const
{
Q_D(const QQuickWebEngineView);
+ if (!d->adapter)
+ return false;
return d->adapter->canGoForward();
}
void QQuickWebEngineView::runJavaScript(const QString &script, const QJSValue &callback)
{
Q_D(QQuickWebEngineView);
+ if (!d->adapter)
+ return;
if (!callback.isUndefined()) {
quint64 requestId = d_ptr->adapter->runJavaScriptCallbackResult(script);
d->m_callbacks.insert(requestId, callback);
@@ -632,28 +838,19 @@ QQuickWebEngineViewExperimental *QQuickWebEngineView::experimental() const
return d->e.data();
}
-bool QQuickWebEngineViewExperimental::inspectable() const
+qreal QQuickWebEngineView::zoomFactor() const
{
Q_D(const QQuickWebEngineView);
- return d->inspectable;
-}
-
-void QQuickWebEngineViewExperimental::setInspectable(bool enable)
-{
- Q_D(QQuickWebEngineView);
- d->inspectable = enable;
- d->adapter->enableInspector(enable);
+ if (!d->adapter)
+ return 1.0;
+ return d->adapter->currentZoomFactor();
}
-void QQuickWebEngineViewExperimental::setIsFullScreen(bool fullscreen)
-{
- d_ptr->m_isFullScreen = fullscreen;
- emit isFullScreenChanged();
-}
-bool QQuickWebEngineViewExperimental::isFullScreen() const
+bool QQuickWebEngineView::isFullScreen() const
{
- return d_ptr->m_isFullScreen;
+ Q_D(const QQuickWebEngineView);
+ return d->m_isFullScreen;
}
void QQuickWebEngineViewExperimental::setExtraContextMenuEntriesComponent(QQmlComponent *contextMenuExtras)
@@ -669,69 +866,115 @@ QQmlComponent *QQuickWebEngineViewExperimental::extraContextMenuEntriesComponent
return d_ptr->contextMenuExtraItems;
}
-QQuickWebEngineSettings *QQuickWebEngineViewExperimental::settings() const
-{
- return d_ptr->m_settings.data();
-}
-
-void QQuickWebEngineViewExperimental::findText(const QString &subString, FindFlags options, const QJSValue &callback)
+void QQuickWebEngineView::findText(const QString &subString, FindFlags options, const QJSValue &callback)
{
+ Q_D(QQuickWebEngineView);
+ if (!d->adapter)
+ return;
if (subString.isEmpty()) {
- d_ptr->adapter->stopFinding();
+ d->adapter->stopFinding();
if (!callback.isUndefined()) {
QJSValueList args;
args.append(QJSValue(0));
const_cast<QJSValue&>(callback).call(args);
}
} else {
- quint64 requestId = d_ptr->adapter->findText(subString, options & FindCaseSensitively, options & FindBackward);
+ quint64 requestId = d->adapter->findText(subString, options & FindCaseSensitively, options & FindBackward);
if (!callback.isUndefined())
- d_ptr->m_callbacks.insert(requestId, callback);
+ d->m_callbacks.insert(requestId, callback);
+ }
+}
+
+QQuickWebEngineHistory *QQuickWebEngineView::navigationHistory() const
+{
+ Q_D(const QQuickWebEngineView);
+ return d->m_history.data();
+}
+
+/*!
+ * \qmlproperty QQmlWebChannel WebEngineView::webChannel
+ * \since QtWebEngine 1.1
+ *
+ * The web channel instance used by this view.
+ * This channel is automatically using the internal QtWebEngine transport mechanism over Chromium IPC,
+ * and exposed in the javascript context of the page it is rendering as \c qt.webChannelTransport.
+ * This transport object is used when instantiating the JavaScript counterpart of QWebChannel using
+ * the \l{Qt WebChannel JavaScript API}.
+ *
+ * \note The view does not take ownership when explicitly setting a webChannel object.
+ */
+
+QQmlWebChannel *QQuickWebEngineView::webChannel()
+{
+ Q_D(QQuickWebEngineView);
+ d->ensureContentsAdapter();
+ QQmlWebChannel *qmlWebChannel = qobject_cast<QQmlWebChannel *>(d->adapter->webChannel());
+ Q_ASSERT(!d->adapter->webChannel() || qmlWebChannel);
+ if (!qmlWebChannel) {
+ qmlWebChannel = new QQmlWebChannel(this);
+ d->adapter->setWebChannel(qmlWebChannel);
}
+ return qmlWebChannel;
}
-QQuickWebEngineHistory *QQuickWebEngineViewExperimental::navigationHistory() const
+void QQuickWebEngineView::setWebChannel(QQmlWebChannel *webChannel)
{
- return d_ptr->m_history.data();
+ Q_D(QQuickWebEngineView);
+ bool notify = (d->adapter->webChannel() == webChannel);
+ d->adapter->setWebChannel(webChannel);
+ if (notify)
+ Q_EMIT webChannelChanged();
}
-void QQuickWebEngineViewExperimental::grantFeaturePermission(const QUrl &securityOrigin, QQuickWebEngineViewExperimental::Feature feature, bool granted)
+void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQuickWebEngineView::Feature feature, bool granted)
{
- if (!granted && feature >= MediaAudioDevices && feature <= MediaAudioVideoDevices) {
+ if (!d_ptr->adapter)
+ return;
+ if (!granted && feature >= MediaAudioCapture && feature <= MediaAudioVideoCapture) {
d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaNone);
return;
}
switch (feature) {
- case MediaAudioDevices:
+ case MediaAudioCapture:
d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaAudioCapture);
break;
- case MediaVideoDevices:
+ case MediaVideoCapture:
d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaVideoCapture);
break;
- case MediaAudioVideoDevices:
- d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaRequestFlags(WebContentsAdapterClient::MediaAudioCapture
- | WebContentsAdapterClient::MediaVideoCapture));
+ case MediaAudioVideoCapture:
+ d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaRequestFlags(WebContentsAdapterClient::MediaAudioCapture | WebContentsAdapterClient::MediaVideoCapture));
+ break;
+ case Geolocation:
+ d_ptr->adapter->runGeolocationRequestCallback(securityOrigin, granted);
break;
+ default:
+ Q_UNREACHABLE();
}
}
-void QQuickWebEngineViewExperimental::goBackTo(int index)
+void QQuickWebEngineView::goBackOrForward(int offset)
{
- int count = d_ptr->adapter->currentNavigationEntryIndex();
+ Q_D(QQuickWebEngineView);
+ if (!d->adapter)
+ return;
+ const int current = d->adapter->currentNavigationEntryIndex();
+ const int count = d->adapter->navigationEntryCount();
+ const int index = current + offset;
+
if (index < 0 || index >= count)
return;
- d_ptr->adapter->navigateToIndex(count - 1 - index);
+ d->adapter->navigateToIndex(index);
}
-void QQuickWebEngineViewExperimental::goForwardTo(int index)
+void QQuickWebEngineView::fullScreenCancelled()
{
- int count = d_ptr->adapter->navigationEntryCount() - d_ptr->adapter->currentNavigationEntryIndex() - 1;
- if (index < 0 || index >= count)
- return;
-
- d_ptr->adapter->navigateToIndex(d_ptr->adapter->currentNavigationEntryIndex() + 1 + index);
+ Q_D(QQuickWebEngineView);
+ if (d->m_isFullScreen) {
+ d->m_isFullScreen = false;
+ Q_EMIT isFullScreenChanged();
+ }
}
void QQuickWebEngineView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
@@ -746,7 +989,7 @@ void QQuickWebEngineView::geometryChanged(const QRectF &newGeometry, const QRect
void QQuickWebEngineView::itemChange(ItemChange change, const ItemChangeData &value)
{
Q_D(QQuickWebEngineView);
- if (change == ItemSceneChange || change == ItemVisibleHasChanged) {
+ if (d->adapter && (change == ItemSceneChange || change == ItemVisibleHasChanged)) {
if (window() && isVisible())
d->adapter->wasShown();
else
@@ -755,6 +998,68 @@ void QQuickWebEngineView::itemChange(ItemChange change, const ItemChangeData &va
QQuickItem::itemChange(change, value);
}
+void QQuickWebEngineViewPrivate::userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script)
+{
+ Q_ASSERT(p && p->data);
+ QQuickWebEngineViewPrivate *d = static_cast<QQuickWebEngineViewPrivate*>(p->data);
+ UserScriptControllerHost *scriptController = d->browserContextAdapter()->userScriptController();
+ d->m_userScripts.append(script);
+ // If the adapter hasn't been instantiated, we'll bind the scripts in ensureContentsAdapter()
+ if (!d->adapter)
+ return;
+ script->d_func()->bind(scriptController, d->adapter.data());
+}
+
+int QQuickWebEngineViewPrivate::userScripts_count(QQmlListProperty<QQuickWebEngineScript> *p)
+{
+ Q_ASSERT(p && p->data);
+ QQuickWebEngineViewPrivate *d = static_cast<QQuickWebEngineViewPrivate*>(p->data);
+ return d->m_userScripts.count();
+}
+
+QQuickWebEngineScript *QQuickWebEngineViewPrivate::userScripts_at(QQmlListProperty<QQuickWebEngineScript> *p, int idx)
+{
+ Q_ASSERT(p && p->data);
+ QQuickWebEngineViewPrivate *d = static_cast<QQuickWebEngineViewPrivate*>(p->data);
+ return d->m_userScripts.at(idx);
+}
+
+void QQuickWebEngineViewPrivate::userScripts_clear(QQmlListProperty<QQuickWebEngineScript> *p)
+{
+ Q_ASSERT(p && p->data);
+ QQuickWebEngineViewPrivate *d = static_cast<QQuickWebEngineViewPrivate*>(p->data);
+ UserScriptControllerHost *scriptController = d->browserContextAdapter()->userScriptController();
+ scriptController->clearAllScripts(d->adapter.data());
+ d->m_userScripts.clear();
+}
+
+void QQuickWebEngineView::componentComplete()
+{
+ Q_D(QQuickWebEngineView);
+ QQuickItem::componentComplete();
+ d->ensureContentsAdapter();
+}
+
+QQuickWebEngineFullScreenRequest::QQuickWebEngineFullScreenRequest()
+ : viewPrivate(0)
+ , m_toggleOn(false)
+{
+}
+
+QQuickWebEngineFullScreenRequest::QQuickWebEngineFullScreenRequest(QQuickWebEngineViewPrivate *viewPrivate, bool toggleOn)
+ : viewPrivate(viewPrivate)
+ , m_toggleOn(toggleOn)
+{
+}
+
+void QQuickWebEngineFullScreenRequest::accept()
+{
+ if (viewPrivate && viewPrivate->m_isFullScreen != m_toggleOn) {
+ viewPrivate->m_isFullScreen = m_toggleOn;
+ Q_EMIT viewPrivate->q_ptr->isFullScreenChanged();
+ }
+}
+
QQuickWebEngineViewExperimental::QQuickWebEngineViewExperimental(QQuickWebEngineViewPrivate *viewPrivate)
: q_ptr(0)
, d_ptr(viewPrivate)
@@ -786,6 +1091,8 @@ void QQuickWebEngineViewport::setDevicePixelRatio(qreal devicePixelRatio)
if (d->devicePixelRatio == devicePixelRatio)
return;
d->setDevicePixelRatio(devicePixelRatio);
+ if (!d->adapter)
+ return;
d->adapter->dpiScaleChanged();
Q_EMIT devicePixelRatioChanged();
}