From 4da1db8fb60b444dc112b41804a3ac7480197bd2 Mon Sep 17 00:00:00 2001 From: Pierre Rossi <pierre.rossi@digia.com> Date: Fri, 11 Apr 2014 18:46:40 +0200 Subject: [PATCH] Add a way of using UI dialogs for authorization We could use this to prompt the user for various feature permissions that we are not ready to expose in our API. Change-Id: If6e6a16aca4142b0564121dfc7677b7c4996f742 Reviewed-by: Zeno Albisser <zeno.albisser@digia.com> --- src/core/javascript_dialog_controller.cpp | 10 +++++-- src/core/javascript_dialog_controller.h | 1 + src/core/javascript_dialog_controller_p.h | 5 ++-- src/core/javascript_dialog_manager_qt.cpp | 33 ++++++++++++++------- src/core/javascript_dialog_manager_qt.h | 6 ++++ src/core/web_contents_adapter_client.h | 4 ++- src/webengine/ui_delegates_manager.cpp | 12 +++++--- src/webenginewidgets/api/qwebenginepage.cpp | 3 ++ 8 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/core/javascript_dialog_controller.cpp b/src/core/javascript_dialog_controller.cpp index 973fa89b7..c3c133a0d 100644 --- a/src/core/javascript_dialog_controller.cpp +++ b/src/core/javascript_dialog_controller.cpp @@ -54,12 +54,13 @@ void JavaScriptDialogControllerPrivate::dialogFinished(bool accepted, const base } JavaScriptDialogControllerPrivate::JavaScriptDialogControllerPrivate(WebContentsAdapterClient::JavascriptDialogType t, const QString &msg, const QString &prompt - , const QUrl &securityOrigin, const content::JavaScriptDialogManager::DialogClosedCallback &cb - , content::WebContents *c) + , const QString &title, const QUrl &securityOrigin + , const content::JavaScriptDialogManager::DialogClosedCallback &cb, content::WebContents *c) : type(t) , message(msg) , defaultPrompt(prompt) , securityOrigin(securityOrigin) + , title(title) , callback(cb) , contents(c) { @@ -79,6 +80,11 @@ QString JavaScriptDialogController::defaultPrompt() const return d->defaultPrompt; } +QString JavaScriptDialogController::title() const +{ + return d->title; +} + WebContentsAdapterClient::JavascriptDialogType JavaScriptDialogController::type() const { return d->type; diff --git a/src/core/javascript_dialog_controller.h b/src/core/javascript_dialog_controller.h index 755a2712b..25e711cb7 100644 --- a/src/core/javascript_dialog_controller.h +++ b/src/core/javascript_dialog_controller.h @@ -54,6 +54,7 @@ public: ~JavaScriptDialogController(); QString message() const; QString defaultPrompt() const; + QString title() const; WebContentsAdapterClient::JavascriptDialogType type() const; QUrl securityOrigin() const; diff --git a/src/core/javascript_dialog_controller_p.h b/src/core/javascript_dialog_controller_p.h index 0d7552ce2..ed51619d4 100644 --- a/src/core/javascript_dialog_controller_p.h +++ b/src/core/javascript_dialog_controller_p.h @@ -55,14 +55,15 @@ class JavaScriptDialogControllerPrivate { public: void dialogFinished(bool accepted, const base::string16 &promptValue); JavaScriptDialogControllerPrivate(WebContentsAdapterClient::JavascriptDialogType, const QString &message, const QString &prompt - , const QUrl &securityOrigin, const content::JavaScriptDialogManager::DialogClosedCallback & - , content::WebContents *); + , const QString& title, const QUrl &securityOrigin + , const content::JavaScriptDialogManager::DialogClosedCallback &, content::WebContents *); WebContentsAdapterClient::JavascriptDialogType type; QString message; QString defaultPrompt; QUrl securityOrigin; QString userInput; + QString title; content::JavaScriptDialogManager::DialogClosedCallback callback; content::WebContents *contents; }; diff --git a/src/core/javascript_dialog_manager_qt.cpp b/src/core/javascript_dialog_manager_qt.cpp index 1e37481b6..bd528af95 100644 --- a/src/core/javascript_dialog_manager_qt.cpp +++ b/src/core/javascript_dialog_manager_qt.cpp @@ -43,7 +43,6 @@ #include "javascript_dialog_controller.h" #include "javascript_dialog_controller_p.h" -#include "web_contents_adapter_client.h" #include "web_contents_view_qt.h" #include "type_conversion.h" @@ -62,20 +61,13 @@ void JavaScriptDialogManagerQt::RunJavaScriptDialog(content::WebContents *webCon WebContentsAdapterClient *client = WebContentsViewQt::from(webContents->GetView())->client(); if (!client) { - *didSuppressMessage = true; + if (didSuppressMessage) + *didSuppressMessage = true; return; } WebContentsAdapterClient::JavascriptDialogType dialogType = static_cast<WebContentsAdapterClient::JavascriptDialogType>(javascriptMessageType); - JavaScriptDialogControllerPrivate *dialogData = new JavaScriptDialogControllerPrivate(dialogType, toQt(messageText).toHtmlEscaped() - , toQt(defaultPromptText).toHtmlEscaped(), toQt(originUrl), callback, webContents); - QSharedPointer<JavaScriptDialogController> dialog(new JavaScriptDialogController(dialogData)); - - // We shouldn't get new dialogs for a given WebContents until we gave back a result. - Q_ASSERT(!m_activeDialogs.contains(webContents)); - m_activeDialogs.insert(webContents, dialog); - - client->javascriptDialog(dialog); + runDialogForContents(webContents, dialogType, toQt(messageText).toHtmlEscaped(), toQt(defaultPromptText).toHtmlEscaped(), toQt(originUrl), callback); } bool JavaScriptDialogManagerQt::HandleJavaScriptDialog(content::WebContents *contents, bool accept, const base::string16 *promptOverride) @@ -88,6 +80,25 @@ bool JavaScriptDialogManagerQt::HandleJavaScriptDialog(content::WebContents *con return true; } +void JavaScriptDialogManagerQt::runDialogForContents(content::WebContents *webContents, WebContentsAdapterClient::JavascriptDialogType type + , const QString &messageText, const QString &defaultPrompt, const QUrl &origin + , const content::JavaScriptDialogManager::DialogClosedCallback &callback, const QString &title) +{ + WebContentsAdapterClient *client = WebContentsViewQt::from(webContents->GetView())->client(); + if (!client) + return; + + JavaScriptDialogControllerPrivate *dialogData = new JavaScriptDialogControllerPrivate(type, messageText, defaultPrompt, title, origin, callback, webContents); + QSharedPointer<JavaScriptDialogController> dialog(new JavaScriptDialogController(dialogData)); + + // We shouldn't get new dialogs for a given WebContents until we gave back a result. + Q_ASSERT(!m_activeDialogs.contains(webContents)); + m_activeDialogs.insert(webContents, dialog); + + client->javascriptDialog(dialog); + +} + void JavaScriptDialogManagerQt::removeDialogForContents(content::WebContents *contents) { diff --git a/src/core/javascript_dialog_manager_qt.h b/src/core/javascript_dialog_manager_qt.h index 69eaf94b1..518ceca53 100644 --- a/src/core/javascript_dialog_manager_qt.h +++ b/src/core/javascript_dialog_manager_qt.h @@ -44,6 +44,8 @@ #include "content/public/browser/javascript_dialog_manager.h" #include "content/public/common/javascript_message_type.h" +#include "web_contents_adapter_client.h" + #include "qglobal.h" #include <QMap> #include <QSharedPointer> @@ -62,12 +64,16 @@ public: virtual void RunJavaScriptDialog(content::WebContents *, const GURL &, const std::string &acceptLang, content::JavaScriptMessageType javascriptMessageType, const base::string16 &messageText, const base::string16 &defaultPromptText, const content::JavaScriptDialogManager::DialogClosedCallback &callback, bool *didSuppressMessage) Q_DECL_OVERRIDE; + virtual void RunBeforeUnloadDialog(content::WebContents *, const base::string16 &messageText, bool isReload, const content::JavaScriptDialogManager::DialogClosedCallback &callback) Q_DECL_OVERRIDE { Q_UNUSED(messageText); Q_UNUSED(isReload); Q_UNUSED(callback); } virtual bool HandleJavaScriptDialog(content::WebContents *, bool accept, const base::string16 *promptOverride) Q_DECL_OVERRIDE; virtual void CancelActiveAndPendingDialogs(content::WebContents *contents) Q_DECL_OVERRIDE { removeDialogForContents(contents); } virtual void WebContentsDestroyed(content::WebContents *contents) Q_DECL_OVERRIDE { removeDialogForContents(contents); } + + void runDialogForContents(content::WebContents *, WebContentsAdapterClient::JavascriptDialogType, const QString &messageText, const QString &defaultPrompt + , const QUrl &,const content::JavaScriptDialogManager::DialogClosedCallback &callback, const QString &title = QString()); void removeDialogForContents(content::WebContents *); private: diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index 7deb55686..64b5fca38 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -96,7 +96,9 @@ public: enum JavascriptDialogType { AlertDialog, ConfirmDialog, - PromptDialog + PromptDialog, + // Leave room for potential new specs + InternalAuthorizationDialog = 0x10, }; // Must match the ones in file_chooser_params.h diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp index 5fb5ef475..919b3f622 100644 --- a/src/webengine/ui_delegates_manager.cpp +++ b/src/webengine/ui_delegates_manager.cpp @@ -257,15 +257,19 @@ void UIDelegatesManager::showDialog(QSharedPointer<JavaScriptDialogController> d switch (dialogController->type()) { case WebContentsAdapterClient::AlertDialog: dialogComponentType = AlertDialog; - title = QObject::tr("Javascript Alert - %1"); + title = QObject::tr("Javascript Alert - %1").arg(m_view->url().toString()); break; case WebContentsAdapterClient::ConfirmDialog: dialogComponentType = ConfirmDialog; - title = QObject::tr("Javascript Confirm - %1"); + title = QObject::tr("Javascript Confirm - %1").arg(m_view->url().toString()); break; case WebContentsAdapterClient::PromptDialog: dialogComponentType = PromptDialog; - title = QObject::tr("Javascript Prompt - %1"); + title = QObject::tr("Javascript Prompt - %1").arg(m_view->url().toString()); + break; + case WebContentsAdapterClient::InternalAuthorizationDialog: + dialogComponentType = ConfirmDialog; + title = dialogController->title(); break; default: Q_UNREACHABLE(); @@ -288,7 +292,7 @@ void UIDelegatesManager::showDialog(QSharedPointer<JavaScriptDialogController> d textProp.write(dialogController->message()); QQmlProperty titleProp(dialog, QStringLiteral("title")); - titleProp.write(title.arg(m_view->url().toString())); + titleProp.write(title); if (dialogComponentType == PromptDialog) { QQmlProperty promptProp(dialog, QStringLiteral("prompt")); diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 6fcababbf..ec0c0224d 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -594,6 +594,9 @@ void QWebEnginePagePrivate::javascriptDialog(QSharedPointer<JavaScriptDialogCont if (accepted) controller->textProvided(promptResult); break; + case InternalAuthorizationDialog: + accepted = (QMessageBox::question(view, controller->title(), controller->message(), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes); + break; default: Q_UNREACHABLE(); } -- GitLab