summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJüri Valdmann <juri.valdmann@qt.io>2018-02-26 12:48:03 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-04-06 06:36:24 +0000
commit3bc5b9d4f9d481707c02e83e0cd20f60dec425f2 (patch)
treef29ba0036095fcf178133281be582d5fe650814b
parentfbfc9ee7f06c6f36b79145bc7e8ba05c5d3fa621 (diff)
Avoid creating temporary blank WebContents
- Avoid creating a blank WebContents for new QWebEnginePages only to replace it with a different blank WebContents moments later. This problem is already solved in QQuickWebEngineView by lazy initialization, therefore the patch moves this lazy initialization into WebContentsAdapter itself so that it can be applied to both QQuickWebEngineView and QWebEnginePage. - Try to delay WebContents creation until the first navigation so that we have enough information available to pick the right initial SiteInstance when calling WebContents::Create. This is done by triggering WebContents creation from the first call to a WebContentsAdapter::load* method. - Use the SiteInstance from WebContentsDelegate::OpenURLFromTab. This method gets a SiteInstance pointer which we should give to WebContents::Create. Task-number: QTBUG-65561 Task-number: QTBUG-67163 Change-Id: Id7b351998adefb810cf27c61a1447b61d7f4c606 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--src/core/web_contents_adapter.cpp160
-rw-r--r--src/core/web_contents_adapter.h24
-rw-r--r--src/core/web_contents_adapter_client.h1
-rw-r--r--src/core/web_contents_delegate_qt.cpp9
-rw-r--r--src/webengine/api/qquickwebenginehistory.cpp10
-rw-r--r--src/webengine/api/qquickwebengineview.cpp228
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h2
-rw-r--r--src/webenginewidgets/api/qwebenginehistory.cpp7
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp126
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h6
-rw-r--r--src/webenginewidgets/api/qwebenginescriptcollection.cpp45
-rw-r--r--src/webenginewidgets/api/qwebenginescriptcollection_p.h3
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp4
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp1
14 files changed, 395 insertions, 231 deletions
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 26ae9e3c5..95bdaba53 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -104,6 +104,10 @@
namespace QtWebEngineCore {
+#define CHECK_INITIALIZED(return_value) \
+ if (!isInitialized()) \
+ return return_value
+
#define CHECK_VALID_RENDER_WIDGET_HOST_VIEW(render_view_host) \
if (!render_view_host->IsRenderViewLive() && render_view_host->GetWidget()->GetView()) { \
qWarning("Ignore navigation due to terminated render process with invalid RenderWidgetHostView."); \
@@ -406,21 +410,39 @@ WebContentsAdapter::~WebContentsAdapter()
{
}
-void WebContentsAdapter::initialize(WebContentsAdapterClient *adapterClient)
+void WebContentsAdapter::setClient(WebContentsAdapterClient *adapterClient)
{
Q_D(WebContentsAdapter);
+ Q_ASSERT(!isInitialized());
d->adapterClient = adapterClient;
// We keep a reference to browserContextAdapter to keep it alive as long as we use it.
// This is needed in case the QML WebEngineProfile is garbage collected before the WebEnginePage.
d->browserContextAdapter = adapterClient->browserContextAdapter();
Q_ASSERT(d->browserContextAdapter);
- // Create our own if a WebContents wasn't provided at construction.
- if (!d->webContents)
- d->webContents.reset(createBlankWebContents(adapterClient, d->browserContextAdapter->browserContext()));
-
// This might replace any adapter that has been initialized with this WebEngineSettings.
adapterClient->webEngineSettings()->setWebContentsAdapter(this);
+}
+
+bool WebContentsAdapter::isInitialized() const
+{
+ Q_D(const WebContentsAdapter);
+ return bool(d->webContentsDelegate);
+}
+
+void WebContentsAdapter::initialize(content::SiteInstance *site)
+{
+ Q_D(WebContentsAdapter);
+ Q_ASSERT(d->adapterClient);
+ Q_ASSERT(!isInitialized());
+
+ // Create our own if a WebContents wasn't provided at construction.
+ if (!d->webContents) {
+ content::WebContents::CreateParams create_params(d->browserContextAdapter->browserContext(), site);
+ create_params.initial_size = gfx::Size(kTestWindowWidth, kTestWindowHeight);
+ create_params.context = reinterpret_cast<gfx::NativeView>(d->adapterClient);
+ d->webContents.reset(content::WebContents::Create(create_params));
+ }
content::RendererPreferences* rendererPrefs = d->webContents->GetMutableRendererPrefs();
rendererPrefs->use_custom_colors = true;
@@ -434,7 +456,7 @@ void WebContentsAdapter::initialize(WebContentsAdapterClient *adapterClient)
if (commandLine->HasSwitch(switches::kForceWebRtcIPHandlingPolicy))
rendererPrefs->webrtc_ip_handling_policy = commandLine->GetSwitchValueASCII(switches::kForceWebRtcIPHandlingPolicy);
else
- rendererPrefs->webrtc_ip_handling_policy = adapterClient->webEngineSettings()->testAttribute(WebEngineSettings::WebRTCPublicInterfacesOnly)
+ rendererPrefs->webrtc_ip_handling_policy = d->adapterClient->webEngineSettings()->testAttribute(WebEngineSettings::WebRTCPublicInterfacesOnly)
? content::kWebRTCIPHandlingDefaultPublicInterfaceOnly
: content::kWebRTCIPHandlingDefault;
#endif
@@ -450,12 +472,12 @@ void WebContentsAdapter::initialize(WebContentsAdapterClient *adapterClient)
d->webContents->GetRenderViewHost()->SyncRendererPrefs();
// Create and attach observers to the WebContents.
- d->webContentsDelegate.reset(new WebContentsDelegateQt(d->webContents.get(), adapterClient));
- d->renderViewObserverHost.reset(new RenderViewObserverHostQt(d->webContents.get(), adapterClient));
+ d->webContentsDelegate.reset(new WebContentsDelegateQt(d->webContents.get(), d->adapterClient));
+ d->renderViewObserverHost.reset(new RenderViewObserverHostQt(d->webContents.get(), d->adapterClient));
// Let the WebContent's view know about the WebContentsAdapterClient.
WebContentsViewQt* contentsView = static_cast<WebContentsViewQt*>(static_cast<content::WebContentsImpl*>(d->webContents.get())->GetView());
- contentsView->initialize(adapterClient);
+ contentsView->initialize(d->adapterClient);
// This should only be necessary after having restored the history to a new WebContentsAdapter.
d->webContents->GetController().LoadIfNecessary();
@@ -475,11 +497,14 @@ void WebContentsAdapter::initialize(WebContentsAdapterClient *adapterClient)
Q_ASSERT(rvh);
if (!rvh->IsRenderViewLive())
static_cast<content::WebContentsImpl*>(d->webContents.get())->CreateRenderViewForRenderManager(rvh, MSG_ROUTING_NONE, MSG_ROUTING_NONE, base::UnguessableToken::Create(), content::FrameReplicationState());
+
+ d->adapterClient->initializationFinished();
}
void WebContentsAdapter::reattachRWHV()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
if (content::RenderWidgetHostView *rwhv = d->webContents->GetRenderWidgetHostView())
rwhv->InitAsChild(0);
}
@@ -487,18 +512,21 @@ void WebContentsAdapter::reattachRWHV()
bool WebContentsAdapter::canGoBack() const
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED(false);
return d->webContents->GetController().CanGoBack();
}
bool WebContentsAdapter::canGoForward() const
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED(false);
return d->webContents->GetController().CanGoForward();
}
void WebContentsAdapter::stop()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
content::NavigationController& controller = d->webContents->GetController();
int index = controller.GetPendingEntryIndex();
@@ -512,6 +540,7 @@ void WebContentsAdapter::stop()
void WebContentsAdapter::reload()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
CHECK_VALID_RENDER_WIDGET_HOST_VIEW(d->webContents->GetRenderViewHost());
d->webContents->GetController().Reload(content::ReloadType::NORMAL, /*checkRepost = */false);
focusIfNecessary();
@@ -520,11 +549,18 @@ void WebContentsAdapter::reload()
void WebContentsAdapter::reloadAndBypassCache()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
CHECK_VALID_RENDER_WIDGET_HOST_VIEW(d->webContents->GetRenderViewHost());
d->webContents->GetController().Reload(content::ReloadType::BYPASSING_CACHE, /*checkRepost = */false);
focusIfNecessary();
}
+void WebContentsAdapter::loadDefault()
+{
+ Q_ASSERT(!isInitialized());
+ initialize(nullptr);
+}
+
void WebContentsAdapter::load(const QUrl &url)
{
QWebEngineHttpRequest request(url);
@@ -534,6 +570,14 @@ void WebContentsAdapter::load(const QUrl &url)
void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
{
Q_D(WebContentsAdapter);
+
+ GURL gurl = toGurl(request.url());
+ if (!isInitialized()) {
+ scoped_refptr<content::SiteInstance> site =
+ content::SiteInstance::CreateForURL(d->browserContextAdapter->browserContext(), gurl);
+ initialize(site.get());
+ }
+
CHECK_VALID_RENDER_WIDGET_HOST_VIEW(d->webContents->GetRenderViewHost());
// The situation can occur when relying on the editingFinished signal in QML to set the url
@@ -549,8 +593,6 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
LoadRecursionGuard guard(this);
Q_UNUSED(guard);
- GURL gurl = toGurl(request.url());
-
// Add URL scheme if missing from view-source URL.
if (request.url().scheme() == content::kViewSourceScheme) {
QUrl pageUrl = QUrl(request.url().toString().remove(0,
@@ -625,6 +667,10 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl)
{
Q_D(WebContentsAdapter);
+
+ if (!isInitialized())
+ loadDefault();
+
CHECK_VALID_RENDER_WIDGET_HOST_VIEW(d->webContents->GetRenderViewHost());
QByteArray encodedData = data.toPercentEncoding();
@@ -655,6 +701,7 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT
void WebContentsAdapter::save(const QString &filePath, int savePageFormat)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContentsDelegate->setSavePageInfo(SavePageInfo(filePath, savePageFormat));
d->webContents->OnSavePage();
}
@@ -662,23 +709,23 @@ void WebContentsAdapter::save(const QString &filePath, int savePageFormat)
QUrl WebContentsAdapter::activeUrl() const
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED(QUrl());
return d->webContentsDelegate->url();
}
QUrl WebContentsAdapter::requestedUrl() const
{
Q_D(const WebContentsAdapter);
- if (d->webContents) {
- content::NavigationEntry* entry = d->webContents->GetController().GetVisibleEntry();
- content::NavigationEntry* pendingEntry = d->webContents->GetController().GetPendingEntry();
+ CHECK_INITIALIZED(QUrl());
+ content::NavigationEntry* entry = d->webContents->GetController().GetVisibleEntry();
+ content::NavigationEntry* pendingEntry = d->webContents->GetController().GetPendingEntry();
- if (entry) {
- if (!entry->GetOriginalRequestURL().is_empty())
- return toQt(entry->GetOriginalRequestURL());
+ if (entry) {
+ if (!entry->GetOriginalRequestURL().is_empty())
+ return toQt(entry->GetOriginalRequestURL());
- if (pendingEntry && pendingEntry == entry)
- return toQt(entry->GetURL());
- }
+ if (pendingEntry && pendingEntry == entry)
+ return toQt(entry->GetURL());
}
return QUrl();
}
@@ -686,6 +733,7 @@ QUrl WebContentsAdapter::requestedUrl() const
QUrl WebContentsAdapter::iconUrl() const
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED(QUrl());
if (content::NavigationEntry* entry = d->webContents->GetController().GetVisibleEntry()) {
content::FaviconStatus favicon = entry->GetFavicon();
if (favicon.valid)
@@ -697,12 +745,14 @@ QUrl WebContentsAdapter::iconUrl() const
QString WebContentsAdapter::pageTitle() const
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED(QString());
return d->webContentsDelegate->title();
}
QString WebContentsAdapter::selectedText() const
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED(QString());
if (auto *rwhv = d->webContents->GetRenderWidgetHostView())
return toQt(rwhv->GetSelectedText());
return QString();
@@ -711,60 +761,70 @@ QString WebContentsAdapter::selectedText() const
void WebContentsAdapter::undo()
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContents->Undo();
}
void WebContentsAdapter::redo()
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContents->Redo();
}
void WebContentsAdapter::cut()
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContents->Cut();
}
void WebContentsAdapter::copy()
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContents->Copy();
}
void WebContentsAdapter::paste()
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContents->Paste();
}
void WebContentsAdapter::pasteAndMatchStyle()
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContents->PasteAndMatchStyle();
}
void WebContentsAdapter::selectAll()
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContents->SelectAll();
}
void WebContentsAdapter::requestClose()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContents->DispatchBeforeUnload();
}
void WebContentsAdapter::unselect()
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContents->CollapseSelection();
}
void WebContentsAdapter::navigateToIndex(int offset)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
CHECK_VALID_RENDER_WIDGET_HOST_VIEW(d->webContents->GetRenderViewHost());
d->webContents->GetController().GoToIndex(offset);
focusIfNecessary();
@@ -773,6 +833,7 @@ void WebContentsAdapter::navigateToIndex(int offset)
void WebContentsAdapter::navigateToOffset(int offset)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
CHECK_VALID_RENDER_WIDGET_HOST_VIEW(d->webContents->GetRenderViewHost());
d->webContents->GetController().GoToOffset(offset);
focusIfNecessary();
@@ -781,18 +842,21 @@ void WebContentsAdapter::navigateToOffset(int offset)
int WebContentsAdapter::navigationEntryCount()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED(0);
return d->webContents->GetController().GetEntryCount();
}
int WebContentsAdapter::currentNavigationEntryIndex()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED(0);
return d->webContents->GetController().GetCurrentEntryIndex();
}
QUrl WebContentsAdapter::getNavigationEntryOriginalUrl(int index)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED(QUrl());
content::NavigationEntry *entry = d->webContents->GetController().GetEntryAtIndex(index);
return entry ? toQt(entry->GetOriginalRequestURL()) : QUrl();
}
@@ -800,6 +864,7 @@ QUrl WebContentsAdapter::getNavigationEntryOriginalUrl(int index)
QUrl WebContentsAdapter::getNavigationEntryUrl(int index)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED(QUrl());
content::NavigationEntry *entry = d->webContents->GetController().GetEntryAtIndex(index);
return entry ? toQt(entry->GetURL()) : QUrl();
}
@@ -807,6 +872,7 @@ QUrl WebContentsAdapter::getNavigationEntryUrl(int index)
QString WebContentsAdapter::getNavigationEntryTitle(int index)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED(QString());
content::NavigationEntry *entry = d->webContents->GetController().GetEntryAtIndex(index);
return entry ? toQt(entry->GetTitle()) : QString();
}
@@ -814,6 +880,7 @@ QString WebContentsAdapter::getNavigationEntryTitle(int index)
QDateTime WebContentsAdapter::getNavigationEntryTimestamp(int index)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED(QDateTime());
content::NavigationEntry *entry = d->webContents->GetController().GetEntryAtIndex(index);
return entry ? toQt(entry->GetTimestamp()) : QDateTime();
}
@@ -821,6 +888,7 @@ QDateTime WebContentsAdapter::getNavigationEntryTimestamp(int index)
QUrl WebContentsAdapter::getNavigationEntryIconUrl(int index)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED(QUrl());
content::NavigationEntry *entry = d->webContents->GetController().GetEntryAtIndex(index);
if (!entry)
return QUrl();
@@ -831,6 +899,7 @@ QUrl WebContentsAdapter::getNavigationEntryIconUrl(int index)
void WebContentsAdapter::clearNavigationHistory()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
if (d->webContents->GetController().CanPruneAllButLastCommitted())
d->webContents->GetController().PruneAllButLastCommitted();
}
@@ -838,12 +907,14 @@ void WebContentsAdapter::clearNavigationHistory()
void WebContentsAdapter::serializeNavigationHistory(QDataStream &output)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
QtWebEngineCore::serializeNavigationHistory(d->webContents->GetController(), output);
}
void WebContentsAdapter::setZoomFactor(qreal factor)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
if (factor < content::kMinimumZoomFactor || factor > content::kMaximumZoomFactor)
return;
@@ -860,6 +931,7 @@ void WebContentsAdapter::setZoomFactor(qreal factor)
qreal WebContentsAdapter::currentZoomFactor() const
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED(1);
return content::ZoomLevelToZoomFactor(content::HostZoomMap::GetZoomLevel(d->webContents.get()));
}
@@ -879,6 +951,7 @@ BrowserContextAdapter* WebContentsAdapter::browserContextAdapter()
QAccessibleInterface *WebContentsAdapter::browserAccessible()
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED(nullptr);
content::RenderViewHost *rvh = d->webContents->GetRenderViewHost();
Q_ASSERT(rvh);
content::BrowserAccessibilityManager *manager = static_cast<content::RenderFrameHostImpl*>(rvh->GetMainFrame())->GetOrCreateBrowserAccessibilityManager();
@@ -893,6 +966,7 @@ QAccessibleInterface *WebContentsAdapter::browserAccessible()
void WebContentsAdapter::runJavaScript(const QString &javaScript, quint32 worldId)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
content::RenderViewHost *rvh = d->webContents->GetRenderViewHost();
Q_ASSERT(rvh);
if (worldId == 0) {
@@ -907,6 +981,7 @@ void WebContentsAdapter::runJavaScript(const QString &javaScript, quint32 worldI
quint64 WebContentsAdapter::runJavaScriptCallbackResult(const QString &javaScript, quint32 worldId)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED(0);
content::RenderViewHost *rvh = d->webContents->GetRenderViewHost();
Q_ASSERT(rvh);
content::RenderFrameHost::JavaScriptResultCallback callback = base::Bind(&callbackOnEvaluateJS, d->adapterClient, d->nextRequestId);
@@ -920,6 +995,7 @@ quint64 WebContentsAdapter::runJavaScriptCallbackResult(const QString &javaScrip
quint64 WebContentsAdapter::fetchDocumentMarkup()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED(0);
d->renderViewObserverHost->fetchDocumentMarkup(d->nextRequestId);
return d->nextRequestId++;
}
@@ -927,6 +1003,7 @@ quint64 WebContentsAdapter::fetchDocumentMarkup()
quint64 WebContentsAdapter::fetchDocumentInnerText()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED(0);
d->renderViewObserverHost->fetchDocumentInnerText(d->nextRequestId);
return d->nextRequestId++;
}
@@ -934,6 +1011,7 @@ quint64 WebContentsAdapter::fetchDocumentInnerText()
quint64 WebContentsAdapter::findText(const QString &subString, bool caseSensitively, bool findBackward)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED(0);
if (d->lastFindRequestId > d->webContentsDelegate->lastReceivedFindReply()) {
// There are cases where the render process will overwrite a previous request
// with the new search and we'll have a dangling callback, leaving the application
@@ -960,6 +1038,7 @@ quint64 WebContentsAdapter::findText(const QString &subString, bool caseSensitiv
void WebContentsAdapter::stopFinding()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContentsDelegate->setLastSearchedString(QString());
d->webContents->StopFinding(content::STOP_FIND_ACTION_KEEP_SELECTION);
}
@@ -967,6 +1046,7 @@ void WebContentsAdapter::stopFinding()
void WebContentsAdapter::updateWebPreferences(const content::WebPreferences & webPreferences)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContents->GetRenderViewHost()->UpdateWebkitPreferences(webPreferences);
}
@@ -975,6 +1055,7 @@ void WebContentsAdapter::download(const QUrl &url, const QString &suggestedFileN
ReferrerPolicy referrerPolicy)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
content::BrowserContext *bctx = webContents()->GetBrowserContext();
content::DownloadManager *dlm = content::BrowserContext::GetDownloadManager(bctx);
DownloadManagerDelegateQt *dlmd = d->browserContextAdapter->downloadManagerDelegate();
@@ -1021,24 +1102,28 @@ void WebContentsAdapter::download(const QUrl &url, const QString &suggestedFileN
bool WebContentsAdapter::isAudioMuted() const
{
const Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED(false);
return d->webContents->IsAudioMuted();
}
void WebContentsAdapter::setAudioMuted(bool muted)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContents->SetAudioMuted(muted);
}
bool WebContentsAdapter::recentlyAudible()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED(false);
return d->webContents->WasRecentlyAudible();
}
void WebContentsAdapter::copyImageAt(const QPoint &location)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContents->GetRenderViewHost()->GetMainFrame()->CopyImageAt(location.x(), location.y());
}
@@ -1051,6 +1136,7 @@ ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerControls, blink::WebMediaPlay
void WebContentsAdapter::executeMediaPlayerActionAt(const QPoint &location, MediaPlayerAction action, bool enable)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
blink::WebMediaPlayerAction blinkAction((blink::WebMediaPlayerAction::Type)action, enable);
d->webContents->GetRenderViewHost()->ExecuteMediaPlayerActionAtLocation(toGfx(location), blinkAction);
}
@@ -1058,6 +1144,7 @@ void WebContentsAdapter::executeMediaPlayerActionAt(const QPoint &location, Medi
void WebContentsAdapter::inspectElementAt(const QPoint &location)
{
Q_D(WebContentsAdapter);
+ Q_ASSERT(isInitialized());
if (d->devToolsFrontend) {
d->devToolsFrontend->InspectElementAt(location.x(), location.y());
return;
@@ -1069,6 +1156,7 @@ void WebContentsAdapter::inspectElementAt(const QPoint &location)
bool WebContentsAdapter::hasInspector() const
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED(false);
if (d->devToolsFrontend)
return true;
if (content::DevToolsAgentHost::HasFor(d->webContents.get()))
@@ -1079,6 +1167,7 @@ bool WebContentsAdapter::hasInspector() const
void WebContentsAdapter::openDevToolsFrontend(QSharedPointer<WebContentsAdapter> frontendAdapter)
{
Q_D(WebContentsAdapter);
+ Q_ASSERT(isInitialized());
if (d->devToolsFrontend &&
d->devToolsFrontend->frontendDelegate() == frontendAdapter->webContents()->GetDelegate())
return;
@@ -1094,6 +1183,7 @@ void WebContentsAdapter::openDevToolsFrontend(QSharedPointer<WebContentsAdapter>
void WebContentsAdapter::closeDevToolsFrontend()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
if (d->devToolsFrontend) {
d->devToolsFrontend->DisconnectFromTarget();
d->devToolsFrontend->Close();
@@ -1103,6 +1193,7 @@ void WebContentsAdapter::closeDevToolsFrontend()
void WebContentsAdapter::devToolsFrontendDestroyed(DevToolsFrontendQt *frontend)
{
Q_D(WebContentsAdapter);
+ Q_ASSERT(isInitialized());
Q_ASSERT(frontend == d->devToolsFrontend);
Q_UNUSED(frontend);
d->devToolsFrontend = nullptr;
@@ -1111,24 +1202,28 @@ void WebContentsAdapter::devToolsFrontendDestroyed(DevToolsFrontendQt *frontend)
void WebContentsAdapter::exitFullScreen()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContents->ExitFullscreen(false);
}
void WebContentsAdapter::changedFullScreen()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContents->NotifyFullscreenChanged(false);
}
void WebContentsAdapter::wasShown()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContents->WasShown();
}
void WebContentsAdapter::wasHidden()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContents->WasHidden();
}
@@ -1136,6 +1231,7 @@ void WebContentsAdapter::printToPDF(const QPageLayout &pageLayout, const QString
{
#if BUILDFLAG(ENABLE_BASIC_PRINTING)
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
PrintViewManagerQt::PrintToPDFFileCallback callback = base::Bind(&callbackOnPdfSavingFinished,
d->adapterClient,
filePath);
@@ -1152,6 +1248,7 @@ quint64 WebContentsAdapter::printToPDFCallbackResult(const QPageLayout &pageLayo
{
#if BUILDFLAG(ENABLE_BASIC_PRINTING)
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED(0);
PrintViewManagerQt::PrintToPDFCallback callback = base::Bind(&callbackOnPrintingFinished,
d->adapterClient,
d->nextRequestId);
@@ -1170,6 +1267,7 @@ quint64 WebContentsAdapter::printToPDFCallbackResult(const QPageLayout &pageLayo
QPointF WebContentsAdapter::lastScrollOffset() const
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED(QPointF());
if (content::RenderWidgetHostView *rwhv = d->webContents->GetRenderWidgetHostView())
return toQt(rwhv->GetLastScrollOffset());
return QPointF();
@@ -1178,6 +1276,7 @@ QPointF WebContentsAdapter::lastScrollOffset() const
QSizeF WebContentsAdapter::lastContentsSize() const
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED(QSizeF());
if (RenderWidgetHostViewQt *rwhv = static_cast<RenderWidgetHostViewQt *>(d->webContents->GetRenderWidgetHostView()))
return toQt(rwhv->lastContentsSize());
return QSizeF();
@@ -1186,6 +1285,7 @@ QSizeF WebContentsAdapter::lastContentsSize() const
void WebContentsAdapter::grantMediaAccessPermission(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags flags)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
// Let the permission manager remember the reply.
if (flags & WebContentsAdapterClient::MediaAudioCapture)
d->browserContextAdapter->permissionRequestReply(securityOrigin, BrowserContextAdapter::AudioCapturePermission, true);
@@ -1197,12 +1297,14 @@ void WebContentsAdapter::grantMediaAccessPermission(const QUrl &securityOrigin,
void WebContentsAdapter::runGeolocationRequestCallback(const QUrl &securityOrigin, bool allowed)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
d->browserContextAdapter->permissionRequestReply(securityOrigin, BrowserContextAdapter::GeolocationPermission, allowed);
}
void WebContentsAdapter::grantMouseLockPermission(bool granted)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
if (granted) {
if (RenderWidgetHostViewQt *rwhv = static_cast<RenderWidgetHostViewQt *>(d->webContents->GetRenderWidgetHostView()))
@@ -1217,6 +1319,7 @@ void WebContentsAdapter::grantMouseLockPermission(bool granted)
void WebContentsAdapter::dpiScaleChanged()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
content::RenderWidgetHostImpl* impl = NULL;
if (d->webContents->GetRenderViewHost())
impl = content::RenderWidgetHostImpl::From(d->webContents->GetRenderViewHost()->GetWidget());
@@ -1227,6 +1330,7 @@ void WebContentsAdapter::dpiScaleChanged()
void WebContentsAdapter::backgroundColorChanged()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
if (content::RenderWidgetHostView *rwhv = d->webContents->GetRenderWidgetHostView())
rwhv->SetBackgroundColor(toSk(d->adapterClient->backgroundColor()));
}
@@ -1246,6 +1350,7 @@ QWebChannel *WebContentsAdapter::webChannel() const
void WebContentsAdapter::setWebChannel(QWebChannel *channel, uint worldId)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
if (d->webChannel == channel && d->webChannelWorld == worldId)
return;
@@ -1260,6 +1365,7 @@ void WebContentsAdapter::setWebChannel(QWebChannel *channel, uint worldId)
d->webChannel = channel;
d->webChannelWorld = worldId;
+
if (!channel) {
d->webChannelTransport.reset();
return;
@@ -1301,6 +1407,7 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD
const QPoint &offset)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
if (d->currentDropData)
return;
@@ -1353,6 +1460,7 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD
bool WebContentsAdapter::handleDropDataFileContents(const content::DropData &dropData,
QMimeData *mimeData)
{
+ CHECK_INITIALIZED(false);
if (dropData.file_contents.empty())
return false;
@@ -1409,6 +1517,7 @@ static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeDat
void WebContentsAdapter::enterDrag(QDragEnterEvent *e, const QPointF &screenPos)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
if (!d->currentDropData) {
// The drag originated outside the WebEngineView.
@@ -1463,6 +1572,7 @@ static int toWeb(Qt::KeyboardModifiers modifiers)
Qt::DropAction WebContentsAdapter::updateDragPosition(QDragMoveEvent *e, const QPointF &screenPos)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED(Qt::DropAction());
content::RenderViewHost *rvh = d->webContents->GetRenderViewHost();
d->lastDragClientPos = toGfx(e->posF());
d->lastDragScreenPos = toGfx(screenPos);
@@ -1475,6 +1585,7 @@ Qt::DropAction WebContentsAdapter::updateDragPosition(QDragMoveEvent *e, const Q
void WebContentsAdapter::waitForUpdateDragActionCalled()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
const qint64 timeout = 3000;
QElapsedTimer t;
t.start();
@@ -1497,6 +1608,7 @@ void WebContentsAdapter::waitForUpdateDragActionCalled()
void WebContentsAdapter::updateDragAction(int action)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
d->updateDragActionCalled = true;
d->currentDropAction = static_cast<blink::WebDragOperation>(action);
}
@@ -1504,6 +1616,7 @@ void WebContentsAdapter::updateDragAction(int action)
void WebContentsAdapter::endDragging(const QPointF &clientPos, const QPointF &screenPos)
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
content::RenderViewHost *rvh = d->webContents->GetRenderViewHost();
rvh->GetWidget()->FilterDropData(d->currentDropData.get());
d->lastDragClientPos = toGfx(clientPos);
@@ -1515,6 +1628,7 @@ void WebContentsAdapter::endDragging(const QPointF &clientPos, const QPointF &sc
void WebContentsAdapter::leaveDrag()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
content::RenderViewHost *rvh = d->webContents->GetRenderViewHost();
rvh->GetWidget()->DragTargetDragLeave(d->lastDragClientPos, d->lastDragScreenPos);
d->currentDropData.reset();
@@ -1524,6 +1638,7 @@ void WebContentsAdapter::replaceMisspelling(const QString &word)
{
#if BUILDFLAG(ENABLE_SPELLCHECK)
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContents->ReplaceMisspelling(toString16(word));
#endif
}
@@ -1531,6 +1646,7 @@ void WebContentsAdapter::replaceMisspelling(const QString &word)
void WebContentsAdapter::focusIfNecessary()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
const WebEngineSettings *settings = d->adapterClient->webEngineSettings();
bool focusOnNavigation = settings->testAttribute(WebEngineSettings::FocusOnNavigationEnabled);
if (focusOnNavigation)
@@ -1540,6 +1656,7 @@ void WebContentsAdapter::focusIfNecessary()
bool WebContentsAdapter::isFindTextInProgress() const
{
Q_D(const WebContentsAdapter);
+ CHECK_INITIALIZED(false);
return d->lastFindRequestId != d->webContentsDelegate->lastReceivedFindReply();
}
@@ -1578,18 +1695,21 @@ WebContentsAdapterClient::renderProcessExitStatus(int terminationStatus) {
FaviconManager *WebContentsAdapter::faviconManager()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED(nullptr);
return d->webContentsDelegate->faviconManager();
}
void WebContentsAdapter::viewSource()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED();
d->webContents->GetMainFrame()->ViewSource();
}
bool WebContentsAdapter::canViewSource()
{
Q_D(WebContentsAdapter);
+ CHECK_INITIALIZED(false);
return d->webContents->GetController().CanViewSource();
}
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 54b07b4ff..f42dea394 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -52,6 +52,8 @@
namespace content {
class WebContents;
struct WebPreferences;
+struct OpenURLParams;
+class SiteInstance;
}
QT_BEGIN_NAMESPACE
@@ -78,7 +80,18 @@ public:
// Takes ownership of the WebContents.
WebContentsAdapter(content::WebContents *webContents = 0);
~WebContentsAdapter();
- void initialize(WebContentsAdapterClient *adapterClient);
+
+ void setClient(WebContentsAdapterClient *adapterClient);
+
+ bool isInitialized() const;
+
+ // These and only these methods will initialize the WebContentsAdapter. All
+ // other methods below will do nothing until one of these has been called.
+ void loadDefault();
+ void load(const QUrl &url);
+ void load(const QWebEngineHttpRequest &request);
+ void setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl);
+
void reattachRWHV();
bool canGoBack() const;
@@ -86,9 +99,6 @@ public:
void stop();
void reload();
void reloadAndBypassCache();
- void load(const QUrl &url);
- void load(const QWebEngineHttpRequest &request);
- void setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl);
void save(const QString &filePath = QString(), int savePageFormat = -1);
QUrl activeUrl() const;
QUrl requestedUrl() const;
@@ -183,15 +193,15 @@ public:
bool colorMode = true,
bool useCustomMargins = true);
- // meant to be used within WebEngineCore only
- content::WebContents *webContents() const;
void replaceMisspelling(const QString &word);
-
void viewSource();
bool canViewSource();
void focusIfNecessary();
bool isFindTextInProgress() const;
+ // meant to be used within WebEngineCore only
+ void initialize(content::SiteInstance *site);
+ content::WebContents *webContents() const;
private:
Q_DISABLE_COPY(WebContentsAdapter)
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 899678e56..248a963b1 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -395,6 +395,7 @@ public:
virtual RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client) = 0;
virtual RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegateForPopup(RenderWidgetHostViewQtDelegateClient *client) = 0;
+ virtual void initializationFinished() = 0;
virtual void titleChanged(const QString&) = 0;
virtual void urlChanged(const QUrl&) = 0;
virtual void iconChanged(const QUrl&) = 0;
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 4afbbe436..61aeda7bd 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -117,8 +117,11 @@ content::WebContents *WebContentsDelegateQt::OpenURLFromTab(content::WebContents
content::WebContents *target = source;
if (params.disposition != WindowOpenDisposition::CURRENT_TAB) {
QSharedPointer<WebContentsAdapter> targetAdapter = createWindow(0, params.disposition, gfx::Rect(), params.user_gesture);
- if (targetAdapter)
+ if (targetAdapter) {
+ if (!targetAdapter->isInitialized())
+ targetAdapter->initialize(params.source_site_instance.get());
target = targetAdapter->webContents();
+ }
}
Q_ASSERT(target);
@@ -211,7 +214,9 @@ void WebContentsDelegateQt::NavigationStateChanged(content::WebContents* source,
void WebContentsDelegateQt::AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture, bool* was_blocked)
{
Q_UNUSED(source)
- QWeakPointer<WebContentsAdapter> newAdapter = createWindow(new_contents, disposition, initial_pos, user_gesture);
+ QSharedPointer<WebContentsAdapter> newAdapter = createWindow(new_contents, disposition, initial_pos, user_gesture);
+ if (newAdapter && !newAdapter->isInitialized())
+ newAdapter->loadDefault();
if (was_blocked)
*was_blocked = !newAdapter;
}
diff --git a/src/webengine/api/qquickwebenginehistory.cpp b/src/webengine/api/qquickwebenginehistory.cpp
index 970bfb22d..d3c4a0026 100644
--- a/src/webengine/api/qquickwebenginehistory.cpp
+++ b/src/webengine/api/qquickwebenginehistory.cpp
@@ -58,8 +58,6 @@ QQuickWebEngineHistoryListModelPrivate::~QQuickWebEngineHistoryListModelPrivate(
int QQuickWebEngineHistoryListModelPrivate::count() const
{
- if (!adapter())
- return 0;
return adapter()->navigationEntryCount();
}
@@ -70,8 +68,6 @@ int QQuickWebEngineHistoryListModelPrivate::index(int index) const
int QQuickWebEngineHistoryListModelPrivate::offsetForIndex(int index) const
{
- if (!adapter())
- return index;
return index - adapter()->currentNavigationEntryIndex();
}
@@ -87,8 +83,6 @@ QQuickWebEngineBackHistoryListModelPrivate::QQuickWebEngineBackHistoryListModelP
int QQuickWebEngineBackHistoryListModelPrivate::count() const
{
- if (!adapter())
- return 0;
return adapter()->currentNavigationEntryIndex();
}
@@ -110,15 +104,13 @@ QQuickWebEngineForwardHistoryListModelPrivate::QQuickWebEngineForwardHistoryList
int QQuickWebEngineForwardHistoryListModelPrivate::count() const
{
- if (!adapter())
+ if (!adapter()->isInitialized())
return 0;
return adapter()->navigationEntryCount() - adapter()->currentNavigationEntryIndex() - 1;
}
int QQuickWebEngineForwardHistoryListModelPrivate::index(int i) const
{
- if (!adapter())
- return i + 1;
return adapter()->currentNavigationEntryIndex() + i + 1;
}
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 2fe146d4c..18c54c263 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -103,7 +103,7 @@ static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *obje
#endif // QT_NO_ACCESSIBILITY
QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
- : adapter(0)
+ : adapter(QSharedPointer<WebContentsAdapter>::create())
, m_history(new QQuickWebEngineHistory(this))
, m_profile(QQuickWebEngineProfile::defaultProfile())
, m_settings(new QQuickWebEngineSettings(m_profile->settings()))
@@ -119,6 +119,7 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
, devicePixelRatio(QGuiApplication::primaryScreen()->devicePixelRatio())
, m_webChannel(0)
, m_webChannelWorld(0)
+ , m_isBeingAdopted(false)
, m_dpiScale(1.0)
, m_backgroundColor(Qt::white)
, m_defaultZoomFactor(1.0)
@@ -226,7 +227,7 @@ void QQuickWebEngineViewPrivate::navigationRequested(int navigationType, const Q
Q_EMIT q->navigationRequested(&navigationRequest);
navigationRequestAction = navigationRequest.action();
- if ((navigationRequestAction == WebContentsAdapterClient::AcceptRequest) && adapter && adapter->isFindTextInProgress())
+ if ((navigationRequestAction == WebContentsAdapterClient::AcceptRequest) && adapter->isFindTextInProgress())
adapter->stopFinding();
}
@@ -705,47 +706,15 @@ void QQuickWebEngineViewPrivate::adoptWebContents(WebContentsAdapter *webContent
return;
}
- Q_Q(QQuickWebEngineView);
+ m_isBeingAdopted = true;
// This throws away the WebContentsAdapter that has been used until now.
// All its states, particularly the loading URL, are replaced by the adopted WebContentsAdapter.
- if (adapter) {
- WebContentsAdapterOwner *adapterOwner = new WebContentsAdapterOwner(adapter->sharedFromThis());
- adapterOwner->deleteLater();
- }
- adapter = webContents->sharedFromThis();
- adapter->initialize(this);
-
- // associate the webChannel with the new adapter
- if (m_webChannel)
- adapter->setWebChannel(m_webChannel, m_webChannelWorld);
-
- if (devToolsView && devToolsView->d_ptr->adapter)
- adapter->openDevToolsFrontend(devToolsView->d_ptr->adapter);
- else if (inspectedView && inspectedView->d_ptr->adapter)
- inspectedView->d_ptr->adapter->openDevToolsFrontend(adapter);
-
- // set initial background color if non-default
- if (m_backgroundColor != Qt::white)
- adapter->backgroundColorChanged();
-
- // re-bind the userscrips to the new adapter
- Q_FOREACH (QQuickWebEngineScript *script, m_userScripts)
- script->d_func()->bind(browserContextAdapter()->userResourceController(), adapter.data());
-
- // set the zoomFactor if it had been changed on the old adapter.
- if (!qFuzzyCompare(adapter->currentZoomFactor(), m_defaultZoomFactor))
- q->setZoomFactor(m_defaultZoomFactor);
+ WebContentsAdapterOwner *adapterOwner = new WebContentsAdapterOwner(adapter->sharedFromThis());
+ adapterOwner->deleteLater();
- // Emit signals for values that might be different from the previous WebContentsAdapter.
- emit q->titleChanged();
- emit q->urlChanged();
- emit q->iconChanged();
- // FIXME: The current loading state should be stored in the WebContentAdapter
- // and it should be checked here if the signal emission is really necessary.
- QQuickWebEngineLoadRequest loadRequest(adapter->activeUrl(), QQuickWebEngineView::LoadSucceededStatus);
- emit q->loadingChanged(&loadRequest);
- emit q->loadProgressChanged();
+ adapter = webContents->sharedFromThis();
+ adapter->setClient(this);
}
QQuickWebEngineView::QQuickWebEngineView(QQuickItem *parent)
@@ -754,6 +723,8 @@ QQuickWebEngineView::QQuickWebEngineView(QQuickItem *parent)
{
Q_D(QQuickWebEngineView);
d->q_ptr = this;
+ d->adapter->setClient(d);
+
this->setActiveFocusOnTab(true);
this->setFlags(QQuickItem::ItemIsFocusScope | QQuickItem::ItemAcceptsDrops);
}
@@ -761,36 +732,53 @@ QQuickWebEngineView::QQuickWebEngineView(QQuickItem *parent)
QQuickWebEngineView::~QQuickWebEngineView()
{
Q_D(QQuickWebEngineView);
- if (d->adapter)
- d->adapter->stopFinding();
+ d->adapter->stopFinding();
if (d->faviconProvider)
d->faviconProvider->detach(this);
}
void QQuickWebEngineViewPrivate::ensureContentsAdapter()
{
- Q_Q(QQuickWebEngineView);
- if (!adapter) {
- adapter = QSharedPointer<WebContentsAdapter>::create();
- adapter->initialize(this);
- if (m_backgroundColor != Qt::white)
- adapter->backgroundColorChanged();
- if (m_webChannel)
- adapter->setWebChannel(m_webChannel, m_webChannelWorld);
+ if (!adapter->isInitialized()) {
if (explicitUrl.isValid())
adapter->load(explicitUrl);
- if (inspectedView)
- inspectedView->d_ptr->adapter->openDevToolsFrontend(adapter);
- // push down the page's user scripts
- Q_FOREACH (QQuickWebEngineScript *script, m_userScripts)
- script->d_func()->bind(browserContextAdapter()->userResourceController(), adapter.data());
- // set the zoomFactor if it had been changed on the old adapter.
- if (!qFuzzyCompare(adapter->currentZoomFactor(), m_defaultZoomFactor))
- q->setZoomFactor(m_defaultZoomFactor);
-
+ else
+ adapter->loadDefault();
}
}
+void QQuickWebEngineViewPrivate::initializationFinished()
+{
+ Q_Q(QQuickWebEngineView);
+
+ if (m_backgroundColor != Qt::white)
+ adapter->backgroundColorChanged();
+ if (m_webChannel)
+ adapter->setWebChannel(m_webChannel, m_webChannelWorld);
+ if (!qFuzzyCompare(adapter->currentZoomFactor(), m_defaultZoomFactor))
+ q->setZoomFactor(m_defaultZoomFactor);
+ if (devToolsView && devToolsView->d_ptr->adapter)
+ adapter->openDevToolsFrontend(devToolsView->d_ptr->adapter);
+ else if (inspectedView && inspectedView->d_ptr->adapter)
+ inspectedView->d_ptr->adapter->openDevToolsFrontend(adapter);
+
+ Q_FOREACH (QQuickWebEngineScript *script, m_userScripts)
+ script->d_func()->bind(browserContextAdapter()->userResourceController(), adapter.data());
+
+ if (!m_isBeingAdopted)
+ return;
+
+ // Ideally these would only be emitted if something actually changed.
+ emit q->titleChanged();
+ emit q->urlChanged();
+ emit q->iconChanged();
+ QQuickWebEngineLoadRequest loadRequest(adapter->activeUrl(), QQuickWebEngineView::LoadSucceededStatus);
+ emit q->loadingChanged(&loadRequest);
+ emit q->loadProgressChanged();
+
+ m_isBeingAdopted = false;
+}
+
void QQuickWebEngineViewPrivate::setFullScreenMode(bool fullscreen)
{
Q_Q(QQuickWebEngineView);
@@ -804,7 +792,7 @@ void QQuickWebEngineViewPrivate::setFullScreenMode(bool fullscreen)
QUrl QQuickWebEngineView::url() const
{
Q_D(const QQuickWebEngineView);
- return d->explicitUrl.isValid() ? d->explicitUrl : (d->adapter ? d->adapter->activeUrl() : QUrl());
+ return d->explicitUrl.isValid() ? d->explicitUrl : d->adapter->activeUrl();
}
void QQuickWebEngineView::setUrl(const QUrl& url)
@@ -814,7 +802,7 @@ void QQuickWebEngineView::setUrl(const QUrl& url)
Q_D(QQuickWebEngineView);
d->explicitUrl = url;
- if (d->adapter)
+ if (d->adapter->isInitialized())
d->adapter->load(url);
if (!qmlEngine(this) || isComponentComplete())
d->ensureContentsAdapter();
@@ -832,47 +820,37 @@ void QQuickWebEngineView::loadHtml(const QString &html, const QUrl &baseUrl)
d->explicitUrl = QUrl();
if (!qmlEngine(this) || isComponentComplete())
d->ensureContentsAdapter();
- if (d->adapter)
+ if (d->adapter->isInitialized())
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();
}
@@ -881,9 +859,6 @@ void QQuickWebEngineView::setZoomFactor(qreal arg)
Q_D(QQuickWebEngineView);
d->m_defaultZoomFactor = arg;
- if (!d->adapter)
- return;
-
qreal oldFactor = d->adapter->currentZoomFactor();
d->adapter->setZoomFactor(arg);
if (qFuzzyCompare(oldFactor, d->adapter->currentZoomFactor()))
@@ -930,14 +905,20 @@ void QQuickWebEngineViewPrivate::setProfile(QQuickWebEngineProfile *profile)
Q_EMIT q->profileChanged();
m_settings->setParentSettings(profile->settings());
- if (adapter && adapter->browserContext() != browserContextAdapter()->browserContext()) {
+ if (adapter->browserContext() != browserContextAdapter()->browserContext()) {
// 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.reset();
- ensureContentsAdapter();
-
- if (!explicitUrl.isValid() && activeUrl.isValid())
- adapter->load(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();
+ }
}
}
@@ -1053,43 +1034,30 @@ 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);
- d->ensureContentsAdapter();
- if (!callback.isUndefined()) {
- quint64 requestId = d_ptr->adapter->runJavaScriptCallbackResult(script, QQuickWebEngineScript::MainWorld);
- d->m_callbacks.insert(requestId, callback);
- } else
- d->adapter->runJavaScript(script, QQuickWebEngineScript::MainWorld);
+ runJavaScript(script, QQuickWebEngineScript::MainWorld, callback);
}
void QQuickWebEngineView::runJavaScript(const QString &script, quint32 worldId, const QJSValue &callback)
{
Q_D(QQuickWebEngineView);
- if (!d->adapter)
- return;
+ d->ensureContentsAdapter();
if (!callback.isUndefined()) {
quint64 requestId = d_ptr->adapter->runJavaScriptCallbackResult(script, worldId);
d->m_callbacks.insert(requestId, callback);
@@ -1100,7 +1068,7 @@ void QQuickWebEngineView::runJavaScript(const QString &script, quint32 worldId,
qreal QQuickWebEngineView::zoomFactor() const
{
Q_D(const QQuickWebEngineView);
- if (!d->adapter)
+ if (!d->adapter->isInitialized())
return d->m_defaultZoomFactor;
return d->adapter->currentZoomFactor();
}
@@ -1117,8 +1085,7 @@ void QQuickWebEngineView::setBackgroundColor(const QColor &color)
if (color == d->m_backgroundColor)
return;
d->m_backgroundColor = color;
- if (d->adapter)
- d->adapter->backgroundColorChanged();
+ d->adapter->backgroundColorChanged();
emit backgroundColorChanged();
}
@@ -1132,39 +1099,32 @@ void QQuickWebEngineView::setBackgroundColor(const QColor &color)
bool QQuickWebEngineView::isAudioMuted() const
{
const Q_D(QQuickWebEngineView);
- if (d->adapter)
- return d->adapter->isAudioMuted();
- return false;
+ return d->adapter->isAudioMuted();
}
void QQuickWebEngineView::setAudioMuted(bool muted)
{
Q_D(QQuickWebEngineView);
- bool _isAudioMuted = isAudioMuted();
- if (d->adapter) {
- d->adapter->setAudioMuted(muted);
- if (_isAudioMuted != muted) {
- Q_EMIT audioMutedChanged(muted);
- }
- }
+ bool wasAudioMuted = d->adapter->isAudioMuted();
+ d->adapter->setAudioMuted(muted);
+ if (wasAudioMuted != d->adapter->isAudioMuted())
+ Q_EMIT audioMutedChanged(muted);
}
bool QQuickWebEngineView::recentlyAudible() const
{
const Q_D(QQuickWebEngineView);
- if (d->adapter)
- return d->adapter->recentlyAudible();
- return false;
+ return d->adapter->recentlyAudible();
}
void QQuickWebEngineView::printToPdf(const QString& filePath, PrintedPageSizeId pageSizeId, PrintedPageOrientation orientation)
{
#if defined(ENABLE_PDF)
- Q_D(const QQuickWebEngineView);
+ Q_D(QQuickWebEngineView);
QPageSize layoutSize(static_cast<QPageSize::PageSizeId>(pageSizeId));
QPageLayout::Orientation layoutOrientation = static_cast<QPageLayout::Orientation>(orientation);
QPageLayout pageLayout(layoutSize, layoutOrientation, QMarginsF(0.0, 0.0, 0.0, 0.0));
-
+ d->ensureContentsAdapter();
d->adapter->printToPDF(pageLayout, filePath);
#else
Q_UNUSED(filePath);
@@ -1184,6 +1144,7 @@ void QQuickWebEngineView::printToPdf(const QJSValue &callback, PrintedPageSizeId
if (callback.isUndefined())
return;
+ d->ensureContentsAdapter();
quint64 requestId = d->adapter->printToPDFCallbackResult(pageLayout);
d->m_callbacks.insert(requestId, callback);
#else
@@ -1213,7 +1174,7 @@ bool QQuickWebEngineView::isFullScreen() const
void QQuickWebEngineView::findText(const QString &subString, FindFlags options, const QJSValue &callback)
{
Q_D(QQuickWebEngineView);
- if (!d->adapter)
+ if (!d->adapter->isInitialized())
return;
if (subString.isEmpty()) {
d->adapter->stopFinding();
@@ -1240,8 +1201,7 @@ QQmlWebChannel *QQuickWebEngineView::webChannel()
Q_D(QQuickWebEngineView);
if (!d->m_webChannel) {
d->m_webChannel = new QQmlWebChannel(this);
- if (d->adapter)
- d->adapter->setWebChannel(d->m_webChannel, d->m_webChannelWorld);
+ d->adapter->setWebChannel(d->m_webChannel, d->m_webChannelWorld);
}
return d->m_webChannel;
@@ -1253,8 +1213,7 @@ void QQuickWebEngineView::setWebChannel(QQmlWebChannel *webChannel)
if (d->m_webChannel == webChannel)
return;
d->m_webChannel = webChannel;
- if (d->adapter)
- d->adapter->setWebChannel(webChannel, d->m_webChannelWorld);
+ d->adapter->setWebChannel(webChannel, d->m_webChannelWorld);
Q_EMIT webChannelChanged();
}
@@ -1270,8 +1229,7 @@ void QQuickWebEngineView::setWebChannelWorld(uint webChannelWorld)
if (d->m_webChannelWorld == webChannelWorld)
return;
d->m_webChannelWorld = webChannelWorld;
- if (d->adapter)
- d->adapter->setWebChannel(d->m_webChannel, d->m_webChannelWorld);
+ d->adapter->setWebChannel(d->m_webChannel, d->m_webChannelWorld);
Q_EMIT webChannelWorldChanged(webChannelWorld);
}
@@ -1314,19 +1272,15 @@ void QQuickWebEngineView::setDevToolsView(QQuickWebEngineView *devToolsView)
d->devToolsView = devToolsView;
if (devToolsView)
devToolsView->setInspectedView(this);
- if (d->adapter) {
- if (devToolsView)
- d->adapter->openDevToolsFrontend(devToolsView->d_ptr->adapter);
- else
- d->adapter->closeDevToolsFrontend();
- }
+ if (devToolsView)
+ d->adapter->openDevToolsFrontend(devToolsView->d_ptr->adapter);
+ else
+ d->adapter->closeDevToolsFrontend();
Q_EMIT devToolsViewChanged();
}
void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQuickWebEngineView::Feature feature, bool granted)
{
- if (!d_ptr->adapter)
- return;
if (!granted && ((feature >= MediaAudioCapture && feature <= MediaAudioVideoCapture) ||
(feature >= DesktopVideoCapture && feature <= DesktopAudioVideoCapture))) {
d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaNone);
@@ -1374,8 +1328,6 @@ void QQuickWebEngineView::setActiveFocusOnPress(bool arg)
void QQuickWebEngineView::goBackOrForward(int offset)
{
Q_D(QQuickWebEngineView);
- if (!d->adapter)
- return;
const int current = d->adapter->currentNavigationEntryIndex();
const int count = d->adapter->navigationEntryCount();
const int index = current + offset;
@@ -1404,7 +1356,7 @@ void QQuickWebEngineView::geometryChanged(const QRectF &newGeometry, const QRect
void QQuickWebEngineView::itemChange(ItemChange change, const ItemChangeData &value)
{
Q_D(QQuickWebEngineView);
- if (d->adapter && (change == ItemSceneChange || change == ItemVisibleHasChanged)) {
+ if (d->adapter->isInitialized() && (change == ItemSceneChange || change == ItemVisibleHasChanged)) {
if (window() && isVisible())
d->adapter->wasShown();
else
@@ -1666,16 +1618,12 @@ void QQuickWebEngineView::triggerWebAction(WebAction action)
QSizeF QQuickWebEngineView::contentsSize() const
{
Q_D(const QQuickWebEngineView);
- if (!d->adapter)
- return QSizeF();
return d->adapter->lastContentsSize();
}
QPointF QQuickWebEngineView::scrollPosition() const
{
Q_D(const QQuickWebEngineView);
- if (!d->adapter)
- return QPointF();
return d->adapter->lastScrollOffset();
}
@@ -1683,11 +1631,11 @@ void QQuickWebEngineViewPrivate::userScripts_append(QQmlListProperty<QQuickWebEn
{
Q_ASSERT(p && p->data);
QQuickWebEngineViewPrivate *d = static_cast<QQuickWebEngineViewPrivate*>(p->data);
- UserResourceControllerHost *resourceController = d->browserContextAdapter()->userResourceController();
d->m_userScripts.append(script);
- // If the adapter hasn't been instantiated, we'll bind the scripts in ensureContentsAdapter()
- if (!d->adapter)
+ // If the adapter hasn't been initialized, we'll bind the scripts in initializationFinished()
+ if (!d->adapter->isInitialized())
return;
+ UserResourceControllerHost *resourceController = d->browserContextAdapter()->userResourceController();
script->d_func()->bind(resourceController, d->adapter.data());
}
@@ -1709,9 +1657,11 @@ void QQuickWebEngineViewPrivate::userScripts_clear(QQmlListProperty<QQuickWebEng
{
Q_ASSERT(p && p->data);
QQuickWebEngineViewPrivate *d = static_cast<QQuickWebEngineViewPrivate*>(p->data);
+ d->m_userScripts.clear();
+ if (!d->adapter->isInitialized())
+ return;
UserResourceControllerHost *resourceController = d->browserContextAdapter()->userResourceController();
resourceController->clearAllScripts(d->adapter.data());
- d->m_userScripts.clear();
}
void QQuickWebEngineView::componentComplete()
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index 4b8617749..7369a63be 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -93,6 +93,7 @@ public:
QtWebEngineCore::RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override;
QtWebEngineCore::RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegateForPopup(QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override;
+ void initializationFinished() override;
void titleChanged(const QString&) override;
void urlChanged(const QUrl&) override;
void iconChanged(const QUrl&) override;
@@ -185,6 +186,7 @@ public:
QPointer<QQuickWebEngineView> inspectedView;
QPointer<QQuickWebEngineView> devToolsView;
uint m_webChannelWorld;
+ bool m_isBeingAdopted;
private:
QScopedPointer<QtWebEngineCore::UIDelegatesManager> m_uIDelegatesManager;
diff --git a/src/webenginewidgets/api/qwebenginehistory.cpp b/src/webenginewidgets/api/qwebenginehistory.cpp
index 48ddbc48e..34279b016 100644
--- a/src/webenginewidgets/api/qwebenginehistory.cpp
+++ b/src/webenginewidgets/api/qwebenginehistory.cpp
@@ -257,12 +257,17 @@ int QWebEngineHistory::currentItemIndex() const
int QWebEngineHistory::count() const
{
Q_D(const QWebEngineHistory);
+ if (!d->page->webContents()->isInitialized())
+ return 0;
return d->page->webContents()->navigationEntryCount();
}
QDataStream& operator<<(QDataStream& stream, const QWebEngineHistory& history)
{
- history.d_func()->page->webContents()->serializeNavigationHistory(stream);
+ QtWebEngineCore::WebContentsAdapter *adapter = history.d_func()->page->webContents();
+ if (!adapter->isInitialized())
+ adapter->loadDefault();
+ adapter->serializeNavigationHistory(stream);
return stream;
}
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 6b91bd221..1c42628ee 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -226,6 +226,8 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
, fullscreenMode(false)
, webChannel(nullptr)
, webChannelWorldId(QWebEngineScript::MainWorld)
+ , defaultAudioMuted(false)
+ , defaultZoomFactor(1.0)
#if defined(ENABLE_PRINTING)
, currentPrinter(nullptr)
#endif
@@ -234,6 +236,13 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
qRegisterMetaType<QWebEngineQuotaPermissionRequest>();
qRegisterMetaType<QWebEngineRegisterProtocolHandlerPermissionRequest>();
+
+ // See wasShown() and wasHidden().
+ wasShownTimer.setSingleShot(true);
+ QObject::connect(&wasShownTimer, &QTimer::timeout, [this](){
+ ensureInitialized();
+ wasShown();
+ });
}
QWebEnginePagePrivate::~QWebEnginePagePrivate()
@@ -256,6 +265,22 @@ RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostVie
return new RenderWidgetHostViewQtDelegateWidget(client, this->view);
}
+void QWebEnginePagePrivate::initializationFinished()
+{
+ if (m_backgroundColor != Qt::white)
+ adapter->backgroundColorChanged();
+ if (webChannel)
+ adapter->setWebChannel(webChannel, webChannelWorldId);
+ if (defaultAudioMuted != adapter->isAudioMuted())
+ adapter->setAudioMuted(defaultAudioMuted);
+ if (!qFuzzyCompare(adapter->currentZoomFactor(), defaultZoomFactor))
+ adapter->setZoomFactor(defaultZoomFactor);
+
+ scriptCollection.d->initializationFinished(adapter);
+
+ m_isBeingAdopted = false;
+}
+
void QWebEnginePagePrivate::titleChanged(const QString &title)
{
Q_Q(QWebEnginePage);
@@ -426,18 +451,10 @@ void QWebEnginePagePrivate::adoptNewWindowImpl(QWebEnginePage *newPage,
// Overwrite the new page's WebContents with ours.
newPage->d_func()->adapter = newWebContents;
- newWebContents->initialize(newPage->d_func());
- newPage->d_func()->scriptCollection.d->rebindToContents(newWebContents);
+ newWebContents->setClient(newPage->d_func());
+
if (!initialGeometry.isEmpty())
emit newPage->geometryChangeRequested(initialGeometry);
-
- // If the constructor of the QWebEnginePage descendant set a web channel,
- // set it on the new adapter.
- newWebContents->setWebChannel(newPage->d_func()->webChannel
- , newPage->d_func()->webChannelWorldId);
-
- // Page has finished the adoption process.
- newPage->d_func()->m_isBeingAdopted = false;
}
bool QWebEnginePagePrivate::isBeingAdopted()
@@ -599,6 +616,11 @@ void QWebEnginePagePrivate::updateAction(QWebEnginePage::WebAction action) const
if (!a)
return;
+ if (!adapter->isInitialized()) {
+ a->setEnabled(false);
+ return;
+ }
+
bool enabled = true;
switch (action) {
@@ -653,10 +675,8 @@ void QWebEnginePagePrivate::recreateFromSerializedHistory(QDataStream &input)
QSharedPointer<WebContentsAdapter> newWebContents = WebContentsAdapter::createFromSerializedNavigationHistory(input, this);
if (newWebContents) {
adapter = std::move(newWebContents);
- adapter->initialize(this);
- if (webChannel)
- adapter->setWebChannel(webChannel, webChannelWorldId);
- scriptCollection.d->rebindToContents(adapter);
+ adapter->setClient(this);
+ adapter->loadDefault();
}
}
@@ -687,6 +707,7 @@ QSharedPointer<BrowserContextAdapter> QWebEnginePagePrivate::browserContextAdapt
WebContentsAdapter *QWebEnginePagePrivate::webContentsAdapter()
{
+ ensureInitialized();
return adapter.data();
}
@@ -696,13 +717,19 @@ const QObject *QWebEnginePagePrivate::holdingQObject() const
return q;
}
+void QWebEnginePagePrivate::ensureInitialized() const
+{
+ if (!adapter->isInitialized())
+ adapter->loadDefault();
+}
+
QWebEnginePage::QWebEnginePage(QObject* parent)
: QObject(parent)
, d_ptr(new QWebEnginePagePrivate())
{
Q_D(QWebEnginePage);
d->q_ptr = this;
- d->adapter->initialize(d);
+ d->adapter->setClient(d);
}
/*!
@@ -849,15 +876,14 @@ QWebEnginePage::QWebEnginePage(QWebEngineProfile *profile, QObject* parent)
{
Q_D(QWebEnginePage);
d->q_ptr = this;
- d->adapter->initialize(d);
+ d->adapter->setClient(d);
}
QWebEnginePage::~QWebEnginePage()
{
Q_D(QWebEnginePage);
setDevToolsPage(nullptr);
- if (d->adapter)
- d->adapter->stopFinding();
+ d->adapter->stopFinding();
QWebEngineViewPrivate::bind(d->view, 0);
}
@@ -976,6 +1002,7 @@ void QWebEnginePage::save(const QString &filePath,
QWebEngineDownloadItem::SavePageFormat format) const
{
Q_D(const QWebEnginePage);
+ d->ensureInitialized();
d->adapter->save(filePath, format);
}
@@ -988,20 +1015,19 @@ void QWebEnginePage::save(const QString &filePath,
\sa recentlyAudible
*/
bool QWebEnginePage::isAudioMuted() const {
- const Q_D(QWebEnginePage);
- return d->adapter->isAudioMuted();
+ Q_D(const QWebEnginePage);
+ if (d->adapter->isInitialized())
+ return d->adapter->isAudioMuted();
+ return d->defaultAudioMuted;
}
void QWebEnginePage::setAudioMuted(bool muted) {
Q_D(QWebEnginePage);
- bool _isAudioMuted = isAudioMuted();
- d->adapter->setAudioMuted(muted);
- if (_isAudioMuted != muted) {
- Q_EMIT audioMutedChanged(muted);
- }
+ d->defaultAudioMuted = muted;
+ if (d->adapter->isInitialized())
+ d->adapter->setAudioMuted(muted);
}
-
/*!
\property QWebEnginePage::recentlyAudible
\brief the current page's \e {audible state}, that is, whether audio was recently played
@@ -1013,8 +1039,8 @@ void QWebEnginePage::setAudioMuted(bool muted) {
*/
bool QWebEnginePage::recentlyAudible() const
{
- const Q_D(QWebEnginePage);
- return d->adapter->recentlyAudible();
+ Q_D(const QWebEnginePage);
+ return d->adapter->isInitialized() && d->adapter->recentlyAudible();
}
void QWebEnginePage::setView(QWidget *view)
@@ -1225,6 +1251,7 @@ QAction *QWebEnginePage::action(WebAction action) const
void QWebEnginePage::triggerAction(WebAction action, bool)
{
Q_D(QWebEnginePage);
+ d->ensureInitialized();
const QtWebEngineCore::WebEngineContextMenuData &menuData = *d->contextData.d;
switch (action) {
case Back:
@@ -1471,6 +1498,10 @@ void QWebEnginePage::replaceMisspelledWord(const QString &replacement)
void QWebEnginePage::findText(const QString &subString, FindFlags options, const QWebEngineCallback<bool> &resultCallback)
{
Q_D(QWebEnginePage);
+ if (!d->adapter->isInitialized()) {
+ d->m_callbacks.invokeEmpty(resultCallback);
+ return;
+ }
if (subString.isEmpty()) {
d->adapter->stopFinding();
d->m_callbacks.invokeEmpty(resultCallback);
@@ -1490,11 +1521,26 @@ bool QWebEnginePage::event(QEvent *e)
void QWebEnginePagePrivate::wasShown()
{
+ if (!adapter->isInitialized()) {
+ // On the one hand, it is too early to initialize here. The application
+ // may call show() before load(), or it may call show() from
+ // createWindow(), and then we would create an unnecessary blank
+ // WebContents here. On the other hand, if the application calls show()
+ // then it expects something to be shown, so we have to initialize.
+ // Therefore we have to delay the initialization via the event loop.
+ wasShownTimer.start();
+ return;
+ }
adapter->wasShown();
}
void QWebEnginePagePrivate::wasHidden()
{
+ if (!adapter->isInitialized()) {
+ // Cancel timer from wasShown() above.
+ wasShownTimer.stop();
+ return;
+ }
adapter->wasHidden();
}
@@ -1534,7 +1580,7 @@ void QWebEnginePagePrivate::navigationRequested(int navigationType, const QUrl &
{
Q_Q(QWebEnginePage);
bool accepted = q->acceptNavigationRequest(url, static_cast<QWebEnginePage::NavigationType>(navigationType), isMainFrame);
- if (accepted && adapter && adapter->isFindTextInProgress())
+ if (accepted && adapter->isFindTextInProgress())
adapter->stopFinding();
navigationRequestAction = accepted ? WebContentsAdapterClient::AcceptRequest : WebContentsAdapterClient::IgnoreRequest;
}
@@ -1655,6 +1701,7 @@ QMenu *QWebEnginePage::createStandardContextMenu()
Q_D(QWebEnginePage);
if (!d->contextData.d)
return nullptr;
+ d->ensureInitialized();
QMenu *menu = new QMenu(d->view);
const WebEngineContextMenuData &contextMenuData = *d->contextData.d;
@@ -1767,6 +1814,7 @@ WebEngineSettings *QWebEnginePagePrivate::webEngineSettings() const
void QWebEnginePage::download(const QUrl& url, const QString& filename)
{
Q_D(QWebEnginePage);
+ d->ensureInitialized();
d->adapter->download(url, filename);
}
@@ -1791,6 +1839,7 @@ void QWebEnginePage::load(const QWebEngineHttpRequest& request)
void QWebEnginePage::toHtml(const QWebEngineCallback<const QString &> &resultCallback) const
{
Q_D(const QWebEnginePage);
+ d->ensureInitialized();
quint64 requestId = d->adapter->fetchDocumentMarkup();
d->m_callbacks.registerCallback(requestId, resultCallback);
}
@@ -1798,6 +1847,7 @@ void QWebEnginePage::toHtml(const QWebEngineCallback<const QString &> &resultCal
void QWebEnginePage::toPlainText(const QWebEngineCallback<const QString &> &resultCallback) const
{
Q_D(const QWebEnginePage);
+ d->ensureInitialized();
quint64 requestId = d->adapter->fetchDocumentInnerText();
d->m_callbacks.registerCallback(requestId, resultCallback);
}
@@ -1867,7 +1917,7 @@ QIcon QWebEnginePage::icon() const
{
Q_D(const QWebEnginePage);
- if (d->iconUrl.isEmpty())
+ if (d->iconUrl.isEmpty() || !d->adapter->isInitialized())
return QIcon();
return d->adapter->faviconManager()->getIcon();
@@ -1876,24 +1926,30 @@ QIcon QWebEnginePage::icon() const
qreal QWebEnginePage::zoomFactor() const
{
Q_D(const QWebEnginePage);
- return d->adapter->currentZoomFactor();
+ if (d->adapter->isInitialized())
+ return d->adapter->currentZoomFactor();
+ return d->defaultZoomFactor;
}
void QWebEnginePage::setZoomFactor(qreal factor)
{
Q_D(QWebEnginePage);
- d->adapter->setZoomFactor(factor);
+ d->defaultZoomFactor = factor;
+ if (d->adapter->isInitialized())
+ d->adapter->setZoomFactor(factor);
}
void QWebEnginePage::runJavaScript(const QString &scriptSource)
{
Q_D(QWebEnginePage);
+ d->ensureInitialized();
d->adapter->runJavaScript(scriptSource, QWebEngineScript::MainWorld);
}
void QWebEnginePage::runJavaScript(const QString& scriptSource, const QWebEngineCallback<const QVariant &> &resultCallback)
{
Q_D(QWebEnginePage);
+ d->ensureInitialized();
quint64 requestId = d->adapter->runJavaScriptCallbackResult(scriptSource, QWebEngineScript::MainWorld);
d->m_callbacks.registerCallback(requestId, resultCallback);
}
@@ -1901,12 +1957,14 @@ void QWebEnginePage::runJavaScript(const QString& scriptSource, const QWebEngine
void QWebEnginePage::runJavaScript(const QString &scriptSource, quint32 worldId)
{
Q_D(QWebEnginePage);
+ d->ensureInitialized();
d->adapter->runJavaScript(scriptSource, worldId);
}
void QWebEnginePage::runJavaScript(const QString& scriptSource, quint32 worldId, const QWebEngineCallback<const QVariant &> &resultCallback)
{
Q_D(QWebEnginePage);
+ d->ensureInitialized();
quint64 requestId = d->adapter->runJavaScriptCallbackResult(scriptSource, worldId);
d->m_callbacks.registerCallback(requestId, resultCallback);
}
@@ -2010,6 +2068,7 @@ void QWebEnginePage::setDevToolsPage(QWebEnginePage *devToolsPage)
Q_D(QWebEnginePage);
if (d->devToolsPage == devToolsPage)
return;
+ d->ensureInitialized();
QWebEnginePage *oldDevTools = d->devToolsPage;
d->devToolsPage = nullptr;
if (oldDevTools)
@@ -2152,6 +2211,7 @@ void QWebEnginePage::printToPdf(const QString &filePath, const QPageLayout &page
return;
}
#endif // ENABLE_PRINTING
+ d->ensureInitialized();
d->adapter->printToPDF(pageLayout, filePath);
#else
Q_UNUSED(filePath);
@@ -2181,6 +2241,7 @@ void QWebEnginePage::printToPdf(const QWebEngineCallback<const QByteArray&> &res
return;
}
#endif // ENABLE_PRINTING
+ d->ensureInitialized();
quint64 requestId = d->adapter->printToPDFCallbackResult(pageLayout);
d->m_callbacks.registerCallback(requestId, resultCallback);
#else // if defined(ENABLE_PDF)
@@ -2213,6 +2274,7 @@ void QWebEnginePage::print(QPrinter *printer, const QWebEngineCallback<bool> &re
}
d->currentPrinter = printer;
#endif // ENABLE_PRINTING
+ d->ensureInitialized();
quint64 requestId = d->adapter->printToPDFCallbackResult(printer->pageLayout(),
printer->colorMode() == QPrinter::Color,
false);
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 81caaf415..fd7928006 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -61,6 +61,7 @@
#include <QtCore/qcompilerdetection.h>
#include <QtCore/QPointer>
+#include <QtCore/QTimer>
namespace QtWebEngineCore {
class RenderWidgetHostViewQtDelegate;
@@ -87,6 +88,7 @@ public:
QtWebEngineCore::RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override;
QtWebEngineCore::RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegateForPopup(QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override { return CreateRenderWidgetHostViewQtDelegate(client); }
+ void initializationFinished() override;
void titleChanged(const QString&) override;
void urlChanged(const QUrl&) override;
void iconChanged(const QUrl&) override;
@@ -158,6 +160,7 @@ public:
void recreateFromSerializedHistory(QDataStream &input);
void setFullScreenMode(bool);
+ void ensureInitialized() const;
QSharedPointer<QtWebEngineCore::WebContentsAdapter> adapter;
QWebEngineHistory *history;
@@ -177,6 +180,9 @@ public:
bool m_navigationActionTriggered;
QPointer<QWebEnginePage> inspectedPage;
QPointer<QWebEnginePage> devToolsPage;
+ bool defaultAudioMuted;
+ qreal defaultZoomFactor;
+ QTimer wasShownTimer;
mutable QtWebEngineCore::CallbackDirectory m_callbacks;
mutable QAction *actions[QWebEnginePage::WebActionCount];
diff --git a/src/webenginewidgets/api/qwebenginescriptcollection.cpp b/src/webenginewidgets/api/qwebenginescriptcollection.cpp
index 8d393924f..bcf0c127c 100644
--- a/src/webenginewidgets/api/qwebenginescriptcollection.cpp
+++ b/src/webenginewidgets/api/qwebenginescriptcollection.cpp
@@ -175,63 +175,72 @@ QWebEngineScriptCollectionPrivate::QWebEngineScriptCollectionPrivate(QtWebEngine
int QWebEngineScriptCollectionPrivate::count() const
{
- return m_scriptController->registeredScripts(m_contents.data()).count();
+ return m_scripts.count();
}
bool QWebEngineScriptCollectionPrivate::contains(const QWebEngineScript &s) const
{
- return m_scriptController->containsUserScript(*s.d, m_contents.data());
+ return m_scripts.contains(s);
}
void QWebEngineScriptCollectionPrivate::insert(const QWebEngineScript &script)
{
- if (!script.d)
+ if (!script.d || script.d->isNull())
return;
- m_scriptController->addUserScript(*script.d, m_contents.data());
+ m_scripts.append(script);
+ if (!m_contents || m_contents->isInitialized())
+ m_scriptController->addUserScript(*script.d, m_contents.data());
}
bool QWebEngineScriptCollectionPrivate::remove(const QWebEngineScript &script)
{
- if (!script.d)
+ if (!script.d || script.d->isNull())
return false;
- return m_scriptController->removeUserScript(*script.d, m_contents.data());
+ if (!m_contents || m_contents->isInitialized())
+ m_scriptController->removeUserScript(*script.d, m_contents.data());
+ return m_scripts.removeAll(script);
}
QList<QWebEngineScript> QWebEngineScriptCollectionPrivate::toList(const QString &scriptName) const
{
+ if (scriptName.isNull())
+ return m_scripts;
+
QList<QWebEngineScript> ret;
- Q_FOREACH (const UserScript &script, m_scriptController->registeredScripts(m_contents.data()))
- if (scriptName.isNull() || scriptName == script.name())
- ret.append(QWebEngineScript(script));
+ Q_FOREACH (const QWebEngineScript &script, m_scripts)
+ if (scriptName == script.name())
+ ret.append(script);
return ret;
}
QWebEngineScript QWebEngineScriptCollectionPrivate::find(const QString &name) const
{
- Q_FOREACH (const UserScript &script, m_scriptController->registeredScripts(m_contents.data()))
+ Q_FOREACH (const QWebEngineScript &script, m_scripts)
if (name == script.name())
- return QWebEngineScript(script);
+ return script;
return QWebEngineScript();
}
void QWebEngineScriptCollectionPrivate::clear()
{
- m_scriptController->clearAllScripts(m_contents.data());
+ m_scripts.clear();
+ if (!m_contents || m_contents->isInitialized())
+ m_scriptController->clearAllScripts(m_contents.data());
}
void QWebEngineScriptCollectionPrivate::reserve(int capacity)
{
- m_scriptController->reserve(m_contents.data(), capacity);
+ m_scripts.reserve(capacity);
+ if (!m_contents || m_contents->isInitialized())
+ m_scriptController->reserve(m_contents.data(), capacity);
}
-void QWebEngineScriptCollectionPrivate::rebindToContents(QSharedPointer<QtWebEngineCore::WebContentsAdapter> contents)
+void QWebEngineScriptCollectionPrivate::initializationFinished(QSharedPointer<QtWebEngineCore::WebContentsAdapter> contents)
{
Q_ASSERT(m_contents);
Q_ASSERT(contents);
- Q_ASSERT(m_contents != contents);
- Q_FOREACH (const UserScript &script, m_scriptController->registeredScripts(m_contents.data())) {
- m_scriptController->addUserScript(script, contents.data());
- }
+ Q_FOREACH (const QWebEngineScript &script, m_scripts)
+ m_scriptController->addUserScript(*script.d, contents.data());
m_contents = contents;
}
diff --git a/src/webenginewidgets/api/qwebenginescriptcollection_p.h b/src/webenginewidgets/api/qwebenginescriptcollection_p.h
index fa4b4d790..322ade3b6 100644
--- a/src/webenginewidgets/api/qwebenginescriptcollection_p.h
+++ b/src/webenginewidgets/api/qwebenginescriptcollection_p.h
@@ -73,7 +73,7 @@ public:
QList<QWebEngineScript> toList(const QString &scriptName = QString()) const;
QWebEngineScript find(const QString & name) const;
- void rebindToContents(QSharedPointer<QtWebEngineCore::WebContentsAdapter> contents);
+ void initializationFinished(QSharedPointer<QtWebEngineCore::WebContentsAdapter> contents);
void insert(const QWebEngineScript &);
bool remove(const QWebEngineScript &);
@@ -83,6 +83,7 @@ public:
private:
QtWebEngineCore::UserResourceControllerHost *m_scriptController;
QSharedPointer<QtWebEngineCore::WebContentsAdapter> m_contents;
+ QList<QWebEngineScript> m_scripts;
};
QT_END_NAMESPACE
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 81877657b..18a33695a 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -3974,8 +3974,8 @@ void tst_QWebEnginePage::setZoomFactor()
const QUrl urlToLoad("qrc:/resources/test1.html");
- QSignalSpy finishedSpy(m_page, SIGNAL(loadFinished(bool)));
- m_page->setUrl(urlToLoad);
+ QSignalSpy finishedSpy(&page, SIGNAL(loadFinished(bool)));
+ page.load(urlToLoad);
QTRY_COMPARE(finishedSpy.count(), 1);
QVERIFY(finishedSpy.at(0).first().toBool());
QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index d58bfe0b3..207836bef 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -873,6 +873,7 @@ void tst_QWebEngineView::stopSettingFocusWhenDisabled()
QFETCH(bool, focusResult);
QWebEngineView webView;
+ webView.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
webView.resize(640, 480);
webView.show();
webView.setEnabled(viewEnabled);