diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro index 4064324d04a0c9fcf915ff5190b074a12744ab5c..a22b9126a577b448043f300f61f78d02748d146b 100644 --- a/src/core/core_gyp_generator.pro +++ b/src/core/core_gyp_generator.pro @@ -41,6 +41,7 @@ SOURCES = \ dev_tools_http_handler_delegate_qt.cpp \ download_manager_delegate_qt.cpp \ chromium_gpu_helper.cpp \ + javascript_dialog_controller.cpp \ javascript_dialog_manager_qt.cpp \ process_main.cpp \ render_widget_host_view_qt.cpp \ @@ -69,6 +70,8 @@ HEADERS = \ dev_tools_http_handler_delegate_qt.h \ download_manager_delegate_qt.h \ chromium_gpu_helper.h \ + javascript_dialog_controller_p.h \ + javascript_dialog_controller.h \ javascript_dialog_manager_qt.h \ process_main.h \ render_widget_host_view_qt.h \ diff --git a/src/core/javascript_dialog_controller.cpp b/src/core/javascript_dialog_controller.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ed0431084d252f620562613160cfd3a9103ee051 --- /dev/null +++ b/src/core/javascript_dialog_controller.cpp @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "javascript_dialog_controller.h" +#include "javascript_dialog_controller_p.h" + +#include"javascript_dialog_manager_qt.h" +#include "type_conversion.h" + +void JavaScriptDialogControllerPrivate::dialogFinished(bool accepted, const base::string16 &promptValue) +{ + // Clear the queue first as this could result in the engine asking us to run another dialog. + JavaScriptDialogManagerQt::GetInstance()->removeDialogForContents(contents); + + callback.Run(accepted, promptValue); +} + +JavaScriptDialogControllerPrivate::JavaScriptDialogControllerPrivate(WebContentsAdapterClient::JavascriptDialogType t, const QString &msg, const QString &prompt + , const content::JavaScriptDialogManager::DialogClosedCallback &cb, content::WebContents *c) + : type(t) + , message(msg) + , defaultPrompt(prompt) + , callback(cb) + , contents(c) +{ +} + +JavaScriptDialogController::~JavaScriptDialogController() +{ +} + +QString JavaScriptDialogController::message() const +{ + return d->message; +} + +QString JavaScriptDialogController::defaultPrompt() const +{ + return d->defaultPrompt; +} + +WebContentsAdapterClient::JavascriptDialogType JavaScriptDialogController::type() const +{ + return d->type; +} + +void JavaScriptDialogController::textProvided(const QString &text) +{ + d->userInput = text; +} + +void JavaScriptDialogController::accept() +{ + d->dialogFinished(true, toString16(d->userInput)); +} + +void JavaScriptDialogController::reject() +{ + d->dialogFinished(false, toString16(d->defaultPrompt)); +} + +JavaScriptDialogController::JavaScriptDialogController(JavaScriptDialogControllerPrivate *dd) +{ + Q_ASSERT(dd); + d.reset(dd); +} diff --git a/src/core/javascript_dialog_controller.h b/src/core/javascript_dialog_controller.h new file mode 100644 index 0000000000000000000000000000000000000000..e92bc806729cbd9e1353fda48e7d028aae648e0c --- /dev/null +++ b/src/core/javascript_dialog_controller.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef JAVASCRIPT_DIALOG_CONTROLLER_H +#define JAVASCRIPT_DIALOG_CONTROLLER_H + +#include "web_contents_adapter_client.h" + +QT_FORWARD_DECLARE_CLASS(QString) + +struct JavaScriptDialogControllerPrivate; + +class QWEBENGINE_EXPORT JavaScriptDialogController : public QObject { + Q_OBJECT +public: + ~JavaScriptDialogController(); + QString message() const; + QString defaultPrompt() const; + WebContentsAdapterClient::JavascriptDialogType type() const; + +public Q_SLOTS: + void textProvided(const QString &text); + void accept(); + void reject(); + +Q_SIGNALS: + void dialogCloseRequested(); + +private: + JavaScriptDialogController(JavaScriptDialogControllerPrivate *); + + QScopedPointer<JavaScriptDialogControllerPrivate> d; + friend class JavaScriptDialogManagerQt; +}; + +#endif // JAVASCRIPT_DIALOG_CONTROLLER_H diff --git a/src/core/javascript_dialog_controller_p.h b/src/core/javascript_dialog_controller_p.h new file mode 100644 index 0000000000000000000000000000000000000000..9e84b31a0263009fe9f029ec7ad89a7159890d15 --- /dev/null +++ b/src/core/javascript_dialog_controller_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef JAVASCRIPT_DIALOG_CONTROLLER_P_H +#define JAVASCRIPT_DIALOG_CONTROLLER_P_H + +#include "content/public/browser/javascript_dialog_manager.h" +#include "web_contents_adapter_client.h" +#include <QString> + +namespace content { +class WebContents; +} + +class JavaScriptDialogControllerPrivate { + +public: + void dialogFinished(bool accepted, const base::string16 &promptValue); + JavaScriptDialogControllerPrivate(WebContentsAdapterClient::JavascriptDialogType, const QString &message, const QString &prompt + , const content::JavaScriptDialogManager::DialogClosedCallback &, content::WebContents *); + + WebContentsAdapterClient::JavascriptDialogType type; + QString message; + QString defaultPrompt; + QString userInput; + content::JavaScriptDialogManager::DialogClosedCallback callback; + content::WebContents *contents; +}; + +#endif // JAVASCRIPT_DIALOG_CONTROLLER_P_H diff --git a/src/core/javascript_dialog_manager_qt.cpp b/src/core/javascript_dialog_manager_qt.cpp index b2f6d86bcc996524b6b732c93c76845f86ef14f0..f0b8c54856558b86b618c7827351ac687aed0f93 100644 --- a/src/core/javascript_dialog_manager_qt.cpp +++ b/src/core/javascript_dialog_manager_qt.cpp @@ -41,6 +41,8 @@ #include "javascript_dialog_manager_qt.h" +#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" @@ -65,14 +67,31 @@ void JavaScriptDialogManagerQt::RunJavaScriptDialog(content::WebContents *webCon return; } - QString promptInput; WebContentsAdapterClient::JavascriptDialogType dialogType = static_cast<WebContentsAdapterClient::JavascriptDialogType>(javascriptMessageType); - bool res = client->javascriptDialog(dialogType, toQt(messageText).toHtmlEscaped(), toQt(defaultPromptText).toHtmlEscaped(), &promptInput); - callback.Run(res, toString16(promptInput)); + JavaScriptDialogControllerPrivate *dialogData = new JavaScriptDialogControllerPrivate(dialogType, toQt(messageText).toHtmlEscaped() + , toQt(defaultPromptText).toHtmlEscaped(), 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); +} + +bool JavaScriptDialogManagerQt::HandleJavaScriptDialog(content::WebContents *contents, bool accept, const base::string16 *promptOverride) +{ + if (!m_activeDialogs.contains(contents)) + return false; + QSharedPointer<JavaScriptDialogController> dialog = m_activeDialogs.value(contents); + Q_EMIT dialog->dialogCloseRequested(); + dialog->d->dialogFinished(accept, promptOverride ? *promptOverride : base::string16()); + return true; } -bool JavaScriptDialogManagerQt::HandleJavaScriptDialog(content::WebContents *, bool accept, const base::string16 *promptOverride) + +void JavaScriptDialogManagerQt::removeDialogForContents(content::WebContents *contents) { - // FIXME: We might need to keep a queue of modal dialogs in there and unqueue them... - return false; + QSharedPointer<JavaScriptDialogController> dialog = m_activeDialogs.take(contents); + Q_EMIT dialog->dialogCloseRequested(); } diff --git a/src/core/javascript_dialog_manager_qt.h b/src/core/javascript_dialog_manager_qt.h index de416e03e29f9ebbaee77beaef68aec8d3b5e0f0..69eaf94b1e1d163d6fd0f1d0975d602f6bf6a544 100644 --- a/src/core/javascript_dialog_manager_qt.h +++ b/src/core/javascript_dialog_manager_qt.h @@ -45,7 +45,10 @@ #include "content/public/common/javascript_message_type.h" #include "qglobal.h" +#include <QMap> +#include <QSharedPointer> +class JavaScriptDialogController; namespace content { class WebContents; } @@ -62,8 +65,13 @@ public: 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 *) Q_DECL_OVERRIDE {} - virtual void WebContentsDestroyed(content::WebContents *) 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 removeDialogForContents(content::WebContents *); + +private: + QMap<content::WebContents *, QSharedPointer<JavaScriptDialogController> > m_activeDialogs; }; diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 7542f35bd56c86ad65411f293c4ae5f73f20a49d..bb2ac36f4ecc714516d4177d01b65e3bcafd4a6b 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -40,8 +40,9 @@ ****************************************************************************/ #include "web_contents_adapter.h" -#include "content_browser_client_qt.h" #include "browser_context_qt.h" +#include "content_browser_client_qt.h" +#include "javascript_dialog_manager_qt.h" #include "type_conversion.h" #include "web_contents_adapter_client.h" #include "web_contents_delegate_qt.h" diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index 2231fd46b0f09358a2a934d42e825ba6eb292923..28cd3c4d86dc5288af8c487e9b783af37c5cccba 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -44,10 +44,12 @@ #include "qtwebenginecoreglobal.h" #include <QRect> +#include <QSharedPointer> #include <QString> #include <QStringList> #include <QUrl> +class JavaScriptDialogController; class RenderWidgetHostViewQt; class RenderWidgetHostViewQtDelegate; class RenderWidgetHostViewQtDelegateClient; @@ -123,7 +125,7 @@ public: virtual void adoptNewWindow(WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, const QRect & initialGeometry) = 0; virtual void close() = 0; virtual bool contextMenuRequested(const WebEngineContextMenuData&) = 0; - virtual bool javascriptDialog(JavascriptDialogType type, const QString &message, const QString &defaultValue = QString(), QString *result = 0) = 0; + virtual void javascriptDialog(QSharedPointer<JavaScriptDialogController>) = 0; virtual void runFileChooser(FileChooserMode, const QString &defaultFileName, const QStringList &acceptedMimeTypes) = 0; }; diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index 6dd8121dd39d9194ff494264680bfc19a60dbd4c..c3648bccf128341d20a0a4ad54155f9707005d20 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -86,6 +86,7 @@ void WebContentsDelegateQt::AddNewContents(content::WebContents* source, content void WebContentsDelegateQt::CloseContents(content::WebContents *source) { m_viewClient->close(); + GetJavaScriptDialogManager()->CancelActiveAndPendingDialogs(source); } void WebContentsDelegateQt::LoadingStateChanged(content::WebContents* source) diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 1dcc2acd00f395f8e327849e9be142078b638eaa..c06a4af489d19a860d0f5a3a08abbfcf4d1b6c3e 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -43,6 +43,7 @@ #include "qquickwebengineview_p_p.h" #include "net/base/net_errors.h" +#include "javascript_dialog_controller.h" #include "qquickwebengineloadrequest_p.h" #include "render_widget_host_view_qt_delegate_quick.h" #include "ui_delegates_manager.h" @@ -171,10 +172,9 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu return true; } -bool QQuickWebEngineViewPrivate::javascriptDialog(JavascriptDialogType type, const QString &message, const QString &defaultValue, QString *result) +void QQuickWebEngineViewPrivate::javascriptDialog(QSharedPointer<JavaScriptDialogController> dialog) { - Q_UNUSED(message); Q_UNUSED(defaultValue); Q_UNUSED(result); - return false; + ui()->showDialog(dialog); } void QQuickWebEngineViewPrivate::titleChanged(const QString &title) diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 67337baeb1cf564d6b424fffed3aef34c816615a..45622d308a4b823808eee29043e8a9c6f21b3911 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -136,7 +136,7 @@ public: virtual void adoptNewWindow(WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, const QRect &) Q_DECL_OVERRIDE; virtual void close() Q_DECL_OVERRIDE; virtual bool contextMenuRequested(const WebEngineContextMenuData &) Q_DECL_OVERRIDE; - virtual bool javascriptDialog(JavascriptDialogType, const QString &message, const QString &defaultValue = QString(), QString *result = 0) Q_DECL_OVERRIDE { Q_UNUSED(message); Q_UNUSED(defaultValue); Q_UNUSED(result); return false; } + virtual void javascriptDialog(QSharedPointer<JavaScriptDialogController>) Q_DECL_OVERRIDE; virtual void runFileChooser(FileChooserMode, const QString &defaultFileName, const QStringList &acceptedMimeTypes) { Q_UNUSED(defaultFileName); Q_UNUSED(acceptedMimeTypes);} void setDevicePixelRatio(qreal); diff --git a/src/webengine/ui/AlertDialog.qml b/src/webengine/ui/AlertDialog.qml new file mode 100644 index 0000000000000000000000000000000000000000..bc494a080e087449fb165a7f1c7076329f16b2b1 --- /dev/null +++ b/src/webengine/ui/AlertDialog.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Dialogs 1.1 + +MessageDialog { + icon: StandardIcon.Information +} diff --git a/src/webengine/ui/ConfirmDialog.qml b/src/webengine/ui/ConfirmDialog.qml new file mode 100644 index 0000000000000000000000000000000000000000..108497d3d19912ae7c2c03738db1ad5d2bce0220 --- /dev/null +++ b/src/webengine/ui/ConfirmDialog.qml @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Dialogs 1.1 + +MessageDialog { + icon: StandardIcon.Question + standardButtons: StandardButton.Ok | StandardButton.Cancel +} diff --git a/src/webengine/ui/PromptDialog.qml b/src/webengine/ui/PromptDialog.qml new file mode 100644 index 0000000000000000000000000000000000000000..534c9dd9bcdf27d8f5db81d9e5effd78ef60bea3 --- /dev/null +++ b/src/webengine/ui/PromptDialog.qml @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// FIXME: prompt missing in Qt Quick Dialogs atm. Make our own for now. +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.0 +import QtQuick 2.0 + +ApplicationWindow { + signal input(string text); + signal accepted; + signal rejected; + property alias text: message.text; + property alias prompt: field.text; + + width: 350 + height: 100 + flags: Qt.Dialog + + function open() { + show(); + } + + ColumnLayout { + anchors.fill: parent; + anchors.margins: 4; + Text { + id: message; + Layout.fillWidth: true; + } + TextField { + id:field; + Layout.fillWidth: true; + } + RowLayout { + Layout.alignment: Qt.AlignRight + spacing: 8; + Button { + text: "OK" + onClicked: { + input(field.text) + accepted(); + close(); + destroy(); + } + } + Button { + text: "Cancel" + onClicked: { + rejected(); + close(); + destroy(); + } + } + } + } + +} diff --git a/src/webengine/ui/qmldir b/src/webengine/ui/qmldir index bc0e2e300dbc283e3df71a7a78720b5ca6d96ff1..bb942a81a940dce35a05ad2e0fc6ab6d598a1faf 100644 --- a/src/webengine/ui/qmldir +++ b/src/webengine/ui/qmldir @@ -1,4 +1,7 @@ module QtWebEngine.UIDelegates +AlertDialog 1.0 AlertDialog.qml +ConfirmDialog 1.0 ConfirmDialog.qml +PromptDialog 1.0 PromptDialog.qml Menu 1.0 Menu.qml MenuItem 1.0 MenuItem.qml MenuSeparator 1.0 MenuSeparator.qml diff --git a/src/webengine/ui/ui.pro b/src/webengine/ui/ui.pro index 42a5777dcec6425ab40570a56b7d266b5d9b57b9..049b428f5025eed284bf4ed7b195fc2942594ecb 100644 --- a/src/webengine/ui/ui.pro +++ b/src/webengine/ui/ui.pro @@ -1,6 +1,11 @@ TARGETPATH = QtWebEngine/UIDelegates QML_FILES += \ + # JS Dialogs + AlertDialog.qml \ + ConfirmDialog.qml \ + PromptDialog.qml \ + # Menus. Based on Qt Quick Controls Menu.qml \ MenuItem.qml \ MenuSeparator.qml diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp index 34edbd4790571ccfdc3c5afff47ec582581e799a..6ee3ea3600a76fd89de805b8763115b1cc5b9921 100644 --- a/src/webengine/ui_delegates_manager.cpp +++ b/src/webengine/ui_delegates_manager.cpp @@ -40,7 +40,9 @@ ****************************************************************************/ #include "ui_delegates_manager.h" + #include "api/qquickwebengineview_p.h" +#include "javascript_dialog_controller.h" #include <QAbstractListModel> #include <QClipboard> @@ -158,9 +160,9 @@ QQmlContext *UIDelegatesManager::creationContextForComponent(QQmlComponent *comp return baseContext; } -#define CHECK_QML_SIGNAL_PROPERTY(prop, type, location) \ +#define CHECK_QML_SIGNAL_PROPERTY(prop, location) \ if (!prop.isSignalProperty()) \ - qWarning(#type "component (Loaded from %s) is missing %s signal property.\n", qPrintable(location.toString()), qPrintable(prop.name())); + qWarning("%s is missing %s signal property.\n", qPrintable(location.toString()), qPrintable(prop.name())); void UIDelegatesManager::addMenuItem(MenuItemHandler *menuItemHandler, const QString &text, const QString &iconName, bool enabled) { @@ -231,3 +233,74 @@ QObject *UIDelegatesManager::addMenu(QObject *parentMenu, const QString &title, return menu; } +#define ASSIGN_DIALOG_COMPONENT_DATA_CASE_STATEMENT(TYPE, COMPONENT) \ + case TYPE:\ + dialogComponent = COMPONENT##Component.data(); \ + break; + + +void UIDelegatesManager::showDialog(QSharedPointer<JavaScriptDialogController> dialogController) +{ + Q_ASSERT(!dialogController.isNull()); + ComponentType dialogComponentType = Invalid; + QString title; + switch (dialogController->type()) { + case WebContentsAdapterClient::AlertDialog: + dialogComponentType = AlertDialog; + title = QObject::tr("Javascript Alert - %1"); + break; + case WebContentsAdapterClient::ConfirmDialog: + dialogComponentType = ConfirmDialog; + title = QObject::tr("Javascript Confirm - %1"); + break; + case WebContentsAdapterClient::PromptDialog: + dialogComponentType = PromptDialog; + title = QObject::tr("Javascript Prompt - %1"); + break; + default: + Q_UNREACHABLE(); + } + + if (!ensureComponentLoaded(dialogComponentType)) + return; + + QQmlComponent *dialogComponent = Q_NULLPTR; + switch (dialogComponentType) { + FOR_EACH_COMPONENT_TYPE(ASSIGN_DIALOG_COMPONENT_DATA_CASE_STATEMENT, NO_SEPARATOR) + default: + Q_UNREACHABLE(); + } + + QQmlContext *context(creationContextForComponent(dialogComponent)); + QObject *dialog = dialogComponent->beginCreate(context); + dialog->setParent(m_view); + QQmlProperty textProp(dialog, QStringLiteral("text")); + textProp.write(dialogController->message()); + + QQmlProperty titleProp(dialog, QStringLiteral("title")); + titleProp.write(title.arg(m_view->url().toString())); + + if (dialogComponentType == PromptDialog) { + QQmlProperty promptProp(dialog, QStringLiteral("prompt")); + promptProp.write(dialogController->defaultPrompt()); + QQmlProperty inputSignal(dialog, QStringLiteral("onInput")); + CHECK_QML_SIGNAL_PROPERTY(inputSignal, dialogComponent->url()); + static int setTextIndex = dialogController->metaObject()->indexOfSlot("textProvided(QString)"); + QObject::connect(dialog, inputSignal.method(), dialogController.data(), dialogController->metaObject()->method(setTextIndex)); + } + + QQmlProperty acceptSignal(dialog, QStringLiteral("onAccepted")); + QQmlProperty rejectSignal(dialog, QStringLiteral("onRejected")); + CHECK_QML_SIGNAL_PROPERTY(acceptSignal, dialogComponent->url()); + CHECK_QML_SIGNAL_PROPERTY(rejectSignal, dialogComponent->url()); + + static int acceptIndex = dialogController->metaObject()->indexOfSlot("accept()"); + QObject::connect(dialog, acceptSignal.method(), dialogController.data(), dialogController->metaObject()->method(acceptIndex)); + static int rejectIndex = dialogController->metaObject()->indexOfSlot("reject()"); + QObject::connect(dialog, rejectSignal.method(), dialogController.data(), dialogController->metaObject()->method(rejectIndex)); + dialogComponent->completeCreate(); + + QObject::connect(dialogController.data(), &JavaScriptDialogController::dialogCloseRequested, dialog, &QObject::deleteLater); + + QMetaObject::invokeMethod(dialog, "open"); +} diff --git a/src/webengine/ui_delegates_manager.h b/src/webengine/ui_delegates_manager.h index 65f994b9397ad5aba953e6b52355ef62bdf926b7..eeece895c5f550409e2ef4bd8401675faa1608dd 100644 --- a/src/webengine/ui_delegates_manager.h +++ b/src/webengine/ui_delegates_manager.h @@ -47,14 +47,18 @@ #include <QExplicitlySharedDataPointer> #include <QPoint> -#include <QPointer> #include <QQmlComponent> +#include <QScopedPointer> +#include <QSharedPointer> #include <QUrl> #define FOR_EACH_COMPONENT_TYPE(F, SEPARATOR) \ F(Menu, menu) SEPARATOR \ F(MenuItem, menuItem) SEPARATOR \ - F(MenuSeparator, menuSeparator) SEPARATOR + F(MenuSeparator, menuSeparator) SEPARATOR \ + F(AlertDialog, alertDialog) SEPARATOR \ + F(ConfirmDialog, confirmDialog) SEPARATOR \ + F(PromptDialog, promptDialog) SEPARATOR #define COMMA_SEPARATOR , #define SEMICOLON_SEPARATOR ; @@ -63,6 +67,7 @@ #define MEMBER_DECLARATION(TYPE, COMPONENT) \ QScopedPointer<QQmlComponent> COMPONENT##Component +class JavaScriptDialogController; QT_BEGIN_NAMESPACE class QObject; class QQmlContext; @@ -106,7 +111,9 @@ class UIDelegatesManager { public: enum ComponentType { + Invalid = -1, FOR_EACH_COMPONENT_TYPE(ENUM_DECLARATION, COMMA_SEPARATOR) + ComponentTypeCount }; UIDelegatesManager(QQuickWebEngineView *); @@ -115,6 +122,7 @@ public: void addMenuSeparator(QObject *menu); QObject *addMenu(QObject *parentMenu, const QString &title, const QPoint &pos = QPoint()); QQmlContext *creationContextForComponent(QQmlComponent *); + void showDialog(QSharedPointer<JavaScriptDialogController>); private: bool ensureComponentLoaded(ComponentType); diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 3f4287a02c2dbb6012a9bcaf21bb98d495ac813b..0178c111818cc62743f313f66744bde39166b326 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -23,6 +23,7 @@ #include "qwebenginepage.h" #include "qwebenginepage_p.h" +#include "javascript_dialog_controller.h" #include "qwebenginehistory.h" #include "qwebenginehistory_p.h" #include "qwebengineview.h" @@ -326,20 +327,31 @@ bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData return true; } -bool QWebEnginePagePrivate::javascriptDialog(JavascriptDialogType type, const QString &message, const QString &defaultValue, QString *result) +void QWebEnginePagePrivate::javascriptDialog(QSharedPointer<JavaScriptDialogController> controller) { Q_Q(QWebEnginePage); - switch (type) { + bool accepted = false; + QString promptResult; + switch (controller->type()) { case AlertDialog: - q->javaScriptAlert(0, message); - return true; + q->javaScriptAlert(0, controller->message()); + accepted = true; + break; case ConfirmDialog: - return q->javaScriptConfirm(0, message); + accepted = q->javaScriptConfirm(0, controller->message()); + break; case PromptDialog: - return q->javaScriptPrompt(0, message, defaultValue, result); + accepted = q->javaScriptPrompt(0, controller->message(), controller->defaultPrompt(), &promptResult); + if (accepted) + controller->textProvided(promptResult); + break; + default: + Q_UNREACHABLE(); } - Q_UNREACHABLE(); - return false; + if (accepted) + controller->accept(); + else + controller->reject(); } namespace { diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h index 8901f5ec46a5ccb03add69d01dfe6164f7947bd4..c8dd63daabc068f107fa9b351a7955014e598685 100644 --- a/src/webenginewidgets/api/qwebenginepage_p.h +++ b/src/webenginewidgets/api/qwebenginepage_p.h @@ -78,7 +78,7 @@ public: virtual void adoptNewWindow(WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, const QRect &initialGeometry) Q_DECL_OVERRIDE; virtual void close() Q_DECL_OVERRIDE; virtual bool contextMenuRequested(const WebEngineContextMenuData &data) Q_DECL_OVERRIDE; - virtual bool javascriptDialog(JavascriptDialogType type, const QString &message, const QString &defaultValue = QString(), QString *result = 0) Q_DECL_OVERRIDE; + virtual void javascriptDialog(QSharedPointer<JavaScriptDialogController>) Q_DECL_OVERRIDE; virtual void runFileChooser(FileChooserMode, const QString &defaultFileName, const QStringList &acceptedMimeTypes) Q_DECL_OVERRIDE; void updateAction(QWebEnginePage::WebAction) const;