summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);