diff options
Diffstat (limited to 'src/webengine/api/qquickwebengineview.cpp')
-rw-r--r-- | src/webengine/api/qquickwebengineview.cpp | 197 |
1 files changed, 121 insertions, 76 deletions
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 02666d363..6bf23ea7b 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -107,11 +107,12 @@ static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *obje } #endif // QT_NO_ACCESSIBILITY +static QLatin1String defaultMimeType("text/html;charset=UTF-8"); + QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate() - : m_profile(QQuickWebEngineProfile::defaultProfile()) + : m_profile(nullptr) , adapter(QSharedPointer<WebContentsAdapter>::create()) , m_history(new QQuickWebEngineHistory(this)) - , m_settings(new QQuickWebEngineSettings(m_profile->settings())) #if QT_CONFIG(webengine_testsupport) , m_testSupport(0) #endif @@ -127,11 +128,12 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate() , m_isBeingAdopted(false) , m_dpiScale(1.0) , m_backgroundColor(Qt::white) - , m_defaultZoomFactor(1.0) + , m_zoomFactor(1.0) , m_ui2Enabled(false) + , m_profileInitialized(false) { - m_profile->d_ptr->addWebContentsAdapterClient(this); memset(actions, 0, sizeof(actions)); + QString platform = qApp->platformName().toLower(); if (platform == QLatin1Literal("eglfs")) m_ui2Enabled = true; @@ -159,12 +161,31 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate() QQuickWebEngineViewPrivate::~QQuickWebEngineViewPrivate() { + Q_ASSERT(m_profileInitialized); m_profile->d_ptr->removeWebContentsAdapterClient(this); adapter->stopFinding(); if (faviconProvider) faviconProvider->detach(q_ptr); } +void QQuickWebEngineViewPrivate::initializeProfile() +{ + if (!m_profileInitialized) { + Q_ASSERT(!adapter->isInitialized()); + m_profileInitialized = true; + if (!m_profile) + m_profile = QQuickWebEngineProfile::defaultProfile(); + m_profile->d_ptr->addWebContentsAdapterClient(this); + m_settings.reset(new QQuickWebEngineSettings(m_profile->settings())); + adapter->setClient(this); + } +} + +bool QQuickWebEngineViewPrivate::profileInitialized() const +{ + return m_profileInitialized; +} + void QQuickWebEngineViewPrivate::destroy() { // the profile for this web contens is about to be @@ -327,7 +348,6 @@ void QQuickWebEngineViewPrivate::urlChanged(const QUrl &url) { Q_Q(QQuickWebEngineView); Q_UNUSED(url); - explicitUrl = QUrl(); Q_EMIT q->urlChanged(); } @@ -452,9 +472,8 @@ void QQuickWebEngineViewPrivate::loadFinished(bool success, const QUrl &url, boo return; } if (success) { - explicitUrl = QUrl(); - QTimer::singleShot(0, q, [q, url]() { - QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus); + QTimer::singleShot(0, q, [q, url, errorDescription, errorCode]() { + QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus, errorDescription, errorCode); emit q->loadingChanged(&loadRequest); }); return; @@ -753,8 +772,6 @@ QQuickWebEngineView::QQuickWebEngineView(QQuickItem *parent) { Q_D(QQuickWebEngineView); d->q_ptr = this; - d->adapter->setClient(d); - this->setActiveFocusOnTab(true); this->setFlags(QQuickItem::ItemIsFocusScope | QQuickItem::ItemAcceptsDrops); } @@ -765,9 +782,12 @@ QQuickWebEngineView::~QQuickWebEngineView() void QQuickWebEngineViewPrivate::ensureContentsAdapter() { + initializeProfile(); if (!adapter->isInitialized()) { - if (explicitUrl.isValid()) - adapter->load(explicitUrl); + if (!m_html.isEmpty()) + adapter->setContent(m_html.toUtf8(), defaultMimeType, m_url); + else if (m_url.isValid()) + adapter->load(m_url); else adapter->loadDefault(); } @@ -777,14 +797,21 @@ void QQuickWebEngineViewPrivate::initializationFinished() { Q_Q(QQuickWebEngineView); - if (m_backgroundColor != Qt::white) - adapter->backgroundColorChanged(); + Q_ASSERT(m_profileInitialized); + if (m_backgroundColor != Qt::white) { + adapter->setBackgroundColor(m_backgroundColor); + emit q->backgroundColorChanged(); + } + + if (!qFuzzyCompare(adapter->currentZoomFactor(), m_zoomFactor)) { + adapter->setZoomFactor(m_zoomFactor); + emit q->zoomFactorChanged(m_zoomFactor); + } + #if QT_CONFIG(webengine_webchannel) if (m_webChannel) adapter->setWebChannel(m_webChannel, m_webChannelWorld); #endif - if (!qFuzzyCompare(adapter->currentZoomFactor(), m_defaultZoomFactor)) - q->setZoomFactor(m_defaultZoomFactor); if (devToolsView && devToolsView->d_ptr->adapter) adapter->openDevToolsFrontend(devToolsView->d_ptr->adapter); @@ -855,20 +882,25 @@ void QQuickWebEngineViewPrivate::updateAction(QQuickWebEngineView::WebAction act QUrl QQuickWebEngineView::url() const { Q_D(const QQuickWebEngineView); - return d->explicitUrl.isValid() ? d->explicitUrl : d->adapter->activeUrl(); + if (d->adapter->isInitialized()) + return d->adapter->activeUrl(); + else + return d->m_url; } void QQuickWebEngineView::setUrl(const QUrl& url) { + Q_D(QQuickWebEngineView); if (url.isEmpty()) return; - Q_D(QQuickWebEngineView); - d->explicitUrl = url; - if (d->adapter->isInitialized()) + if (d->adapter->isInitialized()) { d->adapter->load(url); - if (!qmlEngine(this) || isComponentComplete()) - d->ensureContentsAdapter(); + return; + } + + d->m_url = url; + d->m_html.clear(); } QUrl QQuickWebEngineView::icon() const @@ -880,11 +912,12 @@ QUrl QQuickWebEngineView::icon() const void QQuickWebEngineView::loadHtml(const QString &html, const QUrl &baseUrl) { Q_D(QQuickWebEngineView); - d->explicitUrl = QUrl(); - if (!qmlEngine(this) || isComponentComplete()) - d->ensureContentsAdapter(); - if (d->adapter->isInitialized()) - d->adapter->setContent(html.toUtf8(), QStringLiteral("text/html;charset=UTF-8"), baseUrl); + d->m_url = baseUrl; + d->m_html = html; + if (d->adapter->isInitialized()) { + d->adapter->setContent(html.toUtf8(), defaultMimeType, baseUrl); + return; + } } void QQuickWebEngineView::goBack() @@ -920,31 +953,48 @@ void QQuickWebEngineView::stop() void QQuickWebEngineView::setZoomFactor(qreal arg) { Q_D(QQuickWebEngineView); - d->m_defaultZoomFactor = arg; - - qreal oldFactor = d->adapter->currentZoomFactor(); - d->adapter->setZoomFactor(arg); - if (qFuzzyCompare(oldFactor, d->adapter->currentZoomFactor())) - return; - - emit zoomFactorChanged(arg); + if (d->adapter->isInitialized() && !qFuzzyCompare(d->m_zoomFactor, d->adapter->currentZoomFactor())) { + d->adapter->setZoomFactor(arg); + emit zoomFactorChanged(arg); + } else { + d->m_zoomFactor = arg; + } } -QQuickWebEngineProfile *QQuickWebEngineView::profile() const +QQuickWebEngineProfile *QQuickWebEngineView::profile() { - Q_D(const QQuickWebEngineView); + Q_D(QQuickWebEngineView); + d->initializeProfile(); return d->m_profile; } void QQuickWebEngineView::setProfile(QQuickWebEngineProfile *profile) { Q_D(QQuickWebEngineView); - d->setProfile(profile); + + if (d->m_profile == profile) + return; + + if (!d->profileInitialized()) { + d->m_profile = profile; + return; + } + + if (d->m_profile) + d->m_profile->d_ptr->removeWebContentsAdapterClient(d); + + d->m_profile = profile; + d->m_profile->d_ptr->addWebContentsAdapterClient(d); + d->m_settings->setParentSettings(profile->settings()); + + d->updateAdapter(); + Q_EMIT profileChanged(); } -QQuickWebEngineSettings *QQuickWebEngineView::settings() const +QQuickWebEngineSettings *QQuickWebEngineView::settings() { - Q_D(const QQuickWebEngineView); + Q_D(QQuickWebEngineView); + d->initializeProfile(); return d->m_settings.data(); } @@ -958,32 +1008,22 @@ QQmlListProperty<QQuickWebEngineScript> QQuickWebEngineView::userScripts() d->userScripts_clear); } -void QQuickWebEngineViewPrivate::setProfile(QQuickWebEngineProfile *profile) +void QQuickWebEngineViewPrivate::updateAdapter() { - Q_Q(QQuickWebEngineView); - - if (profile == m_profile) - return; - m_profile->d_ptr->removeWebContentsAdapterClient(this); - m_profile = profile; - m_profile->d_ptr->addWebContentsAdapterClient(this); - Q_EMIT q->profileChanged(); - m_settings->setParentSettings(profile->settings()); - - if (adapter->profile() != profileAdapter()->profile()) { - // When the profile changes we need to create a new WebContentAdapter and reload the active URL. - bool wasInitialized = adapter->isInitialized(); - QUrl activeUrl = adapter->activeUrl(); - adapter = QSharedPointer<WebContentsAdapter>::create(); - adapter->setClient(this); - if (wasInitialized) { - if (explicitUrl.isValid()) - adapter->load(explicitUrl); - else if (activeUrl.isValid()) - adapter->load(activeUrl); - else - adapter->loadDefault(); - } + // When the profile changes we need to create a new WebContentAdapter and reload the active URL. + bool wasInitialized = adapter->isInitialized(); + QUrl activeUrl = adapter->activeUrl(); + adapter = QSharedPointer<WebContentsAdapter>::create(); + adapter->setClient(this); + if (wasInitialized) { + if (!m_html.isEmpty()) + adapter->setContent(m_html.toUtf8(), defaultMimeType, m_url); + else if (m_url.isValid()) + adapter->load(m_url); + else if (activeUrl.isValid()) + adapter->load(activeUrl); + else + adapter->loadDefault(); } } @@ -1148,7 +1188,7 @@ qreal QQuickWebEngineView::zoomFactor() const { Q_D(const QQuickWebEngineView); if (!d->adapter->isInitialized()) - return d->m_defaultZoomFactor; + return d->m_zoomFactor; return d->adapter->currentZoomFactor(); } @@ -1164,8 +1204,10 @@ void QQuickWebEngineView::setBackgroundColor(const QColor &color) if (color == d->m_backgroundColor) return; d->m_backgroundColor = color; - d->adapter->backgroundColorChanged(); - emit backgroundColorChanged(); + if (d->adapter->isInitialized()) { + d->adapter->setBackgroundColor(color); + emit backgroundColorChanged(); + } } /*! @@ -1281,9 +1323,7 @@ QQmlWebChannel *QQuickWebEngineView::webChannel() Q_D(QQuickWebEngineView); if (!d->m_webChannel) { d->m_webChannel = new QQmlWebChannel(this); - d->adapter->setWebChannel(d->m_webChannel, d->m_webChannelWorld); } - return d->m_webChannel; #endif qWarning("WebEngine compiled without webchannel support"); @@ -1297,7 +1337,8 @@ void QQuickWebEngineView::setWebChannel(QQmlWebChannel *webChannel) if (d->m_webChannel == webChannel) return; d->m_webChannel = webChannel; - d->adapter->setWebChannel(webChannel, d->m_webChannelWorld); + if (d->profileInitialized()) + d->adapter->setWebChannel(webChannel, d->m_webChannelWorld); Q_EMIT webChannelChanged(); #else Q_UNUSED(webChannel) @@ -1318,7 +1359,8 @@ void QQuickWebEngineView::setWebChannelWorld(uint webChannelWorld) if (d->m_webChannelWorld == webChannelWorld) return; d->m_webChannelWorld = webChannelWorld; - d->adapter->setWebChannel(d->m_webChannel, d->m_webChannelWorld); + if (d->profileInitialized()) + d->adapter->setWebChannel(d->m_webChannel, d->m_webChannelWorld); Q_EMIT webChannelWorldChanged(webChannelWorld); #else Q_UNUSED(webChannelWorld) @@ -1353,6 +1395,7 @@ QQuickWebEngineView *QQuickWebEngineView::devToolsView() const return d->devToolsView; } + void QQuickWebEngineView::setDevToolsView(QQuickWebEngineView *devToolsView) { Q_D(QQuickWebEngineView); @@ -1365,7 +1408,7 @@ void QQuickWebEngineView::setDevToolsView(QQuickWebEngineView *devToolsView) d->devToolsView = devToolsView; if (devToolsView) devToolsView->setInspectedView(this); - if (d->adapter->isInitialized()) { + if (d->profileInitialized() && d->adapter->isInitialized()) { if (devToolsView) d->adapter->openDevToolsFrontend(devToolsView->d_ptr->adapter); else @@ -1452,7 +1495,8 @@ void QQuickWebEngineView::geometryChanged(const QRectF &newGeometry, const QRect void QQuickWebEngineView::itemChange(ItemChange change, const ItemChangeData &value) { Q_D(QQuickWebEngineView); - if (d && d->adapter->isInitialized() && (change == ItemSceneChange || change == ItemVisibleHasChanged)) { + if (d && d->profileInitialized() && d->adapter->isInitialized() + && (change == ItemSceneChange || change == ItemVisibleHasChanged)) { if (window() && isVisible()) d->adapter->wasShown(); else @@ -1497,7 +1541,7 @@ void QQuickWebEngineView::dropEvent(QDropEvent *e) { Q_D(QQuickWebEngineView); e->accept(); - d->adapter->endDragging(e->pos(), mapToScreen(this, e->pos())); + d->adapter->endDragging(e, mapToScreen(this, e->pos())); } #endif // QT_CONFIG(draganddrop) @@ -1929,7 +1973,8 @@ void QQuickWebEngineViewPrivate::userScripts_clear(QQmlListProperty<QQuickWebEng void QQuickWebEngineView::componentComplete() { QQuickItem::componentComplete(); - + Q_D(QQuickWebEngineView); + d->initializeProfile(); #ifndef QT_NO_ACCESSIBILITY // Enable accessibility via a dynamic QQmlProperty, instead of using private API call // QQuickAccessibleAttached::qmlAttachedProperties(this). The qmlContext is required, otherwise |