summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--.qmake.conf1
-rw-r--r--dist/changes-5.6.02
-rw-r--r--examples/examples.pro8
-rw-r--r--examples/webengine/minimal/doc/src/minimal.qdoc82
-rw-r--r--examples/webengine/minimal/main.cpp55
-rw-r--r--examples/webengine/minimal/main.qml53
-rw-r--r--examples/webengine/minimal/minimal.pro10
-rw-r--r--examples/webengine/minimal/qml.qrc6
-rw-r--r--examples/webenginewidgets/demobrowser/browserapplication.cpp11
-rw-r--r--examples/webenginewidgets/demobrowser/browsermainwindow.cpp39
-rw-r--r--examples/webenginewidgets/demobrowser/browsermainwindow.h3
-rw-r--r--examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc3
-rw-r--r--examples/webenginewidgets/markdowneditor/mainwindow.cpp25
-rw-r--r--examples/webenginewidgets/markdowneditor/mainwindow.h2
-rw-r--r--examples/webenginewidgets/minimal/doc/images/minimal-example.pngbin0 -> 89294 bytes
-rw-r--r--examples/webenginewidgets/minimal/doc/src/minimal.qdoc66
-rw-r--r--examples/webenginewidgets/minimal/main.cpp54
-rw-r--r--examples/webenginewidgets/minimal/minimal.pro8
-rw-r--r--examples/webenginewidgets/simplebrowser/browser.cpp88
-rw-r--r--examples/webenginewidgets/simplebrowser/browser.h61
-rw-r--r--examples/webenginewidgets/simplebrowser/browserwindow.cpp437
-rw-r--r--examples/webenginewidgets/simplebrowser/browserwindow.h101
-rw-r--r--examples/webenginewidgets/simplebrowser/certificateerrordialog.ui133
-rw-r--r--examples/webenginewidgets/simplebrowser/data/addtab.pngbin0 -> 469 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/closetab.pngbin0 -> 516 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/defaulticon.pngbin0 -> 1473 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/go-next.pngbin0 -> 930 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/go-previous.pngbin0 -> 955 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/process-stop.pngbin0 -> 1272 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/simplebrowser.qrc12
-rw-r--r--examples/webenginewidgets/simplebrowser/data/simplebrowser.svg24
-rw-r--r--examples/webenginewidgets/simplebrowser/data/view-refresh.pngbin0 -> 1364 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/doc/images/simplebrowser-model.pngbin0 -> 10515 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/doc/images/simplebrowser.pngbin0 -> 70625 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/doc/src/simplebrowser-model.qmodel938
-rw-r--r--examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc263
-rw-r--r--examples/webenginewidgets/simplebrowser/main.cpp60
-rw-r--r--examples/webenginewidgets/simplebrowser/passworddialog.ui121
-rw-r--r--examples/webenginewidgets/simplebrowser/simplebrowser.pro33
-rw-r--r--examples/webenginewidgets/simplebrowser/tabwidget.cpp277
-rw-r--r--examples/webenginewidgets/simplebrowser/tabwidget.h95
-rw-r--r--examples/webenginewidgets/simplebrowser/urllineedit.cpp95
-rw-r--r--examples/webenginewidgets/simplebrowser/urllineedit.h70
-rw-r--r--examples/webenginewidgets/simplebrowser/webpage.cpp132
-rw-r--r--examples/webenginewidgets/simplebrowser/webpage.h61
-rw-r--r--examples/webenginewidgets/simplebrowser/webpopupwindow.cpp95
-rw-r--r--examples/webenginewidgets/simplebrowser/webpopupwindow.h71
-rw-r--r--examples/webenginewidgets/simplebrowser/webview.cpp189
-rw-r--r--examples/webenginewidgets/simplebrowser/webview.h82
-rw-r--r--qtwebengine.pro10
m---------src/3rdparty0
-rw-r--r--src/core/api/qwebengineurlrequestinfo.cpp2
-rw-r--r--src/core/api/qwebengineurlrequestinfo.h2
-rw-r--r--src/core/browser_accessibility_manager_qt.cpp13
-rw-r--r--src/core/browser_accessibility_manager_qt.h2
-rw-r--r--src/core/browser_accessibility_qt.cpp96
-rw-r--r--src/core/browser_accessibility_qt.h15
-rw-r--r--src/core/browser_context_qt.cpp14
-rw-r--r--src/core/browser_context_qt.h3
-rw-r--r--src/core/chromium_gpu_helper.cpp25
-rw-r--r--src/core/chromium_gpu_helper.h5
-rw-r--r--src/core/chromium_overrides.cpp4
-rw-r--r--src/core/clipboard_qt.cpp6
-rw-r--r--src/core/clipboard_qt.h6
-rw-r--r--src/core/common/qt_messages.h10
-rw-r--r--src/core/common/user_script_data.cpp2
-rw-r--r--src/core/common/user_script_data.h5
-rw-r--r--src/core/config/embedded_linux.pri3
-rw-r--r--src/core/config/linux.pri4
-rw-r--r--src/core/config/mac_osx.pri11
-rw-r--r--src/core/config/windows.pri21
-rw-r--r--src/core/content_browser_client_qt.cpp32
-rw-r--r--src/core/content_browser_client_qt.h22
-rw-r--r--src/core/content_client_qt.cpp15
-rw-r--r--src/core/content_main_delegate_qt.cpp17
-rw-r--r--src/core/core_gyp_generator.pro2
-rw-r--r--src/core/core_module.pro37
-rw-r--r--src/core/delegated_frame_node.cpp176
-rw-r--r--src/core/delegated_frame_node.h10
-rw-r--r--src/core/dev_tools_http_handler_delegate_qt.cpp2
-rw-r--r--src/core/download_manager_delegate_qt.h2
-rw-r--r--src/core/favicon_manager.cpp183
-rw-r--r--src/core/favicon_manager.h14
-rw-r--r--src/core/favicon_manager_p.h6
-rw-r--r--src/core/gl_surface_qt.cpp15
-rw-r--r--src/core/gyp_run.pro24
-rw-r--r--src/core/media_capture_devices_dispatcher.cpp12
-rw-r--r--src/core/network_delegate_qt.cpp19
-rw-r--r--src/core/network_delegate_qt.h8
-rw-r--r--src/core/permission_manager_qt.cpp31
-rw-r--r--src/core/permission_manager_qt.h8
-rw-r--r--src/core/print_view_manager_base_qt.cpp6
-rw-r--r--src/core/print_view_manager_qt.cpp120
-rw-r--r--src/core/print_view_manager_qt.h10
-rw-r--r--src/core/printing_message_filter_qt.cpp4
-rw-r--r--src/core/printing_message_filter_qt.h2
-rw-r--r--src/core/process_main.cpp2
-rw-r--r--src/core/proxy_config_service_qt.h1
-rw-r--r--src/core/qtwebengine.gypi16
-rw-r--r--src/core/render_widget_host_view_qt.cpp56
-rw-r--r--src/core/render_widget_host_view_qt.h10
-rw-r--r--src/core/renderer/content_renderer_client_qt.cpp24
-rw-r--r--src/core/renderer/content_renderer_client_qt.h7
-rw-r--r--src/core/renderer/pepper/pepper_flash_browser_host_qt.h1
-rw-r--r--src/core/renderer/pepper/pepper_flash_renderer_host_qt.h1
-rw-r--r--src/core/renderer/pepper/pepper_renderer_host_factory_qt.h2
-rw-r--r--src/core/renderer/render_frame_observer_qt.h1
-rw-r--r--src/core/renderer/user_resource_controller.cpp8
-rw-r--r--src/core/renderer/user_resource_controller.h4
-rw-r--r--src/core/resource_dispatcher_host_delegate_qt.cpp14
-rw-r--r--src/core/resource_dispatcher_host_delegate_qt.h6
-rw-r--r--src/core/resources/resources.gyp2
-rw-r--r--src/core/ssl_host_state_delegate_qt.cpp135
-rw-r--r--src/core/ssl_host_state_delegate_qt.h80
-rw-r--r--src/core/url_request_context_getter_qt.cpp23
-rw-r--r--src/core/url_request_context_getter_qt.h1
-rw-r--r--src/core/url_request_custom_job.cpp25
-rw-r--r--src/core/url_request_custom_job.h2
-rw-r--r--src/core/url_request_qrc_job_qt.cpp13
-rw-r--r--src/core/url_request_qrc_job_qt.h2
-rw-r--r--src/core/web_contents_adapter.cpp50
-rw-r--r--src/core/web_contents_adapter.h4
-rw-r--r--src/core/web_contents_adapter_client.h1
-rw-r--r--src/core/web_contents_delegate_qt.cpp43
-rw-r--r--src/core/web_contents_delegate_qt.h4
-rw-r--r--src/core/web_contents_view_qt.cpp2
-rw-r--r--src/core/web_engine_context.cpp22
-rw-r--r--src/process/process.pro18
-rw-r--r--src/webengine/api/qquickwebenginecertificateerror.cpp15
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp24
-rw-r--r--src/webengine/api/qquickwebenginesettings_p.h29
-rw-r--r--src/webengine/api/qquickwebenginetestsupport.cpp1
-rw-r--r--src/webengine/api/qquickwebengineview.cpp44
-rw-r--r--src/webengine/api/qquickwebengineview_p.h162
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h3
-rw-r--r--src/webengine/doc/images/qtwebengine-architecture.pngbin11325 -> 8098 bytes
-rw-r--r--src/webengine/doc/images/qtwebengine-model.pngbin0 -> 8656 bytes
-rw-r--r--src/webengine/doc/images/qtwebenginewidgets-model.pngbin0 -> 9749 bytes
-rw-r--r--src/webengine/doc/qtwebengine.qdocconf3
-rw-r--r--src/webengine/doc/src/qtwebengine-index.qdoc2
-rw-r--r--src/webengine/doc/src/qtwebengine-modules.qdoc2
-rw-r--r--src/webengine/doc/src/qtwebengine-overview.qdoc108
-rw-r--r--src/webengine/doc/src/qtwebengine-platform-notes.qdoc52
-rw-r--r--src/webengine/doc/src/webengineview.qdoc309
-rw-r--r--src/webengine/plugin/plugin.cpp3
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp51
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h13
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h1
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp34
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp3
-rw-r--r--src/webenginewidgets/api/qwebengineview.h2
-rw-r--r--src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc13
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc50
-rw-r--r--src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc12
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp8
-rw-r--r--tests/auto/quick/inspectorserver/BLACKLIST5
-rw-r--r--tests/auto/quick/publicapi/tst_publicapi.cpp3
-rw-r--r--tests/auto/quick/qmltests/BLACKLIST9
-rw-r--r--tests/auto/quick/qmltests/data/tst_download.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_favicon.qml98
-rw-r--r--tests/auto/quick/qmltests/data/tst_faviconImage.qml125
-rw-r--r--tests/auto/quick/qmltests/data/tst_geopermission.qml19
-rw-r--r--tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml1
-rw-r--r--tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml1
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadFail.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_runJavaScript.qml1
-rw-r--r--tests/auto/quick/qmltests/qmltests.pro1
-rw-r--r--tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp24
-rw-r--r--tests/auto/quick/qquickwebengineviewgraphics/qquickwebengineviewgraphics.pro1
-rw-r--r--tests/auto/quick/tests.pri4
-rw-r--r--tests/auto/widgets/positionplugin/positionplugin.pro11
-rw-r--r--tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp12
-rw-r--r--tests/auto/widgets/qwebenginedefaultsurfaceformat/tst_qwebenginedefaultsurfaceformat.cpp3
-rw-r--r--tests/auto/widgets/qwebenginefaviconmanager/tst_qwebenginefaviconmanager.cpp26
-rw-r--r--tests/auto/widgets/qwebenginepage/BLACKLIST3
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp239
-rw-r--r--tests/auto/widgets/qwebengineprofile/BLACKLIST5
-rw-r--r--tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp3
-rw-r--r--tests/auto/widgets/qwebengineview/resources/basic_printing_page.html8
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp2
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc15
-rw-r--r--tools/qmake/mkspecs/features/configure.prf15
-rw-r--r--tools/qmake/mkspecs/features/default_pre.prf3
-rw-r--r--tools/qmake/mkspecs/features/functions.prf37
-rwxr-xr-xtools/scripts/take_snapshot.py12
-rw-r--r--tools/scripts/version_resolver.py4
187 files changed, 6008 insertions, 1113 deletions
diff --git a/.gitignore b/.gitignore
index ab40b145a..2a74d1302 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@ examples/webenginewidgets/browser/browser
examples/webenginewidgets/browser/browser.app
examples/webenginewidgets/contentmanipulation/contentmanipulation
examples/webenginewidgets/contentmanipulation/contentmanipulation.app
+examples/webenginewidgets/simplebrowser/simplebrowser
tests/quicktestbrowser/quicktestbrowser
tests/**/tst_*
diff --git a/.qmake.conf b/.qmake.conf
index 2b9abfb1a..ffb3dafe0 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -1,5 +1,6 @@
QMAKEPATH += $$PWD/tools/qmake
load(qt_build_config)
CONFIG += qt_example_installs
+CONFIG += warning_clean
MODULE_VERSION = 5.8.0
diff --git a/dist/changes-5.6.0 b/dist/changes-5.6.0
index f6495942a..a4999f320 100644
--- a/dist/changes-5.6.0
+++ b/dist/changes-5.6.0
@@ -21,7 +21,7 @@ information about a particular change.
- Chromium Snapshot:
* The Chromium version has been updated to 45.0.2554.101.
- * In addition security fixes from Chromium 46, 47 and 48 have been merged.
+ * In addition security fixes from Chromium 46 - 49 have been merged.
- General:
* The WebEngineCore module now contains shared C++ API.
diff --git a/examples/examples.pro b/examples/examples.pro
index 867ce4cc6..0de2ec505 100644
--- a/examples/examples.pro
+++ b/examples/examples.pro
@@ -1,13 +1,17 @@
TEMPLATE=subdirs
qtHaveModule(webengine) {
- SUBDIRS += webengine/quicknanobrowser
+ SUBDIRS += \
+ webengine/minimal \
+ webengine/quicknanobrowser
}
qtHaveModule(webenginewidgets) {
SUBDIRS += \
+ webenginewidgets/minimal \
webenginewidgets/contentmanipulation \
webenginewidgets/cookiebrowser \
webenginewidgets/demobrowser \
- webenginewidgets/markdowneditor
+ webenginewidgets/markdowneditor \
+ webenginewidgets/simplebrowser \
}
diff --git a/examples/webengine/minimal/doc/src/minimal.qdoc b/examples/webengine/minimal/doc/src/minimal.qdoc
new file mode 100644
index 000000000..c0b89ba5a
--- /dev/null
+++ b/examples/webengine/minimal/doc/src/minimal.qdoc
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example webengine/minimal
+ \title WebEngine Qt Quick Minimal Example
+ \ingroup webengine-examples
+ \brief Displays a web page using the Qt Quick integration of Qt WebEngine
+
+ \image minimal-example.png
+
+ \e {WebEngine Qt Quick Minimal Example} demonstrates how to use the
+ \l{WebEngineView} item to render a web page. It shows the minimum amount of
+ code needed to load and display an HTML page, and can be used as a basis for
+ further experimentation.
+
+ \include examples-run.qdocinc
+
+ \section1 C++ Code
+
+ In \c main.cpp we use only the QGuiApplication and QQmlApplicationEngine
+ classes. We also include \c qtwebengineglobal.h to be able to use
+ \l{QtWebEngine::initialize}.
+
+ \quotefromfile webengine/minimal/main.cpp
+ \skipto #include
+ \printto main
+
+ In the main function we first instantiate a QGuiApplication object.
+ We then call \l{QtWebEngine::initialize}, which makes sure that OpenGL
+ contexts can be shared between the main process and the dedicated renderer
+ process (\c QtWebEngineProcess). This method needs to be called before
+ any OpenGL context is created.
+
+ Then we create a QQmlApplicationEngine, and tell it to load \c main.qml
+ from the \l{The Qt Resource System}{Qt Resource System}.
+
+ Finally, QGuiApplication::exec() launches the main event loop.
+
+ \printuntil }
+
+ \section1 QML Code
+
+ In \c main.qml we create the top level window, set a sensible default size
+ and make it visible. The window will be filled by a WebEngineView item
+ loading the \l{Qt Homepage}.
+
+ \quotefromfile webengine/minimal/main.qml
+ \skipto import
+ \printuntil }
+ \printline }
+
+ \section1 Requirements
+
+ The example requires a working internet connection to render the
+ \l{Qt Homepage}.
+ An optional system proxy should be picked up automatically.
+*/
diff --git a/examples/webengine/minimal/main.cpp b/examples/webengine/minimal/main.cpp
new file mode 100644
index 000000000..cc5a1f61e
--- /dev/null
+++ b/examples/webengine/minimal/main.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+#include <qtwebengineglobal.h>
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+ QtWebEngine::initialize();
+
+ QQmlApplicationEngine engine;
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+
+ return app.exec();
+}
+
diff --git a/examples/webengine/minimal/main.qml b/examples/webengine/minimal/main.qml
new file mode 100644
index 000000000..f2d9f40b1
--- /dev/null
+++ b/examples/webengine/minimal/main.qml
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Window 2.0
+import QtWebEngine 1.0
+
+Window {
+ width: 1024
+ height: 750
+ visible: true
+ WebEngineView {
+ anchors.fill: parent
+ url: "http://www.qt.io"
+ }
+}
diff --git a/examples/webengine/minimal/minimal.pro b/examples/webengine/minimal/minimal.pro
new file mode 100644
index 000000000..23ce01d5b
--- /dev/null
+++ b/examples/webengine/minimal/minimal.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+
+QT += webengine
+
+SOURCES += main.cpp
+
+RESOURCES += qml.qrc
+
+target.path = $$[QT_INSTALL_EXAMPLES]/webengine/minimal
+INSTALLS += target
diff --git a/examples/webengine/minimal/qml.qrc b/examples/webengine/minimal/qml.qrc
new file mode 100644
index 000000000..0ff3892d9
--- /dev/null
+++ b/examples/webengine/minimal/qml.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ </qresource>
+</RCC>
+
diff --git a/examples/webenginewidgets/demobrowser/browserapplication.cpp b/examples/webenginewidgets/demobrowser/browserapplication.cpp
index 745e38865..a2e47cd9f 100644
--- a/examples/webenginewidgets/demobrowser/browserapplication.cpp
+++ b/examples/webenginewidgets/demobrowser/browserapplication.cpp
@@ -156,12 +156,11 @@ BrowserApplication::BrowserApplication(int &argc, char **argv)
m_localServer = new QLocalServer(this);
connect(m_localServer, SIGNAL(newConnection()),
this, SLOT(newLocalSocketConnection()));
- if (!m_localServer->listen(serverName)) {
- if (m_localServer->serverError() == QAbstractSocket::AddressInUseError
- && QFile::exists(m_localServer->serverName())) {
- QFile::remove(m_localServer->serverName());
- m_localServer->listen(serverName);
- }
+ if (!m_localServer->listen(serverName)
+ && m_localServer->serverError() == QAbstractSocket::AddressInUseError) {
+ QLocalServer::removeServer(serverName);
+ if (!m_localServer->listen(serverName))
+ qWarning("Could not create local socket %s.", qPrintable(serverName));
}
#ifndef QT_NO_OPENSSL
diff --git a/examples/webenginewidgets/demobrowser/browsermainwindow.cpp b/examples/webenginewidgets/demobrowser/browsermainwindow.cpp
index 4b53124da..e72a2b5fe 100644
--- a/examples/webenginewidgets/demobrowser/browsermainwindow.cpp
+++ b/examples/webenginewidgets/demobrowser/browsermainwindow.cpp
@@ -312,8 +312,12 @@ void BrowserMainWindow::setupMenu()
#if defined(QWEBENGINEPAGE_PRINT)
fileMenu->addAction(tr("P&rint Preview..."), this, SLOT(slotFilePrintPreview()));
fileMenu->addAction(tr("&Print..."), this, SLOT(slotFilePrint()), QKeySequence::Print);
- fileMenu->addSeparator();
#endif
+#ifndef QT_NO_PRINTER
+ fileMenu->addAction(tr("&Print to PDF..."), this, SLOT(slotFilePrintToPDF()));
+#endif // ifndef QT_NO_PRINTER
+ fileMenu->addSeparator();
+
QAction *action = fileMenu->addAction(tr("Private &Browsing..."), this, SLOT(slotPrivateBrowsing()));
action->setCheckable(true);
action->setChecked(BrowserApplication::instance()->privateBrowsing());
@@ -697,6 +701,39 @@ void BrowserMainWindow::slotFilePrint()
#endif
}
+void BrowserMainWindow::slotHandlePdfPrinted(const QByteArray& result)
+{
+ if (!result.size())
+ return;
+
+ QFile file(m_printerOutputFileName);
+
+ m_printerOutputFileName.clear();
+ if (!file.open(QFile::WriteOnly))
+ return;
+
+ file.write(result.data(), result.size());
+ file.close();
+}
+
+void BrowserMainWindow::slotFilePrintToPDF()
+{
+#ifndef QT_NO_PRINTER
+ if (!currentTab())
+ return;
+ QPrinter printer;
+ QPrintDialog *dialog = new QPrintDialog(&printer, this);
+ dialog->setWindowTitle(tr("Print Document"));
+ if (dialog->exec() != QDialog::Accepted || printer.outputFileName().isEmpty() || !m_printerOutputFileName.isEmpty())
+ return;
+
+ m_printerOutputFileName = printer.outputFileName();
+
+ currentTab()->page()->printToPdf(printer.pageLayout(), invoke(this, &BrowserMainWindow::slotHandlePdfPrinted));
+
+#endif // QT_NO_PRINTER
+}
+
#if defined(QWEBENGINEPAGE_PRINT)
void BrowserMainWindow::printRequested(QWebEngineFrame *frame)
{
diff --git a/examples/webenginewidgets/demobrowser/browsermainwindow.h b/examples/webenginewidgets/demobrowser/browsermainwindow.h
index 3f939b367..9fb6b0851 100644
--- a/examples/webenginewidgets/demobrowser/browsermainwindow.h
+++ b/examples/webenginewidgets/demobrowser/browsermainwindow.h
@@ -109,6 +109,7 @@ private slots:
void slotFileOpen();
void slotFilePrintPreview();
void slotFilePrint();
+ void slotFilePrintToPDF();
void slotPrivateBrowsing();
void slotFileSaveAs();
void slotEditFind();
@@ -137,6 +138,7 @@ private slots:
void slotOpenActionUrl(QAction *action);
void slotShowWindow();
void slotSwapFocus();
+ void slotHandlePdfPrinted(const QByteArray&);
#if defined(QWEBENGINEPAGE_PRINT)
void printRequested(QWebEngineFrame *frame);
@@ -179,6 +181,7 @@ private:
QIcon m_stopIcon;
QString m_lastSearch;
+ QString m_printerOutputFileName;
friend class BrowserApplication;
};
diff --git a/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc b/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
index 7909aaddd..3a9908ea6 100644
--- a/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
+++ b/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
@@ -116,7 +116,8 @@
\printto connect
The constructor first calls \c setupUi to construct the widgets and menu
- actions according to the UI file. It then makes sure our custom
+ actions according to the UI file. The text editor font is set to one
+ with a fixed character width. It then makes sure our custom
\c PreviewPage is used by the QWebEngineView instance in \c{ui->preview}.
\printto ui->preview
diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.cpp b/examples/webenginewidgets/markdowneditor/mainwindow.cpp
index 34d436cc2..417858d8d 100644
--- a/examples/webenginewidgets/markdowneditor/mainwindow.cpp
+++ b/examples/webenginewidgets/markdowneditor/mainwindow.cpp
@@ -54,6 +54,7 @@
#include <QFile>
#include <QFileDialog>
+#include <QFontDatabase>
#include <QMessageBox>
#include <QTextStream>
#include <QWebChannel>
@@ -63,6 +64,7 @@ MainWindow::MainWindow(QWidget *parent) :
ui(new Ui::MainWindow)
{
ui->setupUi(this);
+ ui->editor->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
PreviewPage *page = new PreviewPage(this);
ui->preview->setPage(page);
@@ -95,6 +97,19 @@ MainWindow::~MainWindow()
delete ui;
}
+void MainWindow::openFile(const QString &path)
+{
+ QFile f(path);
+ if (!f.open(QIODevice::ReadOnly)) {
+ QMessageBox::warning(this, windowTitle(),
+ tr("Could not open file %1: %2").arg(
+ QDir::toNativeSeparators(path), f.errorString()));
+ return;
+ }
+ m_filePath = path;
+ ui->editor->setPlainText(f.readAll());
+}
+
bool MainWindow::isModified() const
{
return ui->editor->document()->isModified();
@@ -128,15 +143,7 @@ void MainWindow::onFileOpen()
if (path.isEmpty())
return;
- QFile f(path);
- if (!f.open(QIODevice::ReadOnly)) {
- QMessageBox::warning(this, windowTitle(),
- tr("Could not open file %1: %2").arg(
- QDir::toNativeSeparators(path), f.errorString()));
- return;
- }
- m_filePath = path;
- ui->editor->setPlainText(f.readAll());
+ openFile(path);
}
void MainWindow::onFileSave()
diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.h b/examples/webenginewidgets/markdowneditor/mainwindow.h
index 19b6cb036..ad0320373 100644
--- a/examples/webenginewidgets/markdowneditor/mainwindow.h
+++ b/examples/webenginewidgets/markdowneditor/mainwindow.h
@@ -70,6 +70,8 @@ public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
+ void openFile(const QString &path);
+
private slots:
void onFileNew();
void onFileOpen();
diff --git a/examples/webenginewidgets/minimal/doc/images/minimal-example.png b/examples/webenginewidgets/minimal/doc/images/minimal-example.png
new file mode 100644
index 000000000..18ac9b177
--- /dev/null
+++ b/examples/webenginewidgets/minimal/doc/images/minimal-example.png
Binary files differ
diff --git a/examples/webenginewidgets/minimal/doc/src/minimal.qdoc b/examples/webenginewidgets/minimal/doc/src/minimal.qdoc
new file mode 100644
index 000000000..22f28e604
--- /dev/null
+++ b/examples/webenginewidgets/minimal/doc/src/minimal.qdoc
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example webenginewidgets/minimal
+ \title WebEngine Widgets Minimal Example
+ \ingroup webengine-widgetexamples
+ \brief Displays a web page using Qt WebEngine Widgets
+
+ \image minimal-example.png
+
+ \e {WebEngine Widgets Minimal Example} demonstrates how to use
+ \l{QWebEngineView} to render a web page. It shows the minimum amount of code
+ needed to load and display an HTML page, and can be used as a basis for
+ further experimentation.
+
+ \include examples-run.qdocinc
+
+ \section1 The Code
+
+ In \c main.cpp we instantiate a QApplication and a QWebEngineView. The URL
+ to load is set by calling \l QWebEngineView::setUrl. The view widget is
+ given a reasonable default size, and shown.
+ Finally, QApplication::exec() launches the main event loop.
+
+ \quotefromfile webenginewidgets/minimal/main.cpp
+ \skipto #include
+
+ \printuntil }
+
+ \section1 Requirements
+
+ The example requires a working internet connection to render
+ the \l{Qt Homepage}.
+ An optional system proxy should be picked up automatically.
+ However, for proxies that require a username or password,
+ you need to connect to
+ QWebEnginePage::proxyAuthenticationRequired.
+
+ \l{Qt WebEngine Widgets} uses the \l{Qt Quick Scene Graph} to compose the
+ page. Therefore, OpenGL support is required.
+*/
diff --git a/examples/webenginewidgets/minimal/main.cpp b/examples/webenginewidgets/minimal/main.cpp
new file mode 100644
index 000000000..d9a137739
--- /dev/null
+++ b/examples/webenginewidgets/minimal/main.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QWebEngineView>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ QWebEngineView view;
+ view.setUrl(QUrl(QStringLiteral("http://www.qt.io")));
+ view.resize(1024, 750);
+ view.show();
+
+ return app.exec();
+}
diff --git a/examples/webenginewidgets/minimal/minimal.pro b/examples/webenginewidgets/minimal/minimal.pro
new file mode 100644
index 000000000..849f4b9b6
--- /dev/null
+++ b/examples/webenginewidgets/minimal/minimal.pro
@@ -0,0 +1,8 @@
+TEMPLATE = app
+
+QT += webenginewidgets
+
+SOURCES += main.cpp
+
+target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/minimal
+INSTALLS += target
diff --git a/examples/webenginewidgets/simplebrowser/browser.cpp b/examples/webenginewidgets/simplebrowser/browser.cpp
new file mode 100644
index 000000000..78b60b8f8
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/browser.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "browser.h"
+#include "browserwindow.h"
+#include "webview.h"
+#include <QAuthenticator>
+#include <QNetworkProxy>
+#include <QNetworkReply>
+
+Browser::Browser()
+{
+ // QTBUG-47967 , downloading favIcon support is coming in 5.7
+ QObject::connect(&WebView::networkAccessManager(), &QNetworkAccessManager::authenticationRequired,
+ [](QNetworkReply *, QAuthenticator *) {
+ qWarning("Authentication required for downloading favicon.");
+ });
+ QObject::connect(&WebView::networkAccessManager(), &QNetworkAccessManager::proxyAuthenticationRequired,
+ [](const QNetworkProxy &, QAuthenticator *) {
+ qWarning("Proxy authentication required for downloading favicon.");
+ });
+}
+
+Browser::~Browser()
+{
+ qDeleteAll(m_windows);
+ m_windows.clear();
+}
+
+Browser &Browser::instance()
+{
+ static Browser browser;
+ return browser;
+}
+
+QVector<BrowserWindow*> Browser::windows()
+{
+ return m_windows;
+}
+
+void Browser::addWindow(BrowserWindow *mainWindow)
+{
+ if (m_windows.contains(mainWindow))
+ return;
+ m_windows.prepend(mainWindow);
+ QObject::connect(mainWindow, &QObject::destroyed, [this, mainWindow]() {
+ m_windows.removeOne(mainWindow);
+ });
+ mainWindow->show();
+}
+
diff --git a/examples/webenginewidgets/simplebrowser/browser.h b/examples/webenginewidgets/simplebrowser/browser.h
new file mode 100644
index 000000000..0fdbd46a7
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/browser.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BROWSER_H
+#define BROWSER_H
+
+#include <QVector>
+
+class BrowserWindow;
+
+class Browser
+{
+public:
+ ~Browser();
+
+ QVector<BrowserWindow*> windows();
+ void addWindow(BrowserWindow* window);
+ static Browser &instance();
+
+private:
+ Browser();
+ QVector<BrowserWindow*> m_windows;
+};
+#endif // BROWSER_H
diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.cpp b/examples/webenginewidgets/simplebrowser/browserwindow.cpp
new file mode 100644
index 000000000..e7d5fd129
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/browserwindow.cpp
@@ -0,0 +1,437 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "browser.h"
+#include "browserwindow.h"
+#include "tabwidget.h"
+#include "urllineedit.h"
+#include "webview.h"
+#include <QApplication>
+#include <QCloseEvent>
+#include <QDesktopWidget>
+#include <QFileDialog>
+#include <QMenuBar>
+#include <QMessageBox>
+#include <QProgressBar>
+#include <QStatusBar>
+#include <QToolBar>
+#include <QVBoxLayout>
+
+BrowserWindow::BrowserWindow(QWidget *parent, Qt::WindowFlags flags)
+ : QMainWindow(parent, flags)
+ , m_tabWidget(new TabWidget(this))
+ , m_progressBar(new QProgressBar(this))
+ , m_historyBackAction(nullptr)
+ , m_historyForwardAction(nullptr)
+ , m_stopAction(nullptr)
+ , m_reloadAction(nullptr)
+ , m_stopReloadAction(nullptr)
+ , m_urlLineEdit(new UrlLineEdit(this))
+{
+ setToolButtonStyle(Qt::ToolButtonFollowStyle);
+ setAttribute(Qt::WA_DeleteOnClose, true);
+
+ QToolBar *toolbar = createToolBar();
+ addToolBar(toolbar);
+ menuBar()->addMenu(createFileMenu(m_tabWidget));
+ menuBar()->addMenu(createViewMenu(toolbar));
+ menuBar()->addMenu(createWindowMenu(m_tabWidget));
+ menuBar()->addMenu(createHelpMenu());
+
+ QWidget *centralWidget = new QWidget(this);
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->setSpacing(0);
+ layout->setMargin(0);
+ addToolBarBreak();
+
+ m_progressBar->setMaximumHeight(1);
+ m_progressBar->setTextVisible(false);
+ m_progressBar->setStyleSheet(QStringLiteral("QProgressBar {border: 0px } QProgressBar::chunk { background-color: red; }"));
+
+ layout->addWidget(m_progressBar);
+ layout->addWidget(m_tabWidget);
+ centralWidget->setLayout(layout);
+ setCentralWidget(centralWidget);
+
+ connect(m_tabWidget, &TabWidget::titleChanged, this, &BrowserWindow::handleWebViewTitleChanged);
+ connect(m_tabWidget, &TabWidget::linkHovered, [this](const QString& url) {
+ statusBar()->showMessage(url);
+ });
+ connect(m_tabWidget, &TabWidget::loadProgress, this, &BrowserWindow::handleWebViewLoadProgress);
+ connect(m_tabWidget, &TabWidget::urlChanged, this, &BrowserWindow::handleWebViewUrlChanged);
+ connect(m_tabWidget, &TabWidget::iconChanged, this, &BrowserWindow::handleWebViewIconChanged);
+ connect(m_tabWidget, &TabWidget::webActionEnabledChanged, this, &BrowserWindow::handleWebActionEnabledChanged);
+ connect(m_urlLineEdit, &QLineEdit::returnPressed, this, [this]() {
+ m_urlLineEdit->setFavIcon(QIcon(QStringLiteral(":defaulticon.png")));
+ loadPage(m_urlLineEdit->url());
+ });
+
+ m_urlLineEdit->setFavIcon(QIcon(QStringLiteral(":defaulticon.png")));
+
+ handleWebViewTitleChanged(tr("Qt Simple Browser"));
+ m_tabWidget->createTab();
+}
+
+BrowserWindow::~BrowserWindow()
+{
+}
+
+QSize BrowserWindow::sizeHint() const
+{
+ QRect desktopRect = QApplication::desktop()->screenGeometry();
+ QSize size = desktopRect.size() * qreal(0.9);
+ return size;
+}
+
+QMenu *BrowserWindow::createFileMenu(TabWidget *tabWidget)
+{
+ QMenu *fileMenu = new QMenu(tr("&File"));
+ fileMenu->addAction(tr("&New Window"), this, &BrowserWindow::handleNewWindowTriggered, QKeySequence::New);
+
+ QAction *newTabAction = new QAction(QIcon(QLatin1String(":addtab.png")), tr("New &Tab"), this);
+ newTabAction->setShortcuts(QKeySequence::AddTab);
+ newTabAction->setIconVisibleInMenu(false);
+ connect(newTabAction, &QAction::triggered, tabWidget, &TabWidget::createTab);
+ fileMenu->addAction(newTabAction);
+
+ fileMenu->addAction(tr("&Open File..."), this, &BrowserWindow::handleFileOpenTriggered, QKeySequence::Open);
+ fileMenu->addSeparator();
+
+ QAction *closeTabAction = new QAction(QIcon(QLatin1String(":closetab.png")), tr("&Close Tab"), this);
+ closeTabAction->setShortcuts(QKeySequence::Close);
+ closeTabAction->setIconVisibleInMenu(false);
+ connect(closeTabAction, &QAction::triggered, [tabWidget]() {
+ tabWidget->closeTab(tabWidget->currentIndex());
+ });
+ fileMenu->addAction(closeTabAction);
+
+ QAction *closeAction = new QAction(tr("&Quit"),this);
+ closeAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q));
+ connect(closeAction, &QAction::triggered, this, &QWidget::close);
+ fileMenu->addAction(closeAction);
+
+ connect(fileMenu, &QMenu::aboutToShow, [closeAction]() {
+ if (Browser::instance().windows().count() == 1)
+ closeAction->setText(tr("&Quit"));
+ else
+ closeAction->setText(tr("&Close Window"));
+ });
+ return fileMenu;
+}
+
+QMenu *BrowserWindow::createViewMenu(QToolBar *toolbar)
+{
+ QMenu *viewMenu = new QMenu(tr("&View"));
+ m_stopAction = viewMenu->addAction(tr("&Stop"));
+ QList<QKeySequence> shortcuts;
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Period));
+ shortcuts.append(Qt::Key_Escape);
+ m_stopAction->setShortcuts(shortcuts);
+ connect(m_stopAction, &QAction::triggered, [this]() {
+ m_tabWidget->triggerWebPageAction(QWebEnginePage::Stop);
+ });
+
+ m_reloadAction = viewMenu->addAction(tr("Reload Page"));
+ m_reloadAction->setShortcuts(QKeySequence::Refresh);
+ connect(m_reloadAction, &QAction::triggered, [this]() {
+ m_tabWidget->triggerWebPageAction(QWebEnginePage::Reload);
+ });
+
+ QAction *zoomIn = viewMenu->addAction(tr("Zoom &In"));
+ zoomIn->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Plus));
+ connect(zoomIn, &QAction::triggered, [this]() {
+ if (currentTab())
+ currentTab()->setZoomFactor(currentTab()->zoomFactor() + 0.1);
+ });
+
+ QAction *zoomOut = viewMenu->addAction(tr("Zoom &Out"));
+ zoomOut->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Minus));
+ connect(zoomOut, &QAction::triggered, [this]() {
+ if (currentTab())
+ currentTab()->setZoomFactor(currentTab()->zoomFactor() - 0.1);
+ });
+
+ QAction *resetZoom = viewMenu->addAction(tr("Reset &Zoom"));
+ resetZoom->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_0));
+ connect(resetZoom, &QAction::triggered, [this]() {
+ if (currentTab())
+ currentTab()->setZoomFactor(1.0);
+ });
+
+
+ viewMenu->addSeparator();
+ QAction *viewToolbarAction = new QAction(tr("Hide Toolbar"),this);
+ viewToolbarAction->setShortcut(tr("Ctrl+|"));
+ connect(viewToolbarAction, &QAction::triggered, [toolbar,viewToolbarAction]() {
+ if (toolbar->isVisible()) {
+ viewToolbarAction->setText(tr("Show Toolbar"));
+ toolbar->close();
+ } else {
+ viewToolbarAction->setText(tr("Hide Toolbar"));
+ toolbar->show();
+ }
+ });
+ viewMenu->addAction(viewToolbarAction);
+
+ QAction *viewStatusbarAction = new QAction(tr("Hide Status Bar"), this);
+ viewStatusbarAction->setShortcut(tr("Ctrl+/"));
+ connect(viewStatusbarAction, &QAction::triggered, [this, viewStatusbarAction]() {
+ if (statusBar()->isVisible()) {
+ viewStatusbarAction->setText(tr("Show Status Bar"));
+ statusBar()->close();
+ } else {
+ viewStatusbarAction->setText(tr("Hide Status Bar"));
+ statusBar()->show();
+ }
+ });
+ viewMenu->addAction(viewStatusbarAction);
+ return viewMenu;
+}
+
+QMenu *BrowserWindow::createWindowMenu(TabWidget *tabWidget)
+{
+ QMenu *menu = new QMenu(tr("&Window"));
+
+ QAction *nextTabAction = new QAction(tr("Show Next Tab"), this);
+ QList<QKeySequence> shortcuts;
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BraceRight));
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_PageDown));
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BracketRight));
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Less));
+ nextTabAction->setShortcuts(shortcuts);
+ connect(nextTabAction, &QAction::triggered, tabWidget, &TabWidget::nextTab);
+
+ QAction *previousTabAction = new QAction(tr("Show Previous Tab"), this);
+ shortcuts.clear();
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BraceLeft));
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_PageUp));
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BracketLeft));
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Greater));
+ previousTabAction->setShortcuts(shortcuts);
+ connect(previousTabAction, &QAction::triggered, tabWidget, &TabWidget::previousTab);
+
+ connect(menu, &QMenu::aboutToShow, [this, menu, nextTabAction, previousTabAction]() {
+ menu->clear();
+ menu->addAction(nextTabAction);
+ menu->addAction(previousTabAction);
+ menu->addSeparator();
+
+ QVector<BrowserWindow*> windows = Browser::instance().windows();
+ int index(-1);
+ for (auto window : windows) {
+ QAction *action = menu->addAction(window->windowTitle(), this, &BrowserWindow::handleShowWindowTriggered);
+ action->setData(++index);
+ action->setCheckable(true);
+ if (window == this)
+ action->setChecked(true);
+ }
+ });
+ return menu;
+}
+
+QMenu *BrowserWindow::createHelpMenu()
+{
+ QMenu *helpMenu = new QMenu(tr("&Help"));
+ helpMenu->addAction(tr("About &Qt"), qApp, QApplication::aboutQt);
+ return helpMenu;
+}
+
+QToolBar *BrowserWindow::createToolBar()
+{
+ QToolBar *navigationBar = new QToolBar(tr("Navigation"));
+ navigationBar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea);
+ navigationBar->toggleViewAction()->setEnabled(false);
+
+ m_historyBackAction = new QAction(this);
+ m_historyBackAction->setShortcuts(QKeySequence::Back);
+ m_historyBackAction->setIconVisibleInMenu(false);
+ m_historyBackAction->setIcon(QIcon(QStringLiteral(":go-previous.png")));
+ connect(m_historyBackAction, &QAction::triggered, [this]() {
+ m_tabWidget->triggerWebPageAction(QWebEnginePage::Back);
+ });
+ navigationBar->addAction(m_historyBackAction);
+
+ m_historyForwardAction = new QAction(this);
+ m_historyForwardAction->setShortcuts(QKeySequence::Forward);
+ m_historyForwardAction->setIconVisibleInMenu(false);
+ m_historyForwardAction->setIcon(QIcon(QStringLiteral(":go-next.png")));
+ connect(m_historyForwardAction, &QAction::triggered, [this]() {
+ m_tabWidget->triggerWebPageAction(QWebEnginePage::Forward);
+ });
+ navigationBar->addAction(m_historyForwardAction);
+
+ m_stopReloadAction = new QAction(this);
+ connect(m_stopReloadAction, &QAction::triggered, [this]() {
+ m_tabWidget->triggerWebPageAction(QWebEnginePage::WebAction(m_stopReloadAction->data().toInt()));
+ });
+ navigationBar->addAction(m_stopReloadAction);
+ navigationBar->addWidget(m_urlLineEdit);
+ int size = m_urlLineEdit->sizeHint().height();
+ navigationBar->setIconSize(QSize(size, size));
+ return navigationBar;
+}
+
+void BrowserWindow::handleWebViewIconChanged(const QIcon &icon)
+{
+ m_urlLineEdit->setFavIcon(icon);
+}
+
+void BrowserWindow::handleWebViewUrlChanged(const QUrl &url)
+{
+ m_urlLineEdit->setUrl(url);
+ if (url.isEmpty())
+ m_urlLineEdit->setFocus();
+}
+
+void BrowserWindow::handleWebActionEnabledChanged(QWebEnginePage::WebAction action, bool enabled)
+{
+ switch (action) {
+ case QWebEnginePage::Back:
+ m_historyBackAction->setEnabled(enabled);
+ break;
+ case QWebEnginePage::Forward:
+ m_historyForwardAction->setEnabled(enabled);
+ break;
+ case QWebEnginePage::Reload:
+ m_reloadAction->setEnabled(enabled);
+ break;
+ case QWebEnginePage::Stop:
+ m_stopAction->setEnabled(enabled);
+ break;
+ default:
+ qWarning("Unhandled webActionChanged singal");
+ }
+}
+
+void BrowserWindow::handleWebViewTitleChanged(const QString &title)
+{
+ if (title.isEmpty())
+ setWindowTitle(tr("Qt Simple Browser"));
+ else
+ setWindowTitle(tr("%1 - Qt Simple Browser").arg(title));
+}
+
+void BrowserWindow::handleNewWindowTriggered()
+{
+ BrowserWindow *window = new BrowserWindow();
+ Browser::instance().addWindow(window);
+ window->loadHomePage();
+}
+
+void BrowserWindow::handleFileOpenTriggered()
+{
+ QString file = QFileDialog::getOpenFileName(this, tr("Open Web Resource"), QString(),
+ tr("Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*)"));
+ if (file.isEmpty())
+ return;
+ loadPage(file);
+}
+
+void BrowserWindow::closeEvent(QCloseEvent *event)
+{
+ if (m_tabWidget->count() > 1) {
+ int ret = QMessageBox::warning(this, tr("Confirm close"),
+ tr("Are you sure you want to close the window ?\n"
+ "There are %1 tabs open.").arg(m_tabWidget->count()),
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
+ if (ret == QMessageBox::No) {
+ event->ignore();
+ return;
+ }
+ }
+ event->accept();
+ deleteLater();
+}
+
+
+void BrowserWindow::loadHomePage()
+{
+ loadPage(QStringLiteral("http://www.qt.io"));
+}
+
+void BrowserWindow::loadPage(const QString &page)
+{
+ loadPage(QUrl::fromUserInput(page));
+}
+
+void BrowserWindow::loadPage(const QUrl &url)
+{
+ if (url.isValid()) {
+ m_urlLineEdit->setUrl(url);
+ m_tabWidget->setUrl(url);
+ }
+}
+
+TabWidget *BrowserWindow::tabWidget() const
+{
+ return m_tabWidget;
+}
+
+WebView *BrowserWindow::currentTab() const
+{
+ return m_tabWidget->currentWebView();
+}
+
+void BrowserWindow::handleWebViewLoadProgress(int progress)
+{
+ static QIcon stopIcon(QStringLiteral(":process-stop.png"));
+ static QIcon reloadIcon(QStringLiteral(":view-refresh.png"));
+
+ if (progress < 100 && progress > 0) {
+ m_stopReloadAction->setData(QWebEnginePage::Stop);
+ m_stopReloadAction->setIcon(stopIcon);
+ m_stopReloadAction->setToolTip(tr("Stop loading the current page"));
+ } else {
+ m_stopReloadAction->setData(QWebEnginePage::Reload);
+ m_stopReloadAction->setIcon(reloadIcon);
+ m_stopReloadAction->setToolTip(tr("Reload the current page"));
+ }
+ m_progressBar->setValue(progress < 100 ? progress : 0);
+}
+
+void BrowserWindow::handleShowWindowTriggered()
+{
+ if (QAction *action = qobject_cast<QAction*>(sender())) {
+ int offset = action->data().toInt();
+ QVector<BrowserWindow*> windows = Browser::instance().windows();
+ windows.at(offset)->activateWindow();
+ windows.at(offset)->currentTab()->setFocus();
+ }
+}
diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.h b/examples/webenginewidgets/simplebrowser/browserwindow.h
new file mode 100644
index 000000000..c947bed1d
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/browserwindow.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BROWSERWINDOW_H
+#define BROWSERWINDOW_H
+
+#include <QMainWindow>
+#include <QWebEnginePage>
+
+QT_BEGIN_NAMESPACE
+class QProgressBar;
+QT_END_NAMESPACE
+
+class TabWidget;
+class UrlLineEdit;
+class WebView;
+
+class BrowserWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ BrowserWindow(QWidget *parent = nullptr, Qt::WindowFlags flags = 0);
+ ~BrowserWindow();
+ QSize sizeHint() const override;
+ TabWidget *tabWidget() const;
+ WebView *currentTab() const;
+
+ void loadPage(const QString &url);
+ void loadPage(const QUrl &url);
+ void loadHomePage();
+
+protected:
+ void closeEvent(QCloseEvent *event) override;
+
+private slots:
+ void handleNewWindowTriggered();
+ void handleFileOpenTriggered();
+ void handleShowWindowTriggered();
+ void handleWebViewLoadProgress(int);
+ void handleWebViewTitleChanged(const QString &title);
+ void handleWebViewUrlChanged(const QUrl &url);
+ void handleWebViewIconChanged(const QIcon &icon);
+ void handleWebActionEnabledChanged(QWebEnginePage::WebAction action, bool enabled);
+
+private:
+ QMenu *createFileMenu(TabWidget *tabWidget);
+ QMenu *createViewMenu(QToolBar *toolBar);
+ QMenu *createWindowMenu(TabWidget *tabWidget);
+ QMenu *createHelpMenu();
+ QToolBar *createToolBar();
+
+private:
+ TabWidget *m_tabWidget;
+ QProgressBar *m_progressBar;
+ QAction *m_historyBackAction;
+ QAction *m_historyForwardAction;
+ QAction *m_stopAction;
+ QAction *m_reloadAction;
+ QAction *m_stopReloadAction;
+ UrlLineEdit *m_urlLineEdit;
+};
+
+#endif // BROWSERWINDOW_H
diff --git a/examples/webenginewidgets/simplebrowser/certificateerrordialog.ui b/examples/webenginewidgets/simplebrowser/certificateerrordialog.ui
new file mode 100644
index 000000000..a97f25b6e
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/certificateerrordialog.ui
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CertificateErrorDialog</class>
+ <widget class="QDialog" name="CertificateErrorDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>370</width>
+ <height>141</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="leftMargin">
+ <number>20</number>
+ </property>
+ <property name="rightMargin">
+ <number>20</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="m_iconLabel">
+ <property name="text">
+ <string>Icon</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="m_errorLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Error</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="m_infoLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>If you wish so, you may continue with an unverified certificate. Accepting an unverified certificate mean you may not be connected with the host you tried to connect to.
+
+Do you wish to override the security check and continue ? </string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::No|QDialogButtonBox::Yes</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>CertificateErrorDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>CertificateErrorDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/examples/webenginewidgets/simplebrowser/data/addtab.png b/examples/webenginewidgets/simplebrowser/data/addtab.png
new file mode 100644
index 000000000..20928fb40
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/addtab.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/closetab.png b/examples/webenginewidgets/simplebrowser/data/closetab.png
new file mode 100644
index 000000000..ab9d669ee
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/closetab.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/defaulticon.png b/examples/webenginewidgets/simplebrowser/data/defaulticon.png
new file mode 100644
index 000000000..01a0920c9
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/defaulticon.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/go-next.png b/examples/webenginewidgets/simplebrowser/data/go-next.png
new file mode 100644
index 000000000..6f3f65d33
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/go-next.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/go-previous.png b/examples/webenginewidgets/simplebrowser/data/go-previous.png
new file mode 100644
index 000000000..93be3d1ee
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/go-previous.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/process-stop.png b/examples/webenginewidgets/simplebrowser/data/process-stop.png
new file mode 100644
index 000000000..b68290bf1
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/process-stop.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/simplebrowser.qrc b/examples/webenginewidgets/simplebrowser/data/simplebrowser.qrc
new file mode 100644
index 000000000..5795063ca
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/simplebrowser.qrc
@@ -0,0 +1,12 @@
+<RCC>
+ <qresource prefix="/">
+ <file>addtab.png</file>
+ <file>defaulticon.png</file>
+ <file>closetab.png</file>
+ <file>go-next.png</file>
+ <file>go-previous.png</file>
+ <file>process-stop.png</file>
+ <file>simplebrowser.svg</file>
+ <file>view-refresh.png</file>
+ </qresource>
+</RCC>
diff --git a/examples/webenginewidgets/simplebrowser/data/simplebrowser.svg b/examples/webenginewidgets/simplebrowser/data/simplebrowser.svg
new file mode 100644
index 000000000..9f39deb66
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/simplebrowser.svg
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="94px" height="94px" viewBox="0 0 94 94" enable-background="new 0 0 94 94" xml:space="preserve">
+<g>
+ <circle fill="none" cx="47" cy="47" r="47"/>
+ <g>
+ <path fill="#46A2DA" d="M47,92.979c-11.779,0-23.559-4.484-32.526-13.451C-3.461,61.591-3.461,32.409,14.472,14.474
+ C32.41-3.463,61.592-3.461,79.526,14.473c17.935,17.936,17.935,47.119,0.002,65.054l-0.002,0.001
+ C70.559,88.495,58.779,92.979,47,92.979z"/>
+ </g>
+ <path fill="#80C342" d="M93,47C93,21.595,72.405,1,47,1C34.297,1,22.797,6.149,14.473,14.473l65.054,65.054
+ C87.851,71.203,93,59.703,93,47z"/>
+ <g>
+ <path fill="#46A2DA" d="M47,65c-4.808,0-9.328-1.873-12.728-5.272c-7.018-7.019-7.018-18.438,0-25.456
+ C37.672,30.873,42.192,29,47,29s9.328,1.873,12.728,5.272c7.018,7.019,7.018,18.438,0,25.456C56.328,63.127,51.808,65,47,65z"/>
+ <path fill="#FFFFFF" d="M62.248,59.919c6.671-7.858,6.312-19.644-1.105-27.061C57.237,28.953,52.118,27,47,27
+ c-5.118,0-10.237,1.953-14.142,5.858c-7.81,7.81-7.81,20.474,0,28.284C36.763,65.047,41.882,67,47,67
+ c4.379,0,8.752-1.441,12.372-4.3L77.88,81.209c0.989-0.895,1.935-1.837,2.843-2.814L62.248,59.919z M35.686,58.314
+ c-6.238-6.238-6.238-16.389,0-22.627C38.708,32.664,42.726,31,47,31c4.274,0,8.292,1.664,11.314,4.686
+ c6.238,6.238,6.238,16.389,0,22.627C55.292,61.336,51.274,63,47,63C42.726,63,38.708,61.336,35.686,58.314z"/>
+ </g>
+</g>
+</svg>
diff --git a/examples/webenginewidgets/simplebrowser/data/view-refresh.png b/examples/webenginewidgets/simplebrowser/data/view-refresh.png
new file mode 100644
index 000000000..cab4d02c7
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/view-refresh.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser-model.png b/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser-model.png
new file mode 100644
index 000000000..2a1abce50
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser-model.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser.png b/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser.png
new file mode 100644
index 000000000..777309075
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser-model.qmodel b/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser-model.qmodel
new file mode 100644
index 000000000..ce6f8ea2a
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser-model.qmodel
@@ -0,0 +1,938 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<qmt>
+ <project>
+ <uid>{fa2cc127-337e-4194-b272-fc8bb6c1e3b0}</uid>
+ <root-package>
+ <instance>
+ <MPackage>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{4ffa8932-4330-4845-af33-c26f0fcdecd7}</uid>
+ </MElement>
+ </base-MElement>
+ <name>simplebrowser-model</name>
+ <children>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{de670101-4064-4a81-bdf0-885b4cb09526}</uid>
+ <target>
+ <instance type="MCanvasDiagram">
+ <MCanvasDiagram>
+ <base-MDiagram>
+ <MDiagram>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{de670101-4064-4a81-bdf0-885b4cb09526}</uid>
+ </MElement>
+ </base-MElement>
+ <name>simplebrowser-model</name>
+ </MObject>
+ </base-MObject>
+ <elements>
+ <qlist>
+ <item>
+ <instance type="DClass">
+ <DClass>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{b7b131f9-5e56-484a-ba8b-c7a5fc34fb7b}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{ee93b67f-4caf-4d92-9303-f6c2582bf1b9}</object>
+ <name>BrowserWindow</name>
+ <pos>x:190;y:100</pos>
+ <rect>x:-55;y:-30;w:110;h:60</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ </DClass>
+ </instance>
+ </item>
+ <item>
+ <instance type="DClass">
+ <DClass>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{8d3e6a00-ffa6-497a-a5a2-f1ba13deee76}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{72a2b731-3aad-430f-a76c-f43dd9b36462}</object>
+ <name>Browser</name>
+ <pos>x:5;y:100</pos>
+ <rect>x:-55;y:-30;w:110;h:60</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ </DClass>
+ </instance>
+ </item>
+ <item>
+ <instance type="DAssociation">
+ <DAssociation>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{5ab59ef4-3509-4ea3-900e-20d1cea16af1}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{e878ee71-b5d1-4943-b081-466851b0f721}</object>
+ <a>{8d3e6a00-ffa6-497a-a5a2-f1ba13deee76}</a>
+ <b>{b7b131f9-5e56-484a-ba8b-c7a5fc34fb7b}</b>
+ </DRelation>
+ </base-DRelation>
+ <a>
+ <DAssociationEnd>
+ <cradinality>1..*</cradinality>
+ <kind>2</kind>
+ </DAssociationEnd>
+ </a>
+ <b>
+ <DAssociationEnd>
+ <cradinality>1</cradinality>
+ </DAssociationEnd>
+ </b>
+ </DAssociation>
+ </instance>
+ </item>
+ <item>
+ <instance type="DClass">
+ <DClass>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{487d395c-3f8b-422c-9568-d70a5d50a9d4}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{1ab2b778-127b-4661-ba2d-8f329f44d859}</object>
+ <name>TabWidget</name>
+ <pos>x:360;y:100</pos>
+ <rect>x:-55;y:-30;w:110;h:60</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ </DClass>
+ </instance>
+ </item>
+ <item>
+ <instance type="DAssociation">
+ <DAssociation>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{cc9dee75-9f9c-4599-acf8-35e14f75cd78}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{ee3a86b4-773d-4ea5-81c1-552501061629}</object>
+ <a>{b7b131f9-5e56-484a-ba8b-c7a5fc34fb7b}</a>
+ <b>{487d395c-3f8b-422c-9568-d70a5d50a9d4}</b>
+ </DRelation>
+ </base-DRelation>
+ <a>
+ <DAssociationEnd>
+ <cradinality>1</cradinality>
+ </DAssociationEnd>
+ </a>
+ <b>
+ <DAssociationEnd>
+ <cradinality>1</cradinality>
+ </DAssociationEnd>
+ </b>
+ </DAssociation>
+ </instance>
+ </item>
+ <item>
+ <instance type="DClass">
+ <DClass>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{9d909ab7-02a8-4582-89cd-b31bb794bc40}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{b8a281e2-4ee3-42cd-bb3d-d075a54ad358}</object>
+ <name>WebView</name>
+ <pos>x:550;y:100</pos>
+ <rect>x:-55;y:-30;w:110;h:60</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ </DClass>
+ </instance>
+ </item>
+ <item>
+ <instance type="DAssociation">
+ <DAssociation>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{1e82e3ce-c835-4b7a-99ec-ae40e07f0185}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{97fd8235-200e-4448-b173-51add1df8edc}</object>
+ <a>{487d395c-3f8b-422c-9568-d70a5d50a9d4}</a>
+ <b>{9d909ab7-02a8-4582-89cd-b31bb794bc40}</b>
+ </DRelation>
+ </base-DRelation>
+ <a>
+ <DAssociationEnd>
+ <cradinality>1..*</cradinality>
+ <kind>2</kind>
+ </DAssociationEnd>
+ </a>
+ <b>
+ <DAssociationEnd>
+ <cradinality>1</cradinality>
+ </DAssociationEnd>
+ </b>
+ </DAssociation>
+ </instance>
+ </item>
+ <item>
+ <instance type="DClass">
+ <DClass>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{ed0a94cd-0abd-49f6-ac98-3da13fef9dff}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{320f3a48-12de-4bcb-b7f5-47b12c77dbee}</object>
+ <name>WebPage</name>
+ <pos>x:720;y:100</pos>
+ <rect>x:-55;y:-30;w:110;h:60</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ </DClass>
+ </instance>
+ </item>
+ <item>
+ <instance type="DAssociation">
+ <DAssociation>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{06ce5b46-b043-45b8-8718-0054d7baf939}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{772227ff-d0df-4ecd-97ea-89d1bd10a96f}</object>
+ <a>{9d909ab7-02a8-4582-89cd-b31bb794bc40}</a>
+ <b>{ed0a94cd-0abd-49f6-ac98-3da13fef9dff}</b>
+ </DRelation>
+ </base-DRelation>
+ <a>
+ <DAssociationEnd>
+ <cradinality>1</cradinality>
+ </DAssociationEnd>
+ </a>
+ <b>
+ <DAssociationEnd>
+ <cradinality>1</cradinality>
+ </DAssociationEnd>
+ </b>
+ </DAssociation>
+ </instance>
+ </item>
+ <item>
+ <instance type="DClass">
+ <DClass>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{cb588414-35d6-482f-a9df-2dddb7d72af1}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{9b91aa7b-0fa3-4c78-9e8d-e1bfdfce9f7f}</object>
+ <name>QWebEngineView</name>
+ <pos>x:550;y:0</pos>
+ <rect>x:-55;y:-30;w:110;h:60</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ </DClass>
+ </instance>
+ </item>
+ <item>
+ <instance type="DClass">
+ <DClass>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{c9755d3b-0ed4-4821-95d3-64f4f4cdb458}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{6659de40-605d-4744-8654-73ae959dcb8a}</object>
+ <name>QWebEnginePage</name>
+ <pos>x:720;y:0</pos>
+ <rect>x:-50;y:-30;w:100;h:60</rect>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ </DClass>
+ </instance>
+ </item>
+ <item>
+ <instance type="DInheritance">
+ <DInheritance>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{6bdcd7e9-fa78-417d-9024-47796596e18d}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{1176aee6-be27-4b21-be22-33bca908a71e}</object>
+ <a>{9d909ab7-02a8-4582-89cd-b31bb794bc40}</a>
+ <b>{cb588414-35d6-482f-a9df-2dddb7d72af1}</b>
+ </DRelation>
+ </base-DRelation>
+ </DInheritance>
+ </instance>
+ </item>
+ <item>
+ <instance type="DInheritance">
+ <DInheritance>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{30abce68-7fa1-4b0c-8620-9f96c7392be7}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{20788ccc-cab0-406b-8cf4-d8062570085e}</object>
+ <a>{ed0a94cd-0abd-49f6-ac98-3da13fef9dff}</a>
+ <b>{c9755d3b-0ed4-4821-95d3-64f4f4cdb458}</b>
+ </DRelation>
+ </base-DRelation>
+ </DInheritance>
+ </instance>
+ </item>
+ <item>
+ <instance type="DClass">
+ <DClass>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{a372397b-316a-48c0-b99f-724372413a64}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{32e677d2-4bfb-4f5d-93dc-67fdb1a0c8a1}</object>
+ <name>QTabWidget</name>
+ <pos>x:360;y:0</pos>
+ <rect>x:-55;y:-30;w:110;h:60</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ </DClass>
+ </instance>
+ </item>
+ <item>
+ <instance type="DInheritance">
+ <DInheritance>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{dce2499c-fdef-40e3-ba77-29b94f8beb1b}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{66fd2699-e4ea-4312-990a-7488c75fc850}</object>
+ <a>{487d395c-3f8b-422c-9568-d70a5d50a9d4}</a>
+ <b>{a372397b-316a-48c0-b99f-724372413a64}</b>
+ </DRelation>
+ </base-DRelation>
+ </DInheritance>
+ </instance>
+ </item>
+ <item>
+ <instance type="DClass">
+ <DClass>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{35e8a91e-8192-4e17-b6c7-e44b3ba3a138}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{988c1b8e-1e9a-4d03-b9b4-75ba5dcac6d7}</object>
+ <name>QMainWindow</name>
+ <pos>x:190;y:0</pos>
+ <rect>x:-55;y:-30;w:110;h:60</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ </DClass>
+ </instance>
+ </item>
+ <item>
+ <instance type="DInheritance">
+ <DInheritance>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{7dd17b0c-4256-463f-8852-c4faf0614997}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{9f29593e-b0b5-4488-ae5d-2378857535a0}</object>
+ <a>{b7b131f9-5e56-484a-ba8b-c7a5fc34fb7b}</a>
+ <b>{35e8a91e-8192-4e17-b6c7-e44b3ba3a138}</b>
+ </DRelation>
+ </base-DRelation>
+ </DInheritance>
+ </instance>
+ </item>
+ </qlist>
+ </elements>
+ <last-modified>1456935246527</last-modified>
+ </MDiagram>
+ </base-MDiagram>
+ </MCanvasDiagram>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{72a2b731-3aad-430f-a76c-f43dd9b36462}</uid>
+ <target>
+ <instance type="MClass">
+ <MClass>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{72a2b731-3aad-430f-a76c-f43dd9b36462}</uid>
+ <flags>1</flags>
+ </MElement>
+ </base-MElement>
+ <name>Browser</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{736a9cc9-35f1-47c1-bdc4-c3033d14a33d}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{736a9cc9-35f1-47c1-bdc4-c3033d14a33d}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{72a2b731-3aad-430f-a76c-f43dd9b36462}</a>
+ <b>{ee93b67f-4caf-4d92-9303-f6c2582bf1b9}</b>
+ </MRelation>
+ </base-MRelation>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{e878ee71-b5d1-4943-b081-466851b0f721}</uid>
+ <target>
+ <instance type="MAssociation">
+ <MAssociation>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{e878ee71-b5d1-4943-b081-466851b0f721}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{72a2b731-3aad-430f-a76c-f43dd9b36462}</a>
+ <b>{ee93b67f-4caf-4d92-9303-f6c2582bf1b9}</b>
+ </MRelation>
+ </base-MRelation>
+ <a>
+ <MAssociationEnd>
+ <cardinality>1..*</cardinality>
+ <kind>2</kind>
+ </MAssociationEnd>
+ </a>
+ <b>
+ <MAssociationEnd>
+ <cardinality>1</cardinality>
+ </MAssociationEnd>
+ </b>
+ </MAssociation>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MClass>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{ee93b67f-4caf-4d92-9303-f6c2582bf1b9}</uid>
+ <target>
+ <instance type="MClass">
+ <MClass>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{ee93b67f-4caf-4d92-9303-f6c2582bf1b9}</uid>
+ <flags>1</flags>
+ </MElement>
+ </base-MElement>
+ <name>BrowserWindow</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{ee3a86b4-773d-4ea5-81c1-552501061629}</uid>
+ <target>
+ <instance type="MAssociation">
+ <MAssociation>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{ee3a86b4-773d-4ea5-81c1-552501061629}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{ee93b67f-4caf-4d92-9303-f6c2582bf1b9}</a>
+ <b>{1ab2b778-127b-4661-ba2d-8f329f44d859}</b>
+ </MRelation>
+ </base-MRelation>
+ <a>
+ <MAssociationEnd>
+ <cardinality>1</cardinality>
+ </MAssociationEnd>
+ </a>
+ <b>
+ <MAssociationEnd>
+ <cardinality>1</cardinality>
+ </MAssociationEnd>
+ </b>
+ </MAssociation>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{9f29593e-b0b5-4488-ae5d-2378857535a0}</uid>
+ <target>
+ <instance type="MInheritance">
+ <MInheritance>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{9f29593e-b0b5-4488-ae5d-2378857535a0}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{ee93b67f-4caf-4d92-9303-f6c2582bf1b9}</a>
+ <b>{988c1b8e-1e9a-4d03-b9b4-75ba5dcac6d7}</b>
+ </MRelation>
+ </base-MRelation>
+ </MInheritance>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MClass>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{1ab2b778-127b-4661-ba2d-8f329f44d859}</uid>
+ <target>
+ <instance type="MClass">
+ <MClass>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{1ab2b778-127b-4661-ba2d-8f329f44d859}</uid>
+ <flags>1</flags>
+ </MElement>
+ </base-MElement>
+ <name>TabWidget</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{97fd8235-200e-4448-b173-51add1df8edc}</uid>
+ <target>
+ <instance type="MAssociation">
+ <MAssociation>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{97fd8235-200e-4448-b173-51add1df8edc}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{1ab2b778-127b-4661-ba2d-8f329f44d859}</a>
+ <b>{b8a281e2-4ee3-42cd-bb3d-d075a54ad358}</b>
+ </MRelation>
+ </base-MRelation>
+ <a>
+ <MAssociationEnd>
+ <cardinality>1..*</cardinality>
+ <kind>2</kind>
+ </MAssociationEnd>
+ </a>
+ <b>
+ <MAssociationEnd>
+ <cardinality>1</cardinality>
+ </MAssociationEnd>
+ </b>
+ </MAssociation>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{66fd2699-e4ea-4312-990a-7488c75fc850}</uid>
+ <target>
+ <instance type="MInheritance">
+ <MInheritance>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{66fd2699-e4ea-4312-990a-7488c75fc850}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{1ab2b778-127b-4661-ba2d-8f329f44d859}</a>
+ <b>{32e677d2-4bfb-4f5d-93dc-67fdb1a0c8a1}</b>
+ </MRelation>
+ </base-MRelation>
+ </MInheritance>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MClass>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{320f3a48-12de-4bcb-b7f5-47b12c77dbee}</uid>
+ <target>
+ <instance type="MClass">
+ <MClass>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{320f3a48-12de-4bcb-b7f5-47b12c77dbee}</uid>
+ <flags>1</flags>
+ </MElement>
+ </base-MElement>
+ <name>WebPage</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{20788ccc-cab0-406b-8cf4-d8062570085e}</uid>
+ <target>
+ <instance type="MInheritance">
+ <MInheritance>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{20788ccc-cab0-406b-8cf4-d8062570085e}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{320f3a48-12de-4bcb-b7f5-47b12c77dbee}</a>
+ <b>{6659de40-605d-4744-8654-73ae959dcb8a}</b>
+ </MRelation>
+ </base-MRelation>
+ </MInheritance>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MClass>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{b8a281e2-4ee3-42cd-bb3d-d075a54ad358}</uid>
+ <target>
+ <instance type="MClass">
+ <MClass>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{b8a281e2-4ee3-42cd-bb3d-d075a54ad358}</uid>
+ <flags>1</flags>
+ </MElement>
+ </base-MElement>
+ <name>WebView</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{772227ff-d0df-4ecd-97ea-89d1bd10a96f}</uid>
+ <target>
+ <instance type="MAssociation">
+ <MAssociation>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{772227ff-d0df-4ecd-97ea-89d1bd10a96f}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{b8a281e2-4ee3-42cd-bb3d-d075a54ad358}</a>
+ <b>{320f3a48-12de-4bcb-b7f5-47b12c77dbee}</b>
+ </MRelation>
+ </base-MRelation>
+ <a>
+ <MAssociationEnd>
+ <cardinality>1</cardinality>
+ </MAssociationEnd>
+ </a>
+ <b>
+ <MAssociationEnd>
+ <cardinality>1</cardinality>
+ </MAssociationEnd>
+ </b>
+ </MAssociation>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{1176aee6-be27-4b21-be22-33bca908a71e}</uid>
+ <target>
+ <instance type="MInheritance">
+ <MInheritance>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{1176aee6-be27-4b21-be22-33bca908a71e}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{b8a281e2-4ee3-42cd-bb3d-d075a54ad358}</a>
+ <b>{9b91aa7b-0fa3-4c78-9e8d-e1bfdfce9f7f}</b>
+ </MRelation>
+ </base-MRelation>
+ </MInheritance>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MClass>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{9b91aa7b-0fa3-4c78-9e8d-e1bfdfce9f7f}</uid>
+ <target>
+ <instance type="MClass">
+ <MClass>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{9b91aa7b-0fa3-4c78-9e8d-e1bfdfce9f7f}</uid>
+ </MElement>
+ </base-MElement>
+ <name>QWebEngineView</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{5124d95d-73fb-4d70-aa89-1135f2202c2f}</uid>
+ <target>
+ <instance type="MInheritance">
+ <MInheritance>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{5124d95d-73fb-4d70-aa89-1135f2202c2f}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{9b91aa7b-0fa3-4c78-9e8d-e1bfdfce9f7f}</a>
+ <b>{b8a281e2-4ee3-42cd-bb3d-d075a54ad358}</b>
+ </MRelation>
+ </base-MRelation>
+ </MInheritance>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MClass>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{6659de40-605d-4744-8654-73ae959dcb8a}</uid>
+ <target>
+ <instance type="MClass">
+ <MClass>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{6659de40-605d-4744-8654-73ae959dcb8a}</uid>
+ </MElement>
+ </base-MElement>
+ <name>QWebEnginePage</name>
+ </MObject>
+ </base-MObject>
+ </MClass>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{32e677d2-4bfb-4f5d-93dc-67fdb1a0c8a1}</uid>
+ <target>
+ <instance type="MClass">
+ <MClass>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{32e677d2-4bfb-4f5d-93dc-67fdb1a0c8a1}</uid>
+ </MElement>
+ </base-MElement>
+ <name>QTabWidget</name>
+ </MObject>
+ </base-MObject>
+ </MClass>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{988c1b8e-1e9a-4d03-b9b4-75ba5dcac6d7}</uid>
+ <target>
+ <instance type="MClass">
+ <MClass>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{988c1b8e-1e9a-4d03-b9b4-75ba5dcac6d7}</uid>
+ </MElement>
+ </base-MElement>
+ <name>QMainWindow</name>
+ </MObject>
+ </base-MObject>
+ </MClass>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </children>
+ </MObject>
+ </base-MObject>
+ </MPackage>
+ </instance>
+ </root-package>
+ </project>
+</qmt>
diff --git a/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc b/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc
new file mode 100644
index 000000000..b8df9b02a
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc
@@ -0,0 +1,263 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example webenginewidgets/simplebrowser
+ \title WebEngine Widgets Simple Browser Example
+ \ingroup webengine-widgetexamples
+ \brief A simple browser based on Qt WebEngine Widgets
+
+ \image simplebrowser.png
+
+ \e {Simple Browser} demonstrates how to use the
+ \l{Qt WebEngine Widgets C++ Classes}{Qt WebEngine C++ classes} to develop a
+ small Web browser application that contains the following elements:
+
+ \list
+ \li Menu bar for opening stored pages and managing windows and tabs.
+ \li Navigation bar for entering a URL and for moving backward and
+ forward in the web page browsing history.
+ \li Multi-tab area for displaying web content within tabs.
+ \li Status bar for displaying hovered links.
+ \endlist
+
+ The web content can be opened in new tabs or separate windows. HTTP and
+ proxy authentication can be used for accessing web pages.
+
+ \include examples-run.qdocinc
+
+ \section1 Class Hierarchy
+
+ We start with sketching a diagram of the classes that we are going to
+ implement:
+
+ \image simplebrowser-model.png
+
+ \list
+ \li \c{Browser} is a singleton class managing the application windows.
+ \li \c{BrowserWindow} is a \l QMainWindow showing the menu, a navigation
+ bar, \c {TabWidget}, and a status bar.
+ \li \c{TabWidget} is a \l QTabWidget and contains one or multiple
+ browser tabs.
+ \li \c{WebView} is a \l QWebEngineView, provides a view for \c{WebPage},
+ and is added as a tab in \c{TabWidget}.
+ \li \c{WebPage} is a \l QWebEnginePage that represents website content.
+ \endlist
+
+ \section1 Creating the Browser Main Window
+
+ This example supports multiple main windows that are owned by a
+ \c Browser singleton object. This class could also be used for further
+ functionality, such as downloading files, bookmarks, and history managers.
+
+ In \c main.cpp, we create the first \c BrowserWindow instance and add it
+ to the \c Browser object. If no arguments are passed on the command line,
+ we open the \l{Qt Homepage}:
+
+ \quotefromfile webenginewidgets/simplebrowser/main.cpp
+ \skipto main
+ \printuntil }
+
+ \section1 Creating Tabs
+
+ The \c BrowserWindow constructor initializes all the necessary user interface
+ related objects. The \c centralWidget of \c BrowserWindow contains an instance of
+ \c TabWidget. The \c TabWidget contains one or several \c WebView instances as tabs,
+ and delegates it's signals and slots to the currently selected one:
+
+ \quotefromfile webenginewidgets/simplebrowser/tabwidget.h
+ \skipto TabWidget :
+ \printuntil {
+ \dots
+ \skipto signals
+ \printuntil triggerWebPageAction
+ \skipto }
+ \dots
+ \printline };
+
+ Each tab contains an instance of \c WebView:
+
+ \quotefromfile webenginewidgets/simplebrowser/tabwidget.cpp
+ \skipto TabWidget::createTab(
+ \printuntil }
+
+ In \c TabWidget::setupView(), we make sure that the \c TabWidget always forwards
+ the signals of the currently selected \c WebView:
+
+ \quotefromfile webenginewidgets/simplebrowser/tabwidget.cpp
+ \skipto TabWidget::setupView
+ \printuntil emit loadProgress
+ \skipto closeTab
+ \skipto });
+ \printline }
+ \dots
+ \printline }
+
+ \section1 Implementing WebView Functionality
+
+ The \c WebView is derived from QWebEngineView to support the following
+ functionality:
+
+ \list
+ \li Downloading favicons
+ \li Displaying error messages in case \c renderProcess dies
+ \li Handling \c createWindow requests
+ \li Adding custom menu items to context menus
+ \endlist
+
+ First, we create the WebView with the necessary methods and signals:
+
+ \quotefromfile webenginewidgets/simplebrowser/webview.h
+ \skipto WebView :
+ \printuntil WebView(
+ \dots
+ \skipto protected:
+ \printuntil handleIconLoaded
+ \skipto }
+ \dots
+ \printline };
+
+ \section2 Downloading Favicons
+
+ To download a favicon, we use QNetworkAccessManager and create a
+ QNetworkRequest every time the URL specified by
+ QWebEngineView::iconUrlChanged is emitted:
+
+ \quotefromfile webenginewidgets/simplebrowser/webview.cpp
+ \skipto WebView::handleIconUrlChanged(
+ \printuntil }
+
+ \section2 Displaying Error Messages
+
+ If the render process is terminated, we display a QMessageBox with an error
+ code, and then we reload the page:
+
+ \quotefromfile webenginewidgets/simplebrowser/webview.cpp
+ \skipto WebView::WebView(QWidget *parent)
+ \printuntil {
+ \skipto renderProcessTerminated
+ \dots
+ \printuntil QTimer
+ \printline });
+ \printline }
+
+ \section2 Managing WebWindows
+
+ The loaded page might want to create windows of the type
+ QWebEnginePage::WebWindowType, for example, when a JavaScript program
+ requests to open a document in a new window or dialog.
+ This is handled by overriding \c QWebView::createWindow():
+
+ \skipto WebView::createWindow(
+ \printuntil return nullptr;
+ \printuntil }
+
+ In case of \c QWebEnginePage::WebDialog, we create an instance of a custom \c WebPopupWindow class:
+
+ \quotefromfile webenginewidgets/simplebrowser/webpopupwindow.h
+ \skipto class WebPopupWindow
+ \printuntil };
+
+ \section2 Adding Context Menu Items
+
+ We add menu items to the context menu, so that users can right-click a link
+ to have it opened in the same tab, a new window, or a new tab. We override
+ QWebEngineView::contextMenuEvent and use
+ QWebEnginePage::createStandardContextMenu to create a default QMenu with a
+ default list of QWebEnginePage::WebAction actions.
+
+ The default name for QWebEnginePage::OpenLinkInThisWindow action is
+ \uicontrol Follow. For clarity, we rename it
+ \uicontrol {Open Link in This Tab}. Also, we add the actions for opening
+ links in a separate window or in a new tab:
+
+ \quotefromfile webenginewidgets/simplebrowser/webview.cpp
+ \skipto WebView::contextMenuEvent(
+ \printuntil menu->popup
+ \printline }
+
+ \section1 Implementing WebPage Functionality
+
+ As mentioned earlier, each \c WebView contains a \c WebPage instance that
+ was created by using QWebEngineProfile::defaultProfile().
+
+ We implement \c WebPage as a subclass of QWebEnginePage to enable HTTP,
+ proxy authentication, and ignoring SSL certificate errors when accessing web
+ pages:
+
+ \quotefromfile webenginewidgets/simplebrowser/webpage.h
+ \skipto WebPage :
+ \printuntil }
+
+ In all the cases above, we display the appropriate dialog to the user. In
+ case of authentication, we need to set the correct credential values on the
+ QAuthenticator object:
+
+ \quotefromfile webenginewidgets/simplebrowser/webpage.cpp
+ \skipto WebPage::handleAuthenticationRequired(
+ \printuntil }
+ \printuntil }
+ \printline }
+
+ The \c handleProxyAuthenticationRequired signal handler implements the very same
+ steps for the authentication of HTTP proxies.
+
+ In case of SSL errors, we just need to return a boolean value indicating
+ whether the certificate should be ignored.
+
+ \quotefromfile webenginewidgets/simplebrowser/webpage.cpp
+ \skipto WebPage::certificateError(
+ \printuntil }
+ \printuntil }
+
+ \section1 Opening a Web Page
+
+ This section describes the workflow for opening a new page.
+ When the user enters a URL in the navigation bar and presses \uicontrol Enter,
+ \c QLineEdit::returnPressed is emitted, which lets \c BrowserWindow
+ load the requested page:
+
+ \quotefromfile webenginewidgets/simplebrowser/browserwindow.cpp
+ \skipto connect(m_urlLineEdit
+ \printuntil });
+
+ The \c loadPage() method calls the \c setUrl() method of \c TabWidget:
+
+ \skipto void BrowserWindow::loadPage(const QUrl
+ \printuntil }
+ \printline }
+
+ The call is forwarded to the currently selected tab:
+
+ \quotefromfile webenginewidgets/simplebrowser/tabwidget.cpp
+ \skipto TabWidget::setUrl(
+ \printuntil }
+ \printuntil }
+
+ The \c setUrl() method of \c WebView just forwards the \c url to the associated \c WebPage,
+ which in turn starts the downloading of the page's content in the background.
+*/
diff --git a/examples/webenginewidgets/simplebrowser/main.cpp b/examples/webenginewidgets/simplebrowser/main.cpp
new file mode 100644
index 000000000..761403fb5
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/main.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "browser.h"
+#include "browserwindow.h"
+#include <QApplication>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ app.setWindowIcon(QIcon(QLatin1String(":simplebrowser.svg")));
+
+ BrowserWindow *window = new BrowserWindow();
+ Browser::instance().addWindow(window);
+
+ QStringList args = QCoreApplication::arguments();
+ if (args.count() > 1)
+ window->loadPage(args.last());
+ else
+ window->loadHomePage();
+
+ return app.exec();
+}
diff --git a/examples/webenginewidgets/simplebrowser/passworddialog.ui b/examples/webenginewidgets/simplebrowser/passworddialog.ui
new file mode 100644
index 000000000..bbf5004f5
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/passworddialog.ui
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PasswordDialog</class>
+ <widget class="QDialog" name="PasswordDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>399</width>
+ <height>148</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Authentication Required</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout" columnstretch="0,0" columnminimumwidth="0,0">
+ <item row="0" column="0">
+ <widget class="QLabel" name="m_iconLabel">
+ <property name="text">
+ <string>Icon</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="m_infoLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Info</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="userLabel">
+ <property name="text">
+ <string>Username:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="m_userNameLineEdit"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="passwordLabel">
+ <property name="text">
+ <string>Password:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="m_passwordLineEdit">
+ <property name="echoMode">
+ <enum>QLineEdit::Password</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ <zorder>userLabel</zorder>
+ <zorder>m_userNameLineEdit</zorder>
+ <zorder>passwordLabel</zorder>
+ <zorder>m_passwordLineEdit</zorder>
+ <zorder>buttonBox</zorder>
+ <zorder>m_iconLabel</zorder>
+ <zorder>m_infoLabel</zorder>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>PasswordDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>PasswordDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/examples/webenginewidgets/simplebrowser/simplebrowser.pro b/examples/webenginewidgets/simplebrowser/simplebrowser.pro
new file mode 100644
index 000000000..ad8a9a2bd
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/simplebrowser.pro
@@ -0,0 +1,33 @@
+TEMPLATE = app
+TARGET = simplebrowser
+QT += webenginewidgets network
+CONFIG += c++11
+
+HEADERS += \
+ browser.h \
+ browserwindow.h \
+ tabwidget.h \
+ urllineedit.h \
+ webview.h \
+ webpage.h \
+ webpopupwindow.h
+
+SOURCES += \
+ browser.cpp \
+ browserwindow.cpp \
+ main.cpp \
+ tabwidget.cpp \
+ urllineedit.cpp \
+ webview.cpp \
+ webpage.cpp \
+ webpopupwindow.cpp
+
+FORMS += \
+ certificateerrordialog.ui \
+ passworddialog.ui
+
+RESOURCES += data/simplebrowser.qrc
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/simplebrowser
+INSTALLS += target
diff --git a/examples/webenginewidgets/simplebrowser/tabwidget.cpp b/examples/webenginewidgets/simplebrowser/tabwidget.cpp
new file mode 100644
index 000000000..d9e0dea1b
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/tabwidget.cpp
@@ -0,0 +1,277 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tabwidget.h"
+#include "webpage.h"
+#include "webview.h"
+#include <QMenu>
+#include <QTabBar>
+#include <QWebEngineProfile>
+
+TabWidget::TabWidget(QWidget *parent)
+ : QTabWidget(parent)
+{
+ QTabBar *tabBar = this->tabBar();
+ tabBar->setTabsClosable(true);
+ tabBar->setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab);
+ tabBar->setMovable(true);
+ tabBar->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(tabBar, &QTabBar::customContextMenuRequested, this, &TabWidget::handleContextMenuRequested);
+ connect(tabBar, &QTabBar::tabCloseRequested, this, &TabWidget::closeTab);
+ connect(tabBar, &QTabBar::tabBarDoubleClicked, [this](int index) {
+ if (index != -1)
+ return;
+ createTab();
+ });
+
+ setDocumentMode(true);
+ setElideMode(Qt::ElideRight);
+
+ connect(this, &QTabWidget::currentChanged, this, &TabWidget::handleCurrentChanged);
+}
+
+TabWidget::~TabWidget()
+{
+}
+
+void TabWidget::handleCurrentChanged(int index)
+{
+ if (index != -1) {
+ WebView *view = webView(index);
+ if (!view->url().isEmpty())
+ view->setFocus();
+ emit titleChanged(view->title());
+ emit loadProgress(view->loadProgress());
+ emit urlChanged(view->url());
+ emit iconChanged(view->icon());
+ emit webActionEnabledChanged(QWebEnginePage::Back, view->isWebActionEnabled(QWebEnginePage::Back));
+ emit webActionEnabledChanged(QWebEnginePage::Forward, view->isWebActionEnabled(QWebEnginePage::Forward));
+ emit webActionEnabledChanged(QWebEnginePage::Stop, view->isWebActionEnabled(QWebEnginePage::Stop));
+ emit webActionEnabledChanged(QWebEnginePage::Reload,view->isWebActionEnabled(QWebEnginePage::Reload));
+ } else {
+ emit titleChanged(QString());
+ emit loadProgress(0);
+ emit urlChanged(QUrl());
+ emit iconChanged(QIcon());
+ emit webActionEnabledChanged(QWebEnginePage::Back, false);
+ emit webActionEnabledChanged(QWebEnginePage::Forward, false);
+ emit webActionEnabledChanged(QWebEnginePage::Stop, false);
+ emit webActionEnabledChanged(QWebEnginePage::Reload, true);
+ }
+}
+
+void TabWidget::handleContextMenuRequested(const QPoint &pos)
+{
+ QMenu menu;
+ menu.addAction(tr("New &Tab"), this, &TabWidget::createTab, QKeySequence::AddTab);
+ int index = tabBar()->tabAt(pos);
+ if (index != -1) {
+ QAction *action = menu.addAction(tr("Clone Tab"));
+ connect(action, &QAction::triggered, this, [this,index]() {
+ cloneTab(index);
+ });
+ menu.addSeparator();
+ action = menu.addAction(tr("&Close Tab"));
+ action->setShortcut(QKeySequence::Close);
+ connect(action, &QAction::triggered, this, [this,index]() {
+ closeTab(index);
+ });
+ action = menu.addAction(tr("Close &Other Tabs"));
+ connect(action, &QAction::triggered, this, [this,index]() {
+ closeOtherTabs(index);
+ });
+ menu.addSeparator();
+ action = menu.addAction(tr("Reload Tab"));
+ action->setShortcut(QKeySequence::Refresh);
+ connect(action, &QAction::triggered, this, [this,index]() {
+ reloadTab(index);
+ });
+ } else {
+ menu.addSeparator();
+ }
+ menu.addAction(tr("Reload All Tabs"), this, &TabWidget::reloadAllTabs);
+ menu.exec(QCursor::pos());
+}
+
+WebView *TabWidget::currentWebView() const
+{
+ return webView(currentIndex());
+}
+
+WebView *TabWidget::webView(int index) const
+{
+ return qobject_cast<WebView*>(widget(index));
+}
+
+void TabWidget::setupView(WebView *webView)
+{
+ QWebEnginePage *webPage = webView->page();
+
+ connect(webView, &QWebEngineView::titleChanged, [this, webView](const QString &title) {
+ int index = indexOf(webView);
+ if (index != -1)
+ setTabText(index, title);
+ if (currentIndex() == index)
+ emit titleChanged(title);
+ });
+ connect(webView, &QWebEngineView::urlChanged, [this, webView](const QUrl &url) {
+ int index = indexOf(webView);
+ if (index != -1)
+ tabBar()->setTabData(index, url);
+ if (currentIndex() == index)
+ emit urlChanged(url);
+ });
+ connect(webView, &QWebEngineView::loadProgress, [this, webView](int progress) {
+ if (currentIndex() == indexOf(webView))
+ emit loadProgress(progress);
+ });
+ connect(webPage, &QWebEnginePage::linkHovered, [this, webView](const QString &url) {
+ if (currentIndex() == indexOf(webView))
+ emit linkHovered(url);
+ });
+ connect(webView, &WebView::iconChanged, [this, webView](const QIcon& icon) {
+ int index = indexOf(webView);
+ if (index != -1)
+ setTabIcon(index, icon);
+ if (currentIndex() == index)
+ emit iconChanged(icon);
+ });
+ connect(webView, &WebView::webActionEnabledChanged, [this, webView](QWebEnginePage::WebAction action, bool enabled) {
+ if (currentIndex() == indexOf(webView))
+ emit webActionEnabledChanged(action,enabled);
+ });
+ connect(webView, &QWebEngineView::loadStarted, [this, webView]() {
+ int index = indexOf(webView);
+ if (index != -1) {
+ QIcon icon(QLatin1String(":loading.gif"));
+ setTabIcon(index, icon);
+ }
+ });
+ connect(webPage, &QWebEnginePage::windowCloseRequested, [this, webView]() {
+ int index = indexOf(webView);
+ if (index >= 0)
+ closeTab(index);
+ });
+}
+
+WebView *TabWidget::createTab(bool makeCurrent)
+{
+ WebView *webView = new WebView;
+ WebPage *webPage = new WebPage(QWebEngineProfile::defaultProfile(), webView);
+ webView->setPage(webPage);
+ setupView(webView);
+ addTab(webView, tr("(Untitled)"));
+ if (makeCurrent)
+ setCurrentWidget(webView);
+ return webView;
+}
+
+void TabWidget::reloadAllTabs()
+{
+ for (int i = 0; i < count(); ++i)
+ webView(i)->reload();
+}
+
+void TabWidget::closeOtherTabs(int index)
+{
+ for (int i = count() - 1; i > index; --i)
+ closeTab(i);
+ for (int i = index - 1; i >= 0; --i)
+ closeTab(i);
+}
+
+void TabWidget::closeTab(int index)
+{
+ if (WebView *view = webView(index)) {
+ bool hasFocus = view->hasFocus();
+ removeTab(index);
+ if (hasFocus && count() > 0)
+ currentWebView()->setFocus();
+ if (count() == 0)
+ createTab();
+ view->deleteLater();
+ }
+}
+
+void TabWidget::cloneTab(int index)
+{
+ if (WebView *view = webView(index)) {
+ WebView *tab = createTab(false);
+ tab->setUrl(view->url());
+ }
+}
+
+void TabWidget::setUrl(const QUrl &url)
+{
+ if (WebView *view = currentWebView()) {
+ view->setUrl(url);
+ view->setFocus();
+ }
+}
+
+void TabWidget::triggerWebPageAction(QWebEnginePage::WebAction action)
+{
+ if (WebView *webView = currentWebView()) {
+ webView->triggerPageAction(action);
+ webView->setFocus();
+ }
+}
+
+void TabWidget::nextTab()
+{
+ int next = currentIndex() + 1;
+ if (next == count())
+ next = 0;
+ setCurrentIndex(next);
+}
+
+void TabWidget::previousTab()
+{
+ int next = currentIndex() - 1;
+ if (next < 0)
+ next = count() - 1;
+ setCurrentIndex(next);
+}
+
+void TabWidget::reloadTab(int index)
+{
+ if (WebView *view = webView(index))
+ view->reload();
+}
diff --git a/examples/webenginewidgets/simplebrowser/tabwidget.h b/examples/webenginewidgets/simplebrowser/tabwidget.h
new file mode 100644
index 000000000..830effa4e
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/tabwidget.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TABWIDGET_H
+#define TABWIDGET_H
+
+#include <QTabWidget>
+#include <QWebEnginePage>
+
+QT_BEGIN_NAMESPACE
+class QUrl;
+QT_END_NAMESPACE
+
+class WebView;
+
+class TabWidget : public QTabWidget
+{
+ Q_OBJECT
+
+public:
+ TabWidget(QWidget *parent = nullptr);
+ ~TabWidget();
+
+ WebView *currentWebView() const;
+
+signals:
+ // current tab/page signals
+ void linkHovered(const QString &link);
+ void loadProgress(int progress);
+ void titleChanged(const QString &title);
+ void urlChanged(const QUrl &url);
+ void iconChanged(const QIcon &icon);
+ void webActionEnabledChanged(QWebEnginePage::WebAction action, bool enabled);
+
+public slots:
+ // current tab/page slots
+ void setUrl(const QUrl &url);
+ void triggerWebPageAction(QWebEnginePage::WebAction action);
+
+ WebView *createTab(bool makeCurrent = true);
+ void closeTab(int index);
+ void nextTab();
+ void previousTab();
+
+private slots:
+ void handleCurrentChanged(int index);
+ void handleContextMenuRequested(const QPoint &pos);
+ void cloneTab(int index);
+ void closeOtherTabs(int index);
+ void reloadAllTabs();
+ void reloadTab(int index);
+
+private:
+ WebView *webView(int index) const;
+ void setupView(WebView *webView);
+};
+
+#endif // TABWIDGET_H
diff --git a/examples/webenginewidgets/simplebrowser/urllineedit.cpp b/examples/webenginewidgets/simplebrowser/urllineedit.cpp
new file mode 100644
index 000000000..7e67b635a
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/urllineedit.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "urllineedit.h"
+#include <QToolButton>
+#include <QUrl>
+
+UrlLineEdit::UrlLineEdit(QWidget *parent)
+ : QLineEdit(parent)
+ , m_favButton(new QToolButton(this))
+ , m_clearButton(new QToolButton(this))
+{
+ m_clearButton->setIcon(QIcon(QStringLiteral(":closetab.png")));
+ m_clearButton->setVisible(false);
+ m_clearButton->setCursor(Qt::ArrowCursor);
+ QString style(QStringLiteral("QToolButton { border: none; padding: 1px; }"));
+ m_clearButton->setStyleSheet(style);
+ m_favButton->setStyleSheet(style);
+ setStyleSheet(QStringLiteral("QLineEdit { padding-left: %1px; padding-right: %2px; } ")
+ .arg(m_clearButton->sizeHint().width())
+ .arg(m_favButton->sizeHint().width()));
+ int minIconHeight = qMax(m_favButton->sizeHint().height(), m_clearButton->sizeHint().height());
+ setMinimumSize(minimumSizeHint().width() +
+ m_favButton->sizeHint().width() +
+ m_clearButton->sizeHint().width(),
+ qMax(minimumSizeHint().height(), minIconHeight));
+
+ connect(m_clearButton, &QToolButton::clicked, this, &QLineEdit::clear);
+ connect(this, &QLineEdit::textChanged, [this](const QString &text) {
+ m_clearButton->setVisible(!text.isEmpty() && !isReadOnly());
+ });
+}
+
+QUrl UrlLineEdit::url() const
+{
+ return QUrl::fromUserInput(text());
+}
+
+void UrlLineEdit::setUrl(const QUrl &url)
+{
+ setText(url.toString());
+ setCursorPosition(0);
+}
+
+void UrlLineEdit::setFavIcon(const QIcon &icon)
+{
+ QPixmap pixmap = icon.pixmap(16, 16);
+ m_favButton->setIcon(pixmap);
+}
+
+void UrlLineEdit::resizeEvent(QResizeEvent *event)
+{
+ QLineEdit::resizeEvent(event);
+ QSize clearButtonSize = m_clearButton->sizeHint();
+ m_clearButton->move(rect().right() - clearButtonSize.width(),
+ (rect().bottom() - clearButtonSize.height()) / 2);
+ m_favButton->move(rect().left(), (rect().bottom() - m_favButton->sizeHint().height()) / 2);
+}
diff --git a/examples/webenginewidgets/simplebrowser/urllineedit.h b/examples/webenginewidgets/simplebrowser/urllineedit.h
new file mode 100644
index 000000000..a01eb0e66
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/urllineedit.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef URLLINEEDIT_H
+#define URLLINEEDIT_H
+
+#include <QLineEdit>
+
+QT_BEGIN_NAMESPACE
+class QToolButton;
+QT_END_NAMESPACE
+
+class UrlLineEdit : public QLineEdit
+{
+ Q_OBJECT
+
+public:
+ UrlLineEdit(QWidget *parent = nullptr);
+
+public:
+ QUrl url() const;
+ void setUrl(const QUrl &url);
+ void setFavIcon(const QIcon &icon);
+
+protected:
+ void resizeEvent(QResizeEvent *event) override;
+
+private:
+ QToolButton *m_favButton;
+ QToolButton *m_clearButton;
+};
+
+#endif // URLLINEEDIT_H
diff --git a/examples/webenginewidgets/simplebrowser/webpage.cpp b/examples/webenginewidgets/simplebrowser/webpage.cpp
new file mode 100644
index 000000000..ae0ef3f48
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/webpage.cpp
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "browserwindow.h"
+#include "tabwidget.h"
+#include "ui_certificateerrordialog.h"
+#include "ui_passworddialog.h"
+#include "webpage.h"
+#include "webview.h"
+#include <QAuthenticator>
+#include <QMessageBox>
+
+WebPage::WebPage(QWebEngineProfile *profile, QObject *parent)
+ : QWebEnginePage(profile, parent)
+{
+ connect(this, &QWebEnginePage::authenticationRequired, this, &WebPage::handleAuthenticationRequired);
+ connect(this, &QWebEnginePage::proxyAuthenticationRequired, this, &WebPage::handleProxyAuthenticationRequired);
+}
+
+bool WebPage::certificateError(const QWebEngineCertificateError &error)
+{
+ QWidget *mainWindow = view()->window();
+ if (error.isOverridable()) {
+ QDialog dialog(mainWindow);
+ dialog.setModal(true);
+ dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ Ui::CertificateErrorDialog certificateDialog;
+ certificateDialog.setupUi(&dialog);
+ certificateDialog.m_iconLabel->setText(QString());
+ QIcon icon(mainWindow->style()->standardIcon(QStyle::SP_MessageBoxWarning, 0, mainWindow));
+ certificateDialog.m_iconLabel->setPixmap(icon.pixmap(32, 32));
+ certificateDialog.m_errorLabel->setText(error.errorDescription());
+ dialog.setWindowTitle(tr("Certificate Error"));
+ return dialog.exec() == QDialog::Accepted;
+ }
+
+ QMessageBox::critical(mainWindow, tr("Certificate Error"), error.errorDescription());
+ return false;
+}
+
+void WebPage::handleAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *auth)
+{
+ QWidget *mainWindow = view()->window();
+ QDialog dialog(mainWindow);
+ dialog.setModal(true);
+ dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ Ui::PasswordDialog passwordDialog;
+ passwordDialog.setupUi(&dialog);
+
+ passwordDialog.m_iconLabel->setText(QString());
+ QIcon icon(mainWindow->style()->standardIcon(QStyle::SP_MessageBoxQuestion, 0, mainWindow));
+ passwordDialog.m_iconLabel->setPixmap(icon.pixmap(32, 32));
+
+ QString introMessage(tr("Enter username and password for \"%1\" at %2")
+ .arg(auth->realm()).arg(requestUrl.toString().toHtmlEscaped()));
+ passwordDialog.m_infoLabel->setText(introMessage);
+ passwordDialog.m_infoLabel->setWordWrap(true);
+
+ if (dialog.exec() == QDialog::Accepted) {
+ auth->setUser(passwordDialog.m_userNameLineEdit->text());
+ auth->setPassword(passwordDialog.m_passwordLineEdit->text());
+ } else {
+ // Set authenticator null if dialog is cancelled
+ *auth = QAuthenticator();
+ }
+}
+
+void WebPage::handleProxyAuthenticationRequired(const QUrl &, QAuthenticator *auth, const QString &proxyHost)
+{
+ QWidget *mainWindow = view()->window();
+ QDialog dialog(mainWindow);
+ dialog.setModal(true);
+ dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ Ui::PasswordDialog passwordDialog;
+ passwordDialog.setupUi(&dialog);
+
+ passwordDialog.m_iconLabel->setText(QString());
+ QIcon icon(mainWindow->style()->standardIcon(QStyle::SP_MessageBoxQuestion, 0, mainWindow));
+ passwordDialog.m_iconLabel->setPixmap(icon.pixmap(32, 32));
+
+ QString introMessage = tr("Connect to proxy \"%1\" using:");
+ introMessage = introMessage.arg(proxyHost.toHtmlEscaped());
+ passwordDialog.m_infoLabel->setText(introMessage);
+ passwordDialog.m_infoLabel->setWordWrap(true);
+
+ if (dialog.exec() == QDialog::Accepted) {
+ auth->setUser(passwordDialog.m_userNameLineEdit->text());
+ auth->setPassword(passwordDialog.m_passwordLineEdit->text());
+ } else {
+ // Set authenticator null if dialog is cancelled
+ *auth = QAuthenticator();
+ }
+}
diff --git a/examples/webenginewidgets/simplebrowser/webpage.h b/examples/webenginewidgets/simplebrowser/webpage.h
new file mode 100644
index 000000000..521534b50
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/webpage.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WEBPAGE_H
+#define WEBPAGE_H
+
+#include <QWebEnginePage>
+
+class WebPage : public QWebEnginePage
+{
+ Q_OBJECT
+
+public:
+ WebPage(QWebEngineProfile *profile, QObject *parent = nullptr);
+
+protected:
+ bool certificateError(const QWebEngineCertificateError &error) override;
+
+private slots:
+ void handleAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *auth);
+ void handleProxyAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *auth, const QString &proxyHost);
+};
+
+#endif // WEBPAGE_H
diff --git a/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp b/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp
new file mode 100644
index 000000000..a3175e546
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "urllineedit.h"
+#include "webpage.h"
+#include "webpopupwindow.h"
+#include "webview.h"
+#include <QIcon>
+#include <QVBoxLayout>
+
+WebPopupWindow::WebPopupWindow(QWebEngineProfile *profile)
+ : m_addressBar(new UrlLineEdit(this))
+ , m_view(new WebView(this))
+{
+ setAttribute(Qt::WA_DeleteOnClose);
+ setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->setMargin(0);
+ setLayout(layout);
+ layout->addWidget(m_addressBar);
+ layout->addWidget(m_view);
+
+ m_view->setPage(new WebPage(profile, m_view));
+ m_view->setFocus();
+ m_addressBar->setReadOnly(true);
+ m_addressBar->setFavIcon(QIcon(QStringLiteral(":defaulticon.png")));
+
+ connect(m_view, &WebView::titleChanged, this, &QWidget::setWindowTitle);
+ connect(m_view, &WebView::urlChanged, this, &WebPopupWindow::setUrl);
+ connect(m_view, &WebView::iconChanged, this, &WebPopupWindow::handleIconChanged);
+ connect(m_view->page(), &WebPage::geometryChangeRequested, this, &WebPopupWindow::handleGeometryChangeRequested);
+ connect(m_view->page(), &WebPage::windowCloseRequested, this, &QWidget::close);
+}
+
+QWebEngineView *WebPopupWindow::view() const
+{
+ return m_view;
+}
+
+void WebPopupWindow::setUrl(const QUrl &url)
+{
+ m_addressBar->setUrl(url);
+}
+
+void WebPopupWindow::handleGeometryChangeRequested(const QRect &newGeometry)
+{
+ m_view->setMinimumSize(newGeometry.width(), newGeometry.height());
+ move(newGeometry.topLeft() - m_view->pos());
+ // let the layout do the magic
+ resize(0, 0);
+ show();
+}
+
+void WebPopupWindow::handleIconChanged(const QIcon &icon)
+{
+ m_addressBar->setFavIcon(icon);
+}
diff --git a/examples/webenginewidgets/simplebrowser/webpopupwindow.h b/examples/webenginewidgets/simplebrowser/webpopupwindow.h
new file mode 100644
index 000000000..af97ef7fc
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/webpopupwindow.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WEBPOPUPWINDOW_H
+#define WEBPOPUPWINDOW_H
+
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QWebEngineProfile;
+class QWebEngineView;
+QT_END_NAMESPACE
+
+class WebView;
+class UrlLineEdit;
+
+class WebPopupWindow : public QWidget
+{
+ Q_OBJECT
+
+public:
+ WebPopupWindow(QWebEngineProfile *profile);
+ QWebEngineView *view() const;
+ void setUrl(const QUrl &url);
+
+private slots:
+ void handleGeometryChangeRequested(const QRect &newGeometry);
+ void handleIconChanged(const QIcon &icon);
+
+private:
+ UrlLineEdit *m_addressBar;
+ WebView *m_view;
+};
+#endif // WEBPOPUPWINDOW_H
diff --git a/examples/webenginewidgets/simplebrowser/webview.cpp b/examples/webenginewidgets/simplebrowser/webview.cpp
new file mode 100644
index 000000000..1fabcc69f
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/webview.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "browser.h"
+#include "browserwindow.h"
+#include "tabwidget.h"
+#include "webpage.h"
+#include "webpopupwindow.h"
+#include "webview.h"
+#include <QContextMenuEvent>
+#include <QMenu>
+#include <QMessageBox>
+#include <QNetworkReply>
+#include <QTimer>
+
+WebView::WebView(QWidget *parent)
+ : QWebEngineView(parent)
+ , m_loadProgress(0)
+{
+ connect(this, &QWebEngineView::loadProgress, [this](int progress) {
+ m_loadProgress = progress;
+ });
+ connect(this, &QWebEngineView::loadFinished, [this](bool success) {
+ if (!success) {
+ qWarning() << "Could not load page: " << url();
+ m_loadProgress = 0;
+ }
+ });
+ connect(this, &QWebEngineView::iconUrlChanged, this, &WebView::handleIconUrlChanged);
+ connect(this, &QWebEngineView::renderProcessTerminated,
+ [this](QWebEnginePage::RenderProcessTerminationStatus termStatus, int statusCode) {
+ QString status;
+ switch (termStatus) {
+ case QWebEnginePage::NormalTerminationStatus:
+ status = tr("Render process normal exit");
+ break;
+ case QWebEnginePage::AbnormalTerminationStatus:
+ status = tr("Render process abnormal exit");
+ break;
+ case QWebEnginePage::CrashedTerminationStatus:
+ status = tr("Render process crashed");
+ break;
+ case QWebEnginePage::KilledTerminationStatus:
+ status = tr("Render process killed");
+ break;
+ }
+ QMessageBox::critical(window(), status, tr("Render process exited with code: %1").arg(statusCode));
+ QTimer::singleShot(0, [this] { reload(); });
+ });
+}
+
+void WebView::setPage(WebPage *page)
+{
+ createWebActionTrigger(page,QWebEnginePage::Forward);
+ createWebActionTrigger(page,QWebEnginePage::Back);
+ createWebActionTrigger(page,QWebEnginePage::Reload);
+ createWebActionTrigger(page,QWebEnginePage::Stop);
+ QWebEngineView::setPage(page);
+}
+
+QIcon WebView::icon() const
+{
+ if (!m_icon.isNull())
+ return m_icon;
+ return QIcon(QLatin1String(":defaulticon.png"));
+}
+
+int WebView::loadProgress() const
+{
+ return m_loadProgress;
+}
+
+void WebView::createWebActionTrigger(QWebEnginePage *page, QWebEnginePage::WebAction webAction)
+{
+ QAction *action = page->action(webAction);
+ connect(action, &QAction::changed, [this, action, webAction]{
+ emit webActionEnabledChanged(webAction, action->isEnabled());
+ });
+}
+
+bool WebView::isWebActionEnabled(QWebEnginePage::WebAction webAction) const
+{
+ return page()->action(webAction)->isEnabled();
+}
+
+QNetworkAccessManager &WebView::networkAccessManager()
+{
+ static QNetworkAccessManager networkAccessManager;
+ return networkAccessManager;
+}
+
+QWebEngineView *WebView::createWindow(QWebEnginePage::WebWindowType type)
+{
+ switch (type) {
+ case QWebEnginePage::WebBrowserTab: {
+ BrowserWindow *mainWindow = qobject_cast<BrowserWindow*>(window());
+ return mainWindow->tabWidget()->createTab();
+ }
+ case QWebEnginePage::WebBrowserWindow: {
+ BrowserWindow *mainWindow = new BrowserWindow();
+ Browser::instance().addWindow(mainWindow);
+ return mainWindow->currentTab();
+ }
+ case QWebEnginePage::WebDialog: {
+ WebPopupWindow *popup = new WebPopupWindow(page()->profile());
+ return popup->view();
+ }
+ }
+ return nullptr;
+}
+
+void WebView::contextMenuEvent(QContextMenuEvent *event)
+{
+ QMenu *menu = page()->createStandardContextMenu();
+ const QList<QAction*> actions = menu->actions();
+ auto it = std::find(actions.cbegin(), actions.cend(), page()->action(QWebEnginePage::OpenLinkInThisWindow));
+ if (it != actions.cend()) {
+ (*it)->setText(tr("Open Link in This Tab"));
+ ++it;
+ menu->insertAction(*it, page()->action(QWebEnginePage::OpenLinkInNewWindow));
+ menu->insertAction(*it, page()->action(QWebEnginePage::OpenLinkInNewTab));
+ }
+ menu->popup(event->globalPos());
+}
+
+void WebView::handleIconUrlChanged(const QUrl &url)
+{
+ QNetworkRequest iconRequest(url);
+#ifndef QT_NO_OPENSSL
+ QSslConfiguration conf = iconRequest.sslConfiguration();
+ conf.setPeerVerifyMode(QSslSocket::VerifyNone);
+ iconRequest.setSslConfiguration(conf);
+#endif
+ QNetworkReply *iconReply = networkAccessManager().get(iconRequest);
+ iconReply->setParent(this);
+ connect(iconReply, &QNetworkReply::finished, this, &WebView::handleIconLoaded);
+}
+
+void WebView::handleIconLoaded()
+{
+ QNetworkReply *iconReply = qobject_cast<QNetworkReply*>(sender());
+ if (iconReply && iconReply->error() == QNetworkReply::NoError) {
+ QByteArray data = iconReply->readAll();
+ QPixmap pixmap;
+ pixmap.loadFromData(data);
+ m_icon.addPixmap(pixmap);
+ iconReply->deleteLater();
+ } else {
+ m_icon = QIcon(QStringLiteral(":defaulticon.png"));
+ }
+ emit iconChanged(m_icon);
+}
diff --git a/examples/webenginewidgets/simplebrowser/webview.h b/examples/webenginewidgets/simplebrowser/webview.h
new file mode 100644
index 000000000..5450ee247
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/webview.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WEBVIEW_H
+#define WEBVIEW_H
+
+#include <QIcon>
+#include <QWebEngineView>
+
+class WebPage;
+
+class WebView : public QWebEngineView
+{
+ Q_OBJECT
+
+public:
+ WebView(QWidget *parent = nullptr);
+ void setPage(WebPage *page);
+
+ QIcon icon() const;
+ int loadProgress() const;
+ bool isWebActionEnabled(QWebEnginePage::WebAction webAction) const;
+ static QNetworkAccessManager &networkAccessManager();
+
+protected:
+ void contextMenuEvent(QContextMenuEvent *event) override;
+ QWebEngineView *createWindow(QWebEnginePage::WebWindowType type) override;
+
+signals:
+ void iconChanged(const QIcon &icon);
+ void webActionEnabledChanged(QWebEnginePage::WebAction webAction, bool enabled);
+
+private slots:
+ void handleIconUrlChanged(const QUrl &url);
+ void handleIconLoaded();
+
+private:
+ void createWebActionTrigger(QWebEnginePage *page, QWebEnginePage::WebAction);
+
+private:
+ int m_loadProgress;
+ QIcon m_icon;
+};
+
+#endif
diff --git a/qtwebengine.pro b/qtwebengine.pro
index 5156e4620..3d20cc2f4 100644
--- a/qtwebengine.pro
+++ b/qtwebengine.pro
@@ -1,2 +1,12 @@
load(qt_build_config)
load(qt_parts)
+
+OTHER_FILES = \
+ tools/buildscripts/* \
+ tools/scripts/* \
+ tools/qmake/config.tests/khr/* \
+ tools/qmake/config.tests/libcap/* \
+ tools/qmake/config.tests/libvpx/* \
+ tools/qmake/config.tests/snappy/* \
+ tools/qmake/config.tests/srtp/* \
+ tools/qmake/mkspecs/features/*
diff --git a/src/3rdparty b/src/3rdparty
-Subproject df7c5f41e9f7e6a1382706e99bd78c4b7e3d120
+Subproject eed57693d22920959d6b7c8f2b1b90b50199476
diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp
index 029c77fe8..7dc5182ad 100644
--- a/src/core/api/qwebengineurlrequestinfo.cpp
+++ b/src/core/api/qwebengineurlrequestinfo.cpp
@@ -62,6 +62,8 @@ ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeFavicon, content::RESOU
ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeXhr, content::RESOURCE_TYPE_XHR)
ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypePing, content::RESOURCE_TYPE_PING)
ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeServiceWorker, content::RESOURCE_TYPE_SERVICE_WORKER)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeCspReport, content::RESOURCE_TYPE_CSP_REPORT)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypePluginResource, content::RESOURCE_TYPE_PLUGIN_RESOURCE)
ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeUnknown, content::RESOURCE_TYPE_LAST_TYPE)
ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::LinkNavigation, QWebEngineUrlRequestInfo::NavigationTypeLink)
diff --git a/src/core/api/qwebengineurlrequestinfo.h b/src/core/api/qwebengineurlrequestinfo.h
index 0d315936c..34570b61f 100644
--- a/src/core/api/qwebengineurlrequestinfo.h
+++ b/src/core/api/qwebengineurlrequestinfo.h
@@ -73,6 +73,8 @@ public:
ResourceTypeXhr, // a XMLHttpRequest
ResourceTypePing, // a ping request for <a ping>
ResourceTypeServiceWorker, // the main resource of a service worker.
+ ResourceTypeCspReport,
+ ResourceTypePluginResource,
ResourceTypeUnknown
};
diff --git a/src/core/browser_accessibility_manager_qt.cpp b/src/core/browser_accessibility_manager_qt.cpp
index 392f57e20..bd3c5e7d9 100644
--- a/src/core/browser_accessibility_manager_qt.cpp
+++ b/src/core/browser_accessibility_manager_qt.cpp
@@ -47,7 +47,7 @@ using namespace blink;
namespace content {
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
- const SimpleAXTreeUpdate& initialTree,
+ const ui::AXTreeUpdate& initialTree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory)
{
@@ -69,12 +69,11 @@ BrowserAccessibility *BrowserAccessibilityFactoryQt::Create()
#ifndef QT_NO_ACCESSIBILITY
BrowserAccessibilityManagerQt::BrowserAccessibilityManagerQt(
- QObject* parentObject,
- const SimpleAXTreeUpdate& initialTree,
- BrowserAccessibilityDelegate* delegate,
- BrowserAccessibilityFactory* factory)
- : BrowserAccessibilityManager(delegate, factory)
- , m_parentObject(parentObject) {
+ QObject *parentObject, const ui::AXTreeUpdate &initialTree,
+ BrowserAccessibilityDelegate* delegate, BrowserAccessibilityFactory* factory)
+ : BrowserAccessibilityManager(delegate, factory)
+ , m_parentObject(parentObject)
+{
Initialize(initialTree);
}
diff --git a/src/core/browser_accessibility_manager_qt.h b/src/core/browser_accessibility_manager_qt.h
index 7f139e03d..4ff9fb699 100644
--- a/src/core/browser_accessibility_manager_qt.h
+++ b/src/core/browser_accessibility_manager_qt.h
@@ -61,7 +61,7 @@ class BrowserAccessibilityManagerQt : public BrowserAccessibilityManager
public:
BrowserAccessibilityManagerQt(
QObject* parentObject,
- const SimpleAXTreeUpdate& initialTree,
+ const ui::AXTreeUpdate& initialTree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactoryQt());
diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp
index 4bb9e3a4a..fecbac111 100644
--- a/src/core/browser_accessibility_qt.cpp
+++ b/src/core/browser_accessibility_qt.cpp
@@ -62,84 +62,6 @@ BrowserAccessibilityQt::BrowserAccessibilityQt()
QAccessible::registerAccessibleInterface(this);
}
-// This function is taken from chromium/content/browser/accessibility/browser_accessibility_win.cc
-// see also http://www.w3.org/TR/html-aapi
-void BrowserAccessibilityQt::OnDataChanged()
-{
- BrowserAccessibility::OnDataChanged();
-
- // The calculation of the accessible name of an element has been
- // standardized in the HTML to Platform Accessibility APIs Implementation
- // Guide (http://www.w3.org/TR/html-aapi/). In order to return the
- // appropriate accessible name on Windows, we need to apply some logic
- // to the fields we get from WebKit.
- //
- // TODO(dmazzoni): move most of this logic into WebKit.
- //
- // WebKit gives us:
- //
- // name: the default name, e.g. inner text
- // title ui element: a reference to a <label> element on the same
- // page that labels this node.
- // description: accessible labels that override the default name:
- // aria-label or aria-labelledby or aria-describedby
- // help: the value of the "title" attribute
- //
- // On Windows, the logic we apply lets some fields take precedence and
- // always returns the primary name in "name" and the secondary name,
- // if any, in "description".
-
- int title_elem_id = GetIntAttribute(ui::AX_ATTR_TITLE_UI_ELEMENT);
- base::string16 name = GetString16Attribute(ui::AX_ATTR_NAME);
- base::string16 description = GetString16Attribute(ui::AX_ATTR_DESCRIPTION);
- base::string16 help = GetString16Attribute(ui::AX_ATTR_HELP);
- base::string16 value = GetString16Attribute(ui::AX_ATTR_VALUE);
-
- // WebKit annoyingly puts the title in the description if there's no other
- // description, which just confuses the rest of the logic. Put it back.
- // Now "help" is always the value of the "title" attribute, if present.
- base::string16 title_attr;
- if (GetHtmlAttribute("title", &title_attr) &&
- description == title_attr &&
- help.empty()) {
- help = description;
- description.clear();
- }
-
- // Now implement the main logic: the descripion should become the name if
- // it's nonempty, and the help should become the description if
- // there's no description - or the name if there's no name or description.
- if (!description.empty()) {
- name = description;
- description.clear();
- }
- if (!help.empty() && description.empty()) {
- description = help;
- help.clear();
- }
- if (!description.empty() && name.empty() && !title_elem_id) {
- name = description;
- description.clear();
- }
-
- // If it's a text field, also consider the placeholder.
- base::string16 placeholder;
- if (GetRole() == ui::AX_ROLE_TEXT_FIELD &&
- HasState(ui::AX_STATE_FOCUSABLE) &&
- GetHtmlAttribute("placeholder", &placeholder)) {
- if (name.empty() && !title_elem_id) {
- name = placeholder;
- } else if (description.empty()) {
- description = placeholder;
- }
- }
-
- m_name = toQt(name);
- m_description = toQt(description);
- m_help = toQt(help);
- m_value = toQt(value);
-}
-
bool BrowserAccessibilityQt::isValid() const
{
return true;
@@ -169,7 +91,7 @@ void *BrowserAccessibilityQt::interface_cast(QAccessible::InterfaceType type)
return static_cast<QAccessibleActionInterface*>(this);
break;
case QAccessible::TextInterface:
- if (IsEditableText())
+ if (HasState(ui::AX_STATE_EDITABLE))
return static_cast<QAccessibleTextInterface*>(this);
break;
case QAccessible::ValueInterface: {
@@ -232,13 +154,11 @@ QString BrowserAccessibilityQt::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
- return name();
+ return toQt(GetStringAttribute(ui::AX_ATTR_NAME));
case QAccessible::Description:
- return description();
- case QAccessible::Help:
- return help();
+ return toQt(GetStringAttribute(ui::AX_ATTR_DESCRIPTION));
case QAccessible::Value:
- return value();
+ return toQt(GetStringAttribute(ui::AX_ATTR_VALUE));
case QAccessible::Accelerator:
return toQt(GetStringAttribute(ui::AX_ATTR_SHORTCUT));
default:
@@ -485,7 +405,7 @@ QAccessible::Role BrowserAccessibilityQt::role() const
QAccessible::State BrowserAccessibilityQt::state() const
{
QAccessible::State state = QAccessible::State();
- int32 s = GetState();
+ int32_t s = GetState();
if (s & (1 << ui::AX_STATE_BUSY))
state.busy = true;
if (s & (1 << ui::AX_STATE_CHECKED))
@@ -504,8 +424,6 @@ QAccessible::State BrowserAccessibilityQt::state() const
state.hasPopup = true;
if (s & (1 << ui::AX_STATE_HOVERED))
state.hotTracked = true;
- if (s & (1 << ui::AX_STATE_INDETERMINATE))
- {} // FIXME
if (s & (1 << ui::AX_STATE_INVISIBLE))
state.invisible = true;
if (s & (1 << ui::AX_STATE_LINKED))
@@ -530,7 +448,7 @@ QAccessible::State BrowserAccessibilityQt::state() const
{} // FIXME
if (s & (1 << ui::AX_STATE_VISITED))
{} // FIXME
- if (IsEditableText())
+ if (HasState(ui::AX_STATE_EDITABLE))
state.editable = true;
return state;
}
@@ -713,7 +631,7 @@ QAccessibleInterface *BrowserAccessibilityQt::cellAt(int row, int column) const
if (row < 0 || row >= rows || column < 0 || column >= columns)
return 0;
- const std::vector<int32>& cell_ids = GetIntListAttribute(ui::AX_ATTR_CELL_IDS);
+ const std::vector<int32_t>& cell_ids = GetIntListAttribute(ui::AX_ATTR_CELL_IDS);
DCHECK_EQ(columns * rows, static_cast<int>(cell_ids.size()));
int cell_id = cell_ids[row * columns + column];
diff --git a/src/core/browser_accessibility_qt.h b/src/core/browser_accessibility_qt.h
index 1cdd97fb3..186bd7d84 100644
--- a/src/core/browser_accessibility_qt.h
+++ b/src/core/browser_accessibility_qt.h
@@ -58,9 +58,6 @@ class BrowserAccessibilityQt
public:
BrowserAccessibilityQt();
- // BrowserAccessibility
- virtual void OnDataChanged() Q_DECL_OVERRIDE;
-
// QAccessibleInterface
virtual bool isValid() const Q_DECL_OVERRIDE;
virtual QObject *object() const Q_DECL_OVERRIDE;
@@ -145,18 +142,6 @@ public:
virtual QAccessibleInterface* table() const Q_DECL_OVERRIDE;
virtual void modelChange(QAccessibleTableModelChangeEvent *event) Q_DECL_OVERRIDE;
-
- QString name() const { return m_name; }
- QString description() const { return m_description; }
- QString help() const { return m_help; }
- QString value() const { return m_value; }
-
-private:
- // IAccessible name, description, help, value.
- QString m_name;
- QString m_description;
- QString m_help;
- QString m_value;
};
}
diff --git a/src/core/browser_context_qt.cpp b/src/core/browser_context_qt.cpp
index ca772c169..5685c2dcd 100644
--- a/src/core/browser_context_qt.cpp
+++ b/src/core/browser_context_qt.cpp
@@ -44,6 +44,7 @@
#include "permission_manager_qt.h"
#include "qtwebenginecoreglobal_p.h"
#include "resource_context_qt.h"
+#include "ssl_host_state_delegate_qt.h"
#include "type_conversion.h"
#include "url_request_context_getter_qt.h"
@@ -86,7 +87,7 @@ BrowserContextQt::BrowserContextQt(BrowserContextAdapter *adapter)
registry->RegisterBooleanPref(prefs::kSpellCheckUseSpellingService, false);
registry->RegisterBooleanPref(prefs::kEnableContinuousSpellcheck, false);
registry->RegisterBooleanPref(prefs::kEnableAutoSpellCorrect, false);
- m_prefService = factory.Create(registry.get()).Pass();
+ m_prefService = factory.Create(std::move(registry.get()));
user_prefs::UserPrefs::Set(this, m_prefService.get());
}
#else
@@ -172,7 +173,9 @@ content::PushMessagingService *BrowserContextQt::GetPushMessagingService()
content::SSLHostStateDelegate* BrowserContextQt::GetSSLHostStateDelegate()
{
- return 0;
+ if (!sslHostStateDelegate)
+ sslHostStateDelegate.reset(new SSLHostStateDelegateQt(m_adapter));
+ return sslHostStateDelegate.get();
}
scoped_ptr<content::ZoomLevelDelegate> BrowserContextQt::CreateZoomLevelDelegate(const base::FilePath&)
@@ -180,6 +183,11 @@ scoped_ptr<content::ZoomLevelDelegate> BrowserContextQt::CreateZoomLevelDelegate
return nullptr;
}
+content::BackgroundSyncController* BrowserContextQt::GetBackgroundSyncController()
+{
+ return nullptr;
+}
+
content::PermissionManager *BrowserContextQt::GetPermissionManager()
{
if (!permissionManager)
@@ -189,7 +197,7 @@ content::PermissionManager *BrowserContextQt::GetPermissionManager()
net::URLRequestContextGetter *BrowserContextQt::CreateRequestContext(content::ProtocolHandlerMap *protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors)
{
- url_request_getter_ = new URLRequestContextGetterQt(m_adapter, protocol_handlers, request_interceptors.Pass());
+ url_request_getter_ = new URLRequestContextGetterQt(m_adapter, protocol_handlers, std::move(request_interceptors));
return url_request_getter_.get();
}
diff --git a/src/core/browser_context_qt.h b/src/core/browser_context_qt.h
index 6a4b65b6b..08ac05fd4 100644
--- a/src/core/browser_context_qt.h
+++ b/src/core/browser_context_qt.h
@@ -59,6 +59,7 @@ namespace QtWebEngineCore {
class BrowserContextAdapter;
class PermissionManagerQt;
+class SSLHostStateDelegateQt;
class URLRequestContextGetterQt;
class BrowserContextQt : public content::BrowserContext
@@ -86,6 +87,7 @@ public:
net::URLRequestContextGetter *CreateRequestContext(content::ProtocolHandlerMap *protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors);
virtual scoped_ptr<content::ZoomLevelDelegate> CreateZoomLevelDelegate(const base::FilePath& partition_path) Q_DECL_OVERRIDE;
virtual content::PermissionManager *GetPermissionManager() Q_DECL_OVERRIDE;
+ virtual content::BackgroundSyncController* GetBackgroundSyncController() Q_DECL_OVERRIDE;
BrowserContextAdapter *adapter() { return m_adapter; }
@@ -103,6 +105,7 @@ private:
scoped_ptr<content::ResourceContext> resourceContext;
scoped_refptr<URLRequestContextGetterQt> url_request_getter_;
scoped_ptr<PermissionManagerQt> permissionManager;
+ scoped_ptr<SSLHostStateDelegateQt> sslHostStateDelegate;
BrowserContextAdapter *m_adapter;
#if defined(ENABLE_SPELLCHECK)
scoped_refptr<TestingPrefStore> m_prefStore;
diff --git a/src/core/chromium_gpu_helper.cpp b/src/core/chromium_gpu_helper.cpp
index c955837b8..349506dbd 100644
--- a/src/core/chromium_gpu_helper.cpp
+++ b/src/core/chromium_gpu_helper.cpp
@@ -57,25 +57,6 @@
#include "content/common/gpu/stream_texture_qnx.h"
#endif
-static void addSyncPointCallbackDelegate(gpu::SyncPointManager *syncPointManager, uint32 sync_point, const base::Closure& callback)
-{
- syncPointManager->AddSyncPointCallback(sync_point, callback);
-}
-
-QMap<uint32, gfx::TransferableFence> transferFences()
-{
- QMap<uint32, gfx::TransferableFence> ret;
- content::GpuChannelManager *gpuChannelManager = content::GpuChildThread::instance()->ChannelManager();
- content::GpuChannelManager::SyncPointGLFences::iterator it = gpuChannelManager->sync_point_gl_fences_.begin();
- content::GpuChannelManager::SyncPointGLFences::iterator end = gpuChannelManager->sync_point_gl_fences_.end();
- for (; it != end; ++it) {
- ret[it->first] = it->second->Transfer();
- delete it->second;
- }
- gpuChannelManager->sync_point_gl_fences_.clear();
- return ret;
-}
-
base::MessageLoop *gpu_message_loop()
{
return content::GpuChildThread::instance()->message_loop();
@@ -87,12 +68,6 @@ gpu::SyncPointManager *sync_point_manager()
return gpuChannelManager->sync_point_manager();
}
-void AddSyncPointCallbackOnGpuThread(base::MessageLoop *gpuMessageLoop, gpu::SyncPointManager *syncPointManager, uint32 sync_point, const base::Closure& callback)
-{
- // We need to set our callback from the GPU thread, where the SyncPointManager lives.
- gpuMessageLoop->PostTask(FROM_HERE, base::Bind(&addSyncPointCallbackDelegate, syncPointManager, sync_point, callback));
-}
-
gpu::gles2::MailboxManager *mailbox_manager()
{
content::GpuChannelManager *gpuChannelManager = content::GpuChildThread::instance()->ChannelManager();
diff --git a/src/core/chromium_gpu_helper.h b/src/core/chromium_gpu_helper.h
index 254143db9..02fe2d3bb 100644
--- a/src/core/chromium_gpu_helper.h
+++ b/src/core/chromium_gpu_helper.h
@@ -43,9 +43,6 @@
#include <QtGlobal> // We need this for the Q_OS_QNX define.
#include <QMap>
-#include "base/callback.h"
-#include "ui/gl/gl_fence.h"
-
namespace base {
class MessageLoop;
}
@@ -64,12 +61,10 @@ class Texture;
// From the outside, types from incompatible headers referenced in these
// functions should only be forward-declared and considered as opaque types.
-QMap<uint32, gfx::TransferableFence> transferFences();
base::MessageLoop *gpu_message_loop();
gpu::SyncPointManager *sync_point_manager();
gpu::gles2::MailboxManager *mailbox_manager();
-void AddSyncPointCallbackOnGpuThread(base::MessageLoop *gpuMessageLoop, gpu::SyncPointManager *syncPointManager, uint32 sync_point, const base::Closure& callback);
gpu::gles2::Texture* ConsumeTexture(gpu::gles2::MailboxManager *mailboxManager, unsigned target, const gpu::Mailbox& mailbox);
unsigned int service_id(gpu::gles2::Texture *tex);
diff --git a/src/core/chromium_overrides.cpp b/src/core/chromium_overrides.cpp
index 8cff99222..18596c337 100644
--- a/src/core/chromium_overrides.cpp
+++ b/src/core/chromium_overrides.cpp
@@ -131,7 +131,7 @@ scoped_ptr<base::ListValue> GetFontList_SlowBlocking()
// TODO: Support localized family names.
font_list->Append(font_item);
}
- return font_list.Pass();
+ return std::move(font_list);
}
#if defined(ENABLE_PLUGINS)
@@ -166,7 +166,7 @@ namespace net {
class SSLPrivateKey { };
class X509Certificate;
-scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey(X509Certificate* certificate, scoped_refptr<base::SequencedTaskRunner> task_runner)
+scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey(X509Certificate* certificate)
{
return scoped_ptr<SSLPrivateKey>();
}
diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp
index 13888c3b0..3b3248559 100644
--- a/src/core/clipboard_qt.cpp
+++ b/src/core/clipboard_qt.cpp
@@ -307,7 +307,7 @@ void ClipboardQt::ReadAsciiText(ui::ClipboardType type, std::string* result) con
*result = mimeData->text().toStdString();
}
-void ClipboardQt::ReadHTML(ui::ClipboardType type, base::string16* markup, std::string* src_url, uint32* fragment_start, uint32* fragment_end) const
+void ClipboardQt::ReadHTML(ui::ClipboardType type, base::string16* markup, std::string* src_url, uint32_t* fragment_start, uint32_t* fragment_end) const
{
markup->clear();
if (src_url)
@@ -317,7 +317,7 @@ void ClipboardQt::ReadHTML(ui::ClipboardType type, base::string16* markup, std::
const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
*markup = toString16(mimeData->html());
- *fragment_end = static_cast<uint32>(markup->length());
+ *fragment_end = static_cast<uint32_t>(markup->length());
}
void ClipboardQt::ReadRTF(ui::ClipboardType type, std::string* result) const
@@ -364,7 +364,7 @@ void ClipboardQt::ReadData(const FormatType& format, std::string* result) const
*result = std::string(byteArray.constData(), byteArray.length());
}
-uint64 ClipboardQt::GetSequenceNumber(ui::ClipboardType type) const
+uint64_t ClipboardQt::GetSequenceNumber(ui::ClipboardType type) const
{
return clipboardChangeObserver()->getSequenceNumber(type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
}
diff --git a/src/core/clipboard_qt.h b/src/core/clipboard_qt.h
index 6a2ea104a..6af4193d9 100644
--- a/src/core/clipboard_qt.h
+++ b/src/core/clipboard_qt.h
@@ -65,7 +65,7 @@ private:
class ClipboardQt : public ui::Clipboard {
public:
- virtual uint64 GetSequenceNumber(ui::ClipboardType type) const Q_DECL_OVERRIDE;
+ virtual uint64_t GetSequenceNumber(ui::ClipboardType type) const Q_DECL_OVERRIDE;
virtual bool IsFormatAvailable(const FormatType& format, ui::ClipboardType type) const Q_DECL_OVERRIDE;
virtual void Clear(ui::ClipboardType type) Q_DECL_OVERRIDE;
virtual void ReadAvailableTypes(ui::ClipboardType type, std::vector<base::string16>* types, bool* contains_filenames) const Q_DECL_OVERRIDE;
@@ -74,8 +74,8 @@ public:
virtual void ReadHTML(ui::ClipboardType type,
base::string16* markup,
std::string* src_url,
- uint32* fragment_start,
- uint32* fragment_end) const Q_DECL_OVERRIDE;
+ uint32_t* fragment_start,
+ uint32_t* fragment_end) const Q_DECL_OVERRIDE;
virtual void ReadRTF(ui::ClipboardType type, std::string* result) const Q_DECL_OVERRIDE;
virtual SkBitmap ReadImage(ui::ClipboardType type) const Q_DECL_OVERRIDE;
virtual void ReadCustomData(ui::ClipboardType clipboard_type, const base::string16& type, base::string16* result) const Q_DECL_OVERRIDE;
diff --git a/src/core/common/qt_messages.h b/src/core/common/qt_messages.h
index d76b1c911..b8991a2b3 100644
--- a/src/core/common/qt_messages.h
+++ b/src/core/common/qt_messages.h
@@ -26,13 +26,13 @@ IPC_STRUCT_TRAITS_END()
// These are messages sent from the browser to the renderer process.
IPC_MESSAGE_ROUTED1(RenderViewObserverQt_FetchDocumentMarkup,
- uint64 /* requestId */)
+ uint64_t /* requestId */)
IPC_MESSAGE_ROUTED1(RenderViewObserverQt_FetchDocumentInnerText,
- uint64 /* requestId */)
+ uint64_t /* requestId */)
IPC_MESSAGE_ROUTED1(RenderViewObserverQt_SetBackgroundColor,
- uint32 /* color */)
+ uint32_t /* color */)
IPC_MESSAGE_ROUTED1(WebChannelIPCTransport_Install, uint /* worldId */)
IPC_MESSAGE_ROUTED1(WebChannelIPCTransport_Uninstall, uint /* worldId */)
@@ -54,11 +54,11 @@ IPC_MESSAGE_CONTROL0(UserResourceController_ClearScripts)
// These are messages sent from the renderer back to the browser process.
IPC_MESSAGE_ROUTED2(RenderViewObserverHostQt_DidFetchDocumentMarkup,
- uint64 /* requestId */,
+ uint64_t /* requestId */,
base::string16 /* markup */)
IPC_MESSAGE_ROUTED2(RenderViewObserverHostQt_DidFetchDocumentInnerText,
- uint64 /* requestId */,
+ uint64_t /* requestId */,
base::string16 /* innerText */)
IPC_MESSAGE_ROUTED0(RenderViewObserverHostQt_DidFirstVisuallyNonEmptyLayout)
diff --git a/src/core/common/user_script_data.cpp b/src/core/common/user_script_data.cpp
index 21047d040..6f4b8cb05 100644
--- a/src/core/common/user_script_data.cpp
+++ b/src/core/common/user_script_data.cpp
@@ -44,6 +44,6 @@ UserScriptData::UserScriptData() : injectionPoint(AfterLoad)
, injectForSubframes(false)
, worldId(1)
{
- static uint64 idCount = 0;
+ static uint64_t idCount = 0;
scriptId = idCount++;
}
diff --git a/src/core/common/user_script_data.h b/src/core/common/user_script_data.h
index b8b6025f0..943d61798 100644
--- a/src/core/common/user_script_data.h
+++ b/src/core/common/user_script_data.h
@@ -42,7 +42,6 @@
#include <QtCore/QHash>
#include <string>
-#include "base/basictypes.h"
#include "ipc/ipc_message_utils.h"
#include "url/gurl.h"
@@ -57,10 +56,10 @@ struct UserScriptData {
std::string source;
GURL url;
- /*InjectionPoint*/uint8 injectionPoint;
+ /*InjectionPoint*/uint8_t injectionPoint;
bool injectForSubframes;
uint worldId;
- uint64 scriptId;
+ uint64_t scriptId;
};
QT_BEGIN_NAMESPACE
diff --git a/src/core/config/embedded_linux.pri b/src/core/config/embedded_linux.pri
index 7cabf52ac..4cb7d89fb 100644
--- a/src/core/config/embedded_linux.pri
+++ b/src/core/config/embedded_linux.pri
@@ -35,7 +35,8 @@ GYP_CONFIG += \
use_libpci=0 \
use_ozone=1 \
use_system_fontconfig=1 \
- icu_use_data_file_flag=0 \
use_x11=0 \
v8_use_snapshot=false \
want_separate_host_toolset=1 \
+
+WEBENGINE_CONFIG *= reduce_binary_size
diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri
index 2fa6aa5c6..7d6c7bfbc 100644
--- a/src/core/config/linux.pri
+++ b/src/core/config/linux.pri
@@ -43,6 +43,6 @@ use?(system_jsoncpp): GYP_CONFIG += use_system_jsoncpp=1
use?(system_opus): GYP_CONFIG += use_system_opus=1
use?(system_snappy): GYP_CONFIG += use_system_snappy=1
use?(system_vpx): GYP_CONFIG += use_system_libvpx=1
-use?(system_icu): GYP_CONFIG += use_system_icu=1
+use?(system_icu): GYP_CONFIG += use_system_icu=1 icu_use_data_file_flag=0
use?(system_ffmpeg): GYP_CONFIG += use_system_ffmpeg=1
-
+use?(system_protobuf): GYP_CONFIG += use_system_protobuf=1
diff --git a/src/core/config/mac_osx.pri b/src/core/config/mac_osx.pri
index dd2affca9..01c1ca977 100644
--- a/src/core/config/mac_osx.pri
+++ b/src/core/config/mac_osx.pri
@@ -1,5 +1,13 @@
include(common.pri)
+# Reuse the cached sdk version value from mac/sdk.prf if available
+# otherwise query for it.
+QMAKE_MAC_SDK_VERSION = $$eval(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.SDKVersion)
+isEmpty(QMAKE_MAC_SDK_VERSION) {
+ QMAKE_MAC_SDK_VERSION = $$system("/usr/bin/xcodebuild -sdk $${QMAKE_MAC_SDK} -version SDKVersion 2>/dev/null")
+ isEmpty(QMAKE_MAC_SDK_VERSION): error("Could not resolve SDK version for \'$${QMAKE_MAC_SDK}\'")
+}
+
QMAKE_CLANG_DIR = "/usr"
QMAKE_CLANG_PATH = $$eval(QMAKE_MAC_SDK.macx-clang.$${QMAKE_MAC_SDK}.QMAKE_CXX)
!isEmpty(QMAKE_CLANG_PATH) {
@@ -10,10 +18,9 @@ QMAKE_CLANG_PATH = $$eval(QMAKE_MAC_SDK.macx-clang.$${QMAKE_MAC_SDK}.QMAKE_CXX)
QMAKE_CLANG_PATH = "$${QMAKE_CLANG_DIR}/bin/clang++"
message("Using clang++ from $${QMAKE_CLANG_PATH}")
system("$${QMAKE_CLANG_PATH} --version")
-
GYP_CONFIG += \
qt_os=\"mac\" \
- mac_sdk_min=\"10.7\" \
+ mac_sdk_min=\"$${QMAKE_MAC_SDK_VERSION}\" \
mac_deployment_target=\"$${QMAKE_MACOSX_DEPLOYMENT_TARGET}\" \
make_clang_dir=\"$${QMAKE_CLANG_DIR}\" \
clang_use_chrome_plugins=0 \
diff --git a/src/core/config/windows.pri b/src/core/config/windows.pri
index ab4037d1f..72de7055c 100644
--- a/src/core/config/windows.pri
+++ b/src/core/config/windows.pri
@@ -11,9 +11,6 @@ GYP_CONFIG += \
no_spellcheck: GYP_CONFIG += enable_spellcheck=0
else: GYP_CONFIG += enable_spellcheck=1
-# Chromium builds with debug info in release by default but Qt doesn't
-CONFIG(release, debug|release):!force_debug_info: GYP_CONFIG += fastbuild=1
-
# Libvpx build needs additional search path on Windows.
GYP_ARGS += "-D qtwe_chromium_obj_dir=\"$$OUT_PWD/$$getConfigDir()/obj/$${getChromiumSrcDir()}\""
@@ -53,6 +50,14 @@ defineTest(usingMSVC32BitCrossCompiler) {
return(false)
}
+msvc:contains(QT_ARCH, "i386"):!usingMSVC32BitCrossCompiler() {
+ # The 32 bit MSVC linker runs out of memory if we do not remove all debug information.
+ GYP_CONFIG += fastbuild=2
+} else {
+ # Chromium builds with debug info in release by default but Qt doesn't
+ CONFIG(release, debug|release):!force_debug_info: GYP_CONFIG += fastbuild=1
+}
+
msvc {
equals(MSVC_VER, 12.0) {
MSVS_VERSION = 2013
@@ -64,16 +69,8 @@ msvc {
GYP_ARGS += "-G msvs_version=$$MSVS_VERSION"
- # The check below is ugly, but necessary, as it seems to be the only reliable way to detect if the host
- # architecture is 32 bit. QMAKE_HOST.arch does not work as it returns the architecture that the toolchain
- # is building for, not the system's actual architecture.
- PROGRAM_FILES_X86 = $$(ProgramW6432)
- isEmpty(PROGRAM_FILES_X86): GYP_ARGS += "-D windows_sdk_path=\"C:/Program Files/Windows Kits/8.1\""
+ isBuildingOnWin32(): GYP_ARGS += "-D windows_sdk_path=\"C:/Program Files/Windows Kits/8.1\""
- contains(QT_ARCH, "i386"):!usingMSVC32BitCrossCompiler() {
- # The 32 bit MSVC linker runs out of memory if we do not remove all debug information.
- GYP_CONFIG += fastbuild=2
- }
} else {
fatal("Qt WebEngine for Windows can only be built with the Microsoft Visual Studio C++ compiler")
}
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 97d43fb90..f5f490ccf 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -403,7 +403,7 @@ content::AccessTokenStore *ContentBrowserClientQt::CreateAccessTokenStore()
net::URLRequestContextGetter* ContentBrowserClientQt::CreateRequestContext(content::BrowserContext* browser_context, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors)
{
- return static_cast<BrowserContextQt*>(browser_context)->CreateRequestContext(protocol_handlers, request_interceptors.Pass());
+ return static_cast<BrowserContextQt*>(browser_context)->CreateRequestContext(protocol_handlers, std::move(request_interceptors));
}
content::QuotaPermissionContext *ContentBrowserClientQt::CreateQuotaPermissionContext()
@@ -411,24 +411,26 @@ content::QuotaPermissionContext *ContentBrowserClientQt::CreateQuotaPermissionCo
return new QuotaPermissionContextQt;
}
-void ContentBrowserClientQt::AllowCertificateError(int render_process_id, int render_frame_id, int cert_error,
- const net::SSLInfo& ssl_info, const GURL& request_url,
- content::ResourceType resource_type,
- bool overridable, bool strict_enforcement,
- bool expired_previous_decision,
- const base::Callback<void(bool)>& callback,
- content::CertificateRequestResultType* result)
-{
- // We leave the result with its default value.
- Q_UNUSED(result);
- content::RenderFrameHost *frameHost = content::RenderFrameHost::FromID(render_process_id, render_frame_id);
- WebContentsDelegateQt* contentsDelegate = 0;
- if (content::WebContents *webContents = frameHost->GetRenderViewHost()->GetDelegate()->GetAsWebContents())
- contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
+void ContentBrowserClientQt::AllowCertificateError(content::WebContents *webContents,
+ int cert_error,
+ const net::SSLInfo& ssl_info,
+ const GURL& request_url,
+ content::ResourceType resource_type,
+ bool overridable,
+ bool strict_enforcement,
+ bool expired_previous_decision,
+ const base::Callback<void(bool)>& callback,
+ content::CertificateRequestResultType* result)
+{
+ WebContentsDelegateQt* contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
QSharedPointer<CertificateErrorController> errorController(new CertificateErrorController(new CertificateErrorControllerPrivate(cert_error, ssl_info, request_url, resource_type, overridable, strict_enforcement, callback)));
contentsDelegate->allowCertificateError(errorController);
+
+ // If we don't give the user a chance to allow it, we can reject it right away.
+ if (result && (!overridable || strict_enforcement))
+ *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY;
}
content::LocationProvider *ContentBrowserClientQt::OverrideSystemLocationProvider()
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index ac5808448..1878e3d27 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -92,18 +92,16 @@ public:
virtual content::AccessTokenStore* CreateAccessTokenStore() Q_DECL_OVERRIDE;
virtual content::QuotaPermissionContext *CreateQuotaPermissionContext() Q_DECL_OVERRIDE;
virtual void OverrideWebkitPrefs(content::RenderViewHost *, content::WebPreferences *) Q_DECL_OVERRIDE;
- virtual void AllowCertificateError(
- int render_process_id,
- int render_frame_id,
- int cert_error,
- const net::SSLInfo& ssl_info,
- const GURL& request_url,
- content::ResourceType resource_type,
- bool overridable,
- bool strict_enforcement,
- bool expired_previous_decision,
- const base::Callback<void(bool)>& callback,
- content::CertificateRequestResultType* result) Q_DECL_OVERRIDE;
+ virtual void AllowCertificateError(content::WebContents* web_contents,
+ int cert_error,
+ const net::SSLInfo& ssl_info,
+ const GURL& request_url,
+ content::ResourceType resource_type,
+ bool overridable,
+ bool strict_enforcement,
+ bool expired_previous_decision,
+ const base::Callback<void(bool)>& callback,
+ content::CertificateRequestResultType* result) Q_DECL_OVERRIDE;
content::LocationProvider* OverrideSystemLocationProvider() Q_DECL_OVERRIDE;
content::DevToolsManagerDelegate *GetDevToolsManagerDelegate() Q_DECL_OVERRIDE;
virtual net::URLRequestContextGetter *CreateRequestContext(content::BrowserContext *browser_context, content::ProtocolHandlerMap *protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptorss) Q_DECL_OVERRIDE;
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index d14e13137..7fc6556fb 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -63,10 +63,10 @@
#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
-static const int32 kPepperFlashPermissions = ppapi::PERMISSION_DEV |
- ppapi::PERMISSION_PRIVATE |
- ppapi::PERMISSION_BYPASS_USER_GESTURE |
- ppapi::PERMISSION_FLASH;
+static const int32_t kPepperFlashPermissions = ppapi::PERMISSION_DEV |
+ ppapi::PERMISSION_PRIVATE |
+ ppapi::PERMISSION_BYPASS_USER_GESTURE |
+ ppapi::PERMISSION_FLASH;
namespace switches {
const char kPpapiFlashPath[] = "ppapi-flash-path";
@@ -78,8 +78,8 @@ static const base::FilePath::CharType kWidevineCdmBaseDirectory[] = FILE_PATH_LI
static const char kWidevineCdmPluginExtension[] = "";
-static const int32 kWidevineCdmPluginPermissions = ppapi::PERMISSION_DEV
- | ppapi::PERMISSION_PRIVATE;
+static const int32_t kWidevineCdmPluginPermissions = ppapi::PERMISSION_DEV
+ | ppapi::PERMISSION_PRIVATE;
static QString ppapiPluginsPath()
{
@@ -156,10 +156,11 @@ void AddPepperFlashFromSystem(std::vector<content::PepperPluginInfo>* plugins)
<< "/usr/lib64/chromium/PepperFlash/libpepflashplayer.so"; // OpenSuSE
pluginPaths << ppapiPluginsPath() + QStringLiteral("/libpepflashplayer.so");
#endif
+ std::string flash_version = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kPpapiFlashVersion);
for (auto it = pluginPaths.constBegin(); it != pluginPaths.constEnd(); ++it) {
if (!QFile::exists(*it))
continue;
- plugins->push_back(CreatePepperFlashInfo(QtWebEngineCore::toFilePath(*it), std::string()));
+ plugins->push_back(CreatePepperFlashInfo(QtWebEngineCore::toFilePath(*it), flash_version));
}
}
diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp
index 2f61e1e5e..ee52dd23e 100644
--- a/src/core/content_main_delegate_qt.cpp
+++ b/src/core/content_main_delegate_qt.cpp
@@ -55,6 +55,10 @@
#include "renderer/content_renderer_client_qt.h"
#include "web_engine_library_info.h"
+#if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX))
+#include "base/cpu.h"
+#endif
+
#include <QLocale>
namespace QtWebEngineCore {
@@ -69,6 +73,12 @@ static base::StringPiece PlatformResourceProvider(int key) {
void ContentMainDelegateQt::PreSandboxStartup()
{
+#if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX))
+ // Create an instance of the CPU class to parse /proc/cpuinfo and cache
+ // cpu_brand info.
+ base::CPU cpu_info;
+#endif
+
net::NetModule::SetResourceProvider(PlatformResourceProvider);
ui::ResourceBundle::InitSharedInstanceWithLocale(WebEngineLibraryInfo::getApplicationLocale(), 0, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
@@ -97,10 +107,17 @@ content::ContentRendererClient *ContentMainDelegateQt::CreateContentRendererClie
return new ContentRendererClientQt;
}
+// see icu_util.cc
+#define ICU_UTIL_DATA_FILE 0
+#define ICU_UTIL_DATA_SHARED 1
+#define ICU_UTIL_DATA_STATIC 2
+
bool ContentMainDelegateQt::BasicStartupComplete(int *exit_code)
{
PathService::Override(base::FILE_EXE, WebEngineLibraryInfo::getPath(base::FILE_EXE));
+#if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE
PathService::Override(base::DIR_QT_LIBRARY_DATA, WebEngineLibraryInfo::getPath(base::DIR_QT_LIBRARY_DATA));
+#endif
PathService::Override(content::DIR_MEDIA_LIBS, WebEngineLibraryInfo::getPath(content::DIR_MEDIA_LIBS));
PathService::Override(ui::DIR_LOCALES, WebEngineLibraryInfo::getPath(ui::DIR_LOCALES));
#if defined(ENABLE_SPELLCHECK)
diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro
index 327ad9625..e04e34c5a 100644
--- a/src/core/core_gyp_generator.pro
+++ b/src/core/core_gyp_generator.pro
@@ -81,6 +81,7 @@ SOURCES = \
resource_bundle_qt.cpp \
resource_context_qt.cpp \
resource_dispatcher_host_delegate_qt.cpp \
+ ssl_host_state_delegate_qt.cpp \
stream_video_node.cpp \
surface_factory_qt.cpp \
type_conversion.cpp \
@@ -160,6 +161,7 @@ HEADERS = \
renderer/web_channel_ipc_transport.h \
resource_context_qt.h \
resource_dispatcher_host_delegate_qt.h \
+ ssl_host_state_delegate_qt.h \
stream_video_node.h \
surface_factory_qt.h \
type_conversion.h \
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index f30af83fc..6d2d11d40 100644
--- a/src/core/core_module.pro
+++ b/src/core/core_module.pro
@@ -72,21 +72,28 @@ icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat
locales.path = $$[QT_INSTALL_TRANSLATIONS]/qtwebengine_locales
resources.CONFIG += no_check_exist
resources.path = $$[QT_INSTALL_DATA]/resources
- icu.CONFIG += no_check_exist
- icu.path = $$[QT_INSTALL_DATA]/resources
- INSTALLS += icu locales resources
+ INSTALLS += locales resources
+
+ !use?(system_icu) {
+ icu.CONFIG += no_check_exist
+ icu.path = $$[QT_INSTALL_DATA]/resources
+ INSTALLS += icu
+ }
}
- !contains(QT_CONFIG, qt_framework): contains(QT_CONFIG, private_tests) {
+ !contains(QT_CONFIG, qt_framework):!force_independent {
#
- # Copy essential files to the qtbase build directory (for non-installed developer builds)
+ # Copy essential files to the qtbase build directory for non-prefix builds
#
- icudt2build.input = icu.files
- icudt2build.output = $$[QT_INSTALL_DATA/get]/resources/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
- icudt2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
- icudt2build.name = COPY ${QMAKE_FILE_IN}
- icudt2build.CONFIG = no_link no_clean target_predeps
+ !use?(system_icu) {
+ icudt2build.input = icu.files
+ icudt2build.output = $$[QT_INSTALL_DATA/get]/resources/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
+ icudt2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
+ icudt2build.name = COPY ${QMAKE_FILE_IN}
+ icudt2build.CONFIG = no_link no_clean target_predeps
+ QMAKE_EXTRA_COMPILERS += icudt2build
+ }
resources2build.input = resources.files
resources2build.output = $$[QT_INSTALL_DATA/get]/resources/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
@@ -94,6 +101,14 @@ icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat
resources2build.name = COPY ${QMAKE_FILE_IN}
resources2build.CONFIG = no_link no_clean target_predeps
- QMAKE_EXTRA_COMPILERS += icudt2build resources2build
+ QMAKE_EXTRA_COMPILERS += resources2build
}
}
+
+OTHER_FILES = \
+ $$files(../3rdparty/chromium/*.h, true) \
+ $$files(../3rdparty/chromium/*.cc, true) \
+ $$files(../3rdparty/chromium/*.mm, true) \
+ $$files(../3rdparty/chromium/*.py, true) \
+ $$files(../3rdparty/chromium/*.gyp, true) \
+ $$files(../3rdparty/chromium/*.gypi, true)
diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp
index 62b5398ce..b181f04e3 100644
--- a/src/core/delegated_frame_node.cpp
+++ b/src/core/delegated_frame_node.cpp
@@ -67,11 +67,16 @@
#include "cc/quads/tile_draw_quad.h"
#include "cc/quads/yuv_video_draw_quad.h"
#include "content/common/host_shared_bitmap_manager.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_fence.h"
+
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QSGSimpleRectNode>
#include <QSGSimpleTextureNode>
#include <QSGTexture>
+#include <QtGui/QOffscreenSurface>
#include <private/qsgadaptationlayer_p.h>
#if !defined(QT_NO_EGL)
@@ -112,6 +117,7 @@ private:
#ifdef Q_OS_QNX
EGLStreamData m_eglStreamData;
#endif
+ friend class DelegatedFrameNode;
};
class ResourceHolder {
@@ -371,7 +377,6 @@ cc::ReturnedResource ResourceHolder::returnResource()
// ack directly from our rendering thread. At this point (in updatePaintNode) we know that
// a frame that was compositing any of those resources has already been swapped and we thus
// don't need to use this mechanism.
- returned.sync_point = 0;
returned.id = m_resource.id;
returned.count = m_importCount;
m_importCount = 0;
@@ -411,35 +416,8 @@ void DelegatedFrameNode::preprocess()
mailboxesToFetch.append(static_cast<MailboxTexture *>((*it)->texture()));
}
- if (!mailboxesToFetch.isEmpty()) {
- QMap<uint32, gfx::TransferableFence> transferredFences;
- {
- QMutexLocker lock(&m_mutex);
- base::MessageLoop *gpuMessageLoop = gpu_message_loop();
- gpu::SyncPointManager *syncPointManager = sync_point_manager();
-
- Q_FOREACH (MailboxTexture *mailboxTexture, mailboxesToFetch) {
- m_numPendingSyncPoints++;
- AddSyncPointCallbackOnGpuThread(gpuMessageLoop, syncPointManager, mailboxTexture->mailboxHolder().sync_point, base::Bind(&DelegatedFrameNode::syncPointRetired, this, &mailboxesToFetch));
- }
-
- m_mailboxesFetchedWaitCond.wait(&m_mutex);
- m_mailboxGLFences.swap(transferredFences);
- }
-
- // Tell GL to wait until Chromium is done generating resource textures on the GPU thread
- // for each mailbox. We can safely start referencing those textures onto geometries afterward.
- Q_FOREACH (MailboxTexture *mailboxTexture, mailboxesToFetch) {
- gfx::TransferableFence fence = transferredFences.take(mailboxTexture->mailboxHolder().sync_point);
- waitChromiumSync(&fence);
- deleteChromiumSync(&fence);
- }
- // We transferred all sync point fences from Chromium,
- // destroy all the ones not referenced by one of our mailboxes without waiting.
- QMap<uint32, gfx::TransferableFence>::iterator end = transferredFences.end();
- for (QMap<uint32, gfx::TransferableFence>::iterator it = transferredFences.begin(); it != end; ++it)
- deleteChromiumSync(&*it);
- }
+ if (!mailboxesToFetch.isEmpty())
+ fetchAndSyncMailboxes(mailboxesToFetch);
// Then render any intermediate RenderPass in order.
typedef QPair<cc::RenderPassId, QSharedPointer<QSGLayer> > Pair;
@@ -513,10 +491,10 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData,
// parent, with the last one in the list being the root RenderPass, the one
// that we displayed to the user.
// All RenderPasses except the last one are rendered to an FBO.
- cc::RenderPass *rootRenderPass = frameData->render_pass_list.back();
+ cc::RenderPass *rootRenderPass = frameData->render_pass_list.back().get();
for (unsigned i = 0; i < frameData->render_pass_list.size(); ++i) {
- cc::RenderPass *pass = frameData->render_pass_list.at(i);
+ cc::RenderPass *pass = frameData->render_pass_list.at(i).get();
QSGNode *renderPassParent = 0;
if (pass != rootRenderPass) {
@@ -709,36 +687,124 @@ QSGTexture *DelegatedFrameNode::initAndHoldTexture(ResourceHolder *resource, boo
return m_sgObjects.textureStrongRefs.last().data();
}
-void DelegatedFrameNode::fetchTexturesAndUnlockQt(DelegatedFrameNode *frameNode, QList<MailboxTexture *> *mailboxesToFetch)
+void DelegatedFrameNode::fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxesToFetch)
{
- // Fetch texture IDs from the mailboxes while we're on the GPU thread, where the MailboxManager lives.
- gpu::gles2::MailboxManager *mailboxManager = mailbox_manager();
- Q_FOREACH (MailboxTexture *mailboxTexture, *mailboxesToFetch)
- mailboxTexture->fetchTexture(mailboxManager);
+ QList<gfx::TransferableFence> transferredFences;
+ {
+ QMutexLocker lock(&m_mutex);
+
+ gpu::SyncPointManager *syncPointManager = sync_point_manager();
+ if (!m_syncPointClient)
+ m_syncPointClient = syncPointManager->CreateSyncPointClientWaiter();
+ base::MessageLoop *gpuMessageLoop = gpu_message_loop();
+ Q_ASSERT(m_numPendingSyncPoints == 0);
+ m_numPendingSyncPoints = mailboxesToFetch.count();
+ auto it = mailboxesToFetch.constBegin();
+ auto end = mailboxesToFetch.constEnd();
+ for (; it != end; ++it) {
+ MailboxTexture *mailboxTexture = *it;
+ gpu::SyncToken &syncToken = mailboxTexture->mailboxHolder().sync_token;
+ if (syncToken.HasData()) {
+ scoped_refptr<gpu::SyncPointClientState> release_state =
+ syncPointManager->GetSyncPointClientState(syncToken.namespace_id(), syncToken.command_buffer_id());
+ if (release_state && !release_state->IsFenceSyncReleased(syncToken.release_count())) {
+ m_syncPointClient->WaitOutOfOrderNonThreadSafe(
+ release_state.get(), syncToken.release_count(),
+ gpuMessageLoop->task_runner(), base::Bind(&DelegatedFrameNode::pullTexture, this, mailboxTexture));
+ continue;
+ }
+ }
+ gpuMessageLoop->PostTask(FROM_HERE, base::Bind(&DelegatedFrameNode::pullTexture, this, mailboxTexture));
+ }
- // Pick fences that we can ask GL to wait for before trying to sample the mailbox texture IDs.
- QMap<uint32, gfx::TransferableFence> transferredFences = transferFences();
+ m_mailboxesFetchedWaitCond.wait(&m_mutex);
+ m_textureFences.swap(transferredFences);
+ }
- // Chromium provided everything we were waiting for, let Qt start rendering.
- QMutexLocker lock(&frameNode->m_mutex);
- Q_ASSERT(frameNode->m_mailboxGLFences.isEmpty());
- frameNode->m_mailboxGLFences.swap(transferredFences);
- frameNode->m_mailboxesFetchedWaitCond.wakeOne();
+ Q_FOREACH (gfx::TransferableFence sync, transferredFences) {
+ // We need to wait on the fences on the Qt current context, and
+ // can therefore not use GLFence routines that uses a different
+ // concept of current context.
+ waitChromiumSync(&sync);
+ deleteChromiumSync(&sync);
+ }
+#if defined(USE_X11)
+ // Workaround when context is not shared QTBUG-48969
+ // Make slow copy between two contexts.
+ QOpenGLContext *currentContext = QOpenGLContext::currentContext() ;
+ QOpenGLContext *sharedContext = qt_gl_global_share_context();
+ if (!QOpenGLContext::areSharing(currentContext,sharedContext)) {
+ static bool allowNotSharedContextWarningShown = true;
+ if (allowNotSharedContextWarningShown) {
+ allowNotSharedContextWarningShown = false;
+ qWarning("Context is not shared, textures will be copied between contexts.");
+ }
+
+ Q_FOREACH (MailboxTexture *mailboxTexture, mailboxesToFetch) {
+ QSurface *surface = currentContext->surface();
+ // Read texture into QImage from shared context.
+ // Switch to shared context.
+ QOffscreenSurface offsurface;
+ offsurface.create();
+ sharedContext->makeCurrent(&offsurface);
+ QOpenGLFunctions *funcs = sharedContext->functions();
+ QImage img(mailboxTexture->textureSize(), QImage::Format_RGBA8888_Premultiplied);
+ GLuint fbo = 0;
+ funcs->glGenFramebuffers(1, &fbo);
+ funcs->glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mailboxTexture->m_textureId, 0);
+ GLenum status = funcs->glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ qWarning("fbo error, skipping slow copy...");
+ continue;
+ }
+
+ funcs->glReadPixels(0, 0, mailboxTexture->textureSize().width(), mailboxTexture->textureSize().height(), GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
+ funcs->glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ // Restore current context.
+ currentContext->makeCurrent(surface);
+ // Create texture from QImage in current context.
+ GLuint texture = 0;
+ funcs = currentContext->functions();
+ funcs->glGenTextures(1, &texture);
+ funcs->glBindTexture(GL_TEXTURE_2D, texture);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mailboxTexture->textureSize().width(), mailboxTexture->textureSize().height(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
+ mailboxTexture->m_textureId = texture;
+ }
+ }
+#endif
+}
+
+
+void DelegatedFrameNode::pullTexture(DelegatedFrameNode *frameNode, MailboxTexture *texture)
+{
+ gpu::gles2::MailboxManager *mailboxManager = mailbox_manager();
+ gpu::SyncToken &syncToken = texture->mailboxHolder().sync_token;
+ if (syncToken.HasData())
+ mailboxManager->PullTextureUpdates(syncToken);
+ texture->fetchTexture(mailboxManager);
+ if (!!gfx::GLContext::GetCurrent()) {
+ // Create a fence on the Chromium GPU-thread and context
+ gfx::GLFence *fence = gfx::GLFence::Create();
+ // But transfer it to something generic since we need to read it using Qt's OpenGL.
+ frameNode->m_textureFences.append(fence->Transfer());
+ delete fence;
+ }
+ if (--frameNode->m_numPendingSyncPoints == 0)
+ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&DelegatedFrameNode::fenceAndUnlockQt, frameNode));
}
-void DelegatedFrameNode::syncPointRetired(DelegatedFrameNode *frameNode, QList<MailboxTexture *> *mailboxesToFetch)
+void DelegatedFrameNode::fenceAndUnlockQt(DelegatedFrameNode *frameNode)
{
- // The way that sync points are normally used by the GpuCommandBufferStub is that it asks
- // the GpuScheduler to resume the work of the associated GL command stream / context once
- // the sync point has been retired by the dependency's context. In other words, a produced
- // texture means that the mailbox can be consumed, but the texture itself isn't expected
- // to be ready until to control is given back to the GpuScheduler through the event loop.
- // Do the same for our implementation by posting a message to the event loop once the last
- // of our syncpoints has been retired (the syncpoint callback is called synchronously) and
- // only at this point we wake the Qt rendering thread.
QMutexLocker lock(&frameNode->m_mutex);
- if (!--frameNode->m_numPendingSyncPoints)
- base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&DelegatedFrameNode::fetchTexturesAndUnlockQt, frameNode, mailboxesToFetch));
+ // Signal preprocess() the textures are ready
+ frameNode->m_mailboxesFetchedWaitCond.wakeOne();
}
} // namespace QtWebEngineCore
diff --git a/src/core/delegated_frame_node.h b/src/core/delegated_frame_node.h
index 9c05cb872..8a37f6b4c 100644
--- a/src/core/delegated_frame_node.h
+++ b/src/core/delegated_frame_node.h
@@ -43,6 +43,8 @@
#include "base/memory/scoped_ptr.h"
#include "cc/quads/render_pass.h"
#include "cc/resources/transferable_resource.h"
+#include "gpu/command_buffer/service/sync_point_manager.h"
+#include "ui/gl/gl_fence.h"
#include <QMutex>
#include <QSGNode>
#include <QSharedData>
@@ -83,10 +85,11 @@ public:
void commit(ChromiumCompositorData *chromiumCompositorData, cc::ReturnedResourceArray *resourcesToRelease, RenderWidgetHostViewQtDelegate *apiDelegate);
private:
+ void fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxesToFetch);
// Making those callbacks static bypasses base::Bind's ref-counting requirement
// of the this pointer when the callback is a method.
- static void fetchTexturesAndUnlockQt(DelegatedFrameNode *frameNode, QList<MailboxTexture *> *mailboxesToFetch);
- static void syncPointRetired(DelegatedFrameNode *frameNode, QList<MailboxTexture *> *mailboxesToFetch);
+ static void pullTexture(DelegatedFrameNode *frameNode, MailboxTexture *mailbox);
+ static void fenceAndUnlockQt(DelegatedFrameNode *frameNode);
ResourceHolder *findAndHoldResource(unsigned resourceId, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates);
QSGTexture *initAndHoldTexture(ResourceHolder *resource, bool quadIsAllOpaque, RenderWidgetHostViewQtDelegate *apiDelegate = 0);
@@ -98,9 +101,10 @@ private:
QVector<QSharedPointer<QSGTexture> > textureStrongRefs;
} m_sgObjects;
int m_numPendingSyncPoints;
- QMap<uint32, gfx::TransferableFence> m_mailboxGLFences;
QWaitCondition m_mailboxesFetchedWaitCond;
QMutex m_mutex;
+ QList<gfx::TransferableFence> m_textureFences;
+ scoped_ptr<gpu::SyncPointClient> m_syncPointClient;
};
} // namespace QtWebEngineCore
diff --git a/src/core/dev_tools_http_handler_delegate_qt.cpp b/src/core/dev_tools_http_handler_delegate_qt.cpp
index d15360e16..f3ffcc86d 100644
--- a/src/core/dev_tools_http_handler_delegate_qt.cpp
+++ b/src/core/dev_tools_http_handler_delegate_qt.cpp
@@ -187,7 +187,7 @@ scoped_ptr<DevToolsHttpHandler> createDevToolsHttpHandler()
}
scoped_ptr<DevToolsHttpHandler::ServerSocketFactory> factory(new TCPServerSocketFactory(delegate->bindAddress().toStdString(), delegate->port(), 1));
// Ownership of the delegate is taken over the devtools http handler.
- scoped_ptr<DevToolsHttpHandler> handler(new DevToolsHttpHandler(factory.Pass(), std::string(), delegate, base::FilePath(), base::FilePath(), std::string(), std::string()));
+ scoped_ptr<DevToolsHttpHandler> handler(new DevToolsHttpHandler(std::move(factory), std::string(), delegate, base::FilePath(), base::FilePath(), std::string(), std::string()));
DevToolsDiscoveryManager::GetInstance()->AddProvider(scoped_ptr<DevToolsDiscoveryManager::Provider>(new DevToolsDiscoveryProviderQt()));
return handler;
}
diff --git a/src/core/download_manager_delegate_qt.h b/src/core/download_manager_delegate_qt.h
index cd7e2ecb7..e724b4e23 100644
--- a/src/core/download_manager_delegate_qt.h
+++ b/src/core/download_manager_delegate_qt.h
@@ -94,7 +94,7 @@ private:
void savePackageDownloadCreated(content::DownloadItem *download);
BrowserContextAdapter *m_contextAdapter;
- uint64 m_currentId;
+ uint64_t m_currentId;
base::WeakPtrFactory<DownloadManagerDelegateQt> m_weakPtrFactory;
friend class DownloadManagerDelegateInstance;
diff --git a/src/core/favicon_manager.cpp b/src/core/favicon_manager.cpp
index 6cbb8bc1c..8469f054e 100644
--- a/src/core/favicon_manager.cpp
+++ b/src/core/favicon_manager.cpp
@@ -44,6 +44,8 @@
#include "web_contents_adapter_client.h"
#include "base/bind.h"
+#include "content/public/browser/favicon_status.h"
+#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/web_contents.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkPixelRef.h"
@@ -76,12 +78,12 @@ FaviconManagerPrivate::~FaviconManagerPrivate()
{
}
-int FaviconManagerPrivate::downloadIcon(const QUrl &url, bool candidate)
+int FaviconManagerPrivate::downloadIcon(const QUrl &url)
{
static int fakeId = 0;
int id;
- bool cached = candidate && m_icons.contains(url);
+ bool cached = m_icons.contains(url);
if (isResourceUrl(url) || cached) {
id = --fakeId;
m_pendingRequests.insert(id, url);
@@ -94,13 +96,8 @@ int FaviconManagerPrivate::downloadIcon(const QUrl &url, bool candidate)
base::Bind(&FaviconManagerPrivate::iconDownloadFinished, m_weakFactory.GetWeakPtr()));
}
- if (candidate) {
- Q_ASSERT(!m_inProgressCandidateRequests.contains(id));
- m_inProgressCandidateRequests.insert(id, url);
- } else {
- Q_ASSERT(!m_inProgressCustomRequests.contains(id));
- m_inProgressCustomRequests.insert(id, url);
- }
+ Q_ASSERT(!m_inProgressRequests.contains(id));
+ m_inProgressRequests.insert(id, url);
return id;
}
@@ -118,12 +115,10 @@ void FaviconManagerPrivate::iconDownloadFinished(int id,
storeIcon(id, toQIcon(bitmaps));
}
-/* Pending requests are used as a workaround for avoiding signal iconChanged when
- * accessing each cached icons or icons stored in qrc. They don't have to be downloaded
- * thus the m_inProgressCustomRequests maybe emptied right before the next icon is added to
- * in-progress-requests queue. The m_pendingRequests stores these requests until all
- * candidates are added to the queue then pending requests should be cleaned up by this
- * function.
+/* Pending requests are used to mark icons that are already downloaded (cached icons or icons
+ * stored in qrc). These requests are also stored in the m_inProgressRequests but the corresponding
+ * icons are stored in m_icons explicitly by this function. It is necessary to avoid
+ * m_inProgressRequests being emptied right before the next icon is added by a downloadIcon() call.
*/
void FaviconManagerPrivate::downloadPendingRequests()
{
@@ -143,10 +138,9 @@ void FaviconManagerPrivate::downloadPendingRequests()
void FaviconManagerPrivate::storeIcon(int id, const QIcon &icon)
{
Q_Q(FaviconManager);
+ Q_ASSERT(m_inProgressRequests.contains(id));
- bool candidate = m_inProgressCandidateRequests.contains(id);
-
- QUrl requestUrl = candidate ? m_inProgressCandidateRequests[id] : m_inProgressCustomRequests[id];
+ QUrl requestUrl = m_inProgressRequests[id];
FaviconInfo &faviconInfo = q->m_faviconInfoMap[requestUrl];
unsigned iconCount = 0;
@@ -168,29 +162,46 @@ void FaviconManagerPrivate::storeIcon(int id, const QIcon &icon)
}
}
}
-
- q->m_hasDownloadedIcon = true;
- } else if (id < 0) {
- // Icon is cached
- q->m_hasDownloadedIcon = true;
- } else {
+ } else if (id >= 0) {
// Reset size if icon cannot be downloaded
faviconInfo.size = QSize(0, 0);
}
- if (candidate) {
- m_inProgressCandidateRequests.remove(id);
- if (m_inProgressCandidateRequests.isEmpty())
- m_viewClient->iconChanged(q->getProposedFaviconInfo().url);
- } else {
- m_inProgressCustomRequests.remove(id);
+ m_inProgressRequests.remove(id);
+ if (m_inProgressRequests.isEmpty())
+ propagateIcon();
+}
+
+void FaviconManagerPrivate::propagateIcon() const
+{
+ Q_Q(const FaviconManager);
+
+ QUrl iconUrl;
+ const QList<FaviconInfo> &faviconInfoList = q->getFaviconInfoList(true /* candidates only */);
+
+ unsigned bestArea = 0;
+ for (auto it = faviconInfoList.cbegin(), end = faviconInfoList.cend(); it != end; ++it) {
+ if (it->type != FaviconInfo::Favicon)
+ continue;
+
+ if (it->isValid() && bestArea < area(it->size)) {
+ iconUrl = it->url;
+ bestArea = area(it->size);
+ }
}
- Q_EMIT q->iconDownloaded(requestUrl);
+ content::NavigationEntry *entry = m_webContents->GetController().GetVisibleEntry();
+ if (entry) {
+ content::FaviconStatus &favicon = entry->GetFavicon();
+ favicon.url = toGurl(iconUrl);
+ favicon.valid = true;
+ }
+
+ m_viewClient->iconChanged(iconUrl);
}
FaviconManager::FaviconManager(FaviconManagerPrivate *d)
- : m_hasDownloadedIcon(false)
+ : m_hasCandidate(false)
{
Q_ASSERT(d);
d_ptr.reset(d);
@@ -228,121 +239,59 @@ QList<FaviconInfo> FaviconManager::getFaviconInfoList(bool candidatesOnly) const
return faviconInfoList;
}
-
-void FaviconManager::downloadIcon(const QUrl &url, FaviconInfo::FaviconType iconType)
-{
- Q_D(FaviconManager);
-
- // If the favicon cannot be found in the list that means that it is not a candidate
- // for any visited page (including the current one). In this case the type of the icon
- // is unknown: it has to be specified explicitly.
- if (!m_faviconInfoMap.contains(url)) {
- FaviconInfo newFaviconInfo(url, iconType);
- m_faviconInfoMap.insert(url, newFaviconInfo);
- }
-
- d->downloadIcon(url, false);
- d->downloadPendingRequests();
-}
-
-void FaviconManager::removeIcon(const QUrl &url)
-{
- Q_D(FaviconManager);
- int removed = d->m_icons.remove(url);
-
- if (removed) {
- Q_ASSERT(removed == 1);
- Q_ASSERT(m_faviconInfoMap.contains(url));
- m_faviconInfoMap[url].size = QSize(0, 0);
- }
-}
-
-bool FaviconManager::hasAvailableCandidateIcon() const
-{
- Q_D(const FaviconManager);
- return m_hasDownloadedIcon || !d->m_inProgressCandidateRequests.isEmpty();
-}
-
void FaviconManager::update(const QList<FaviconInfo> &candidates)
{
Q_D(FaviconManager);
updateCandidates(candidates);
- for (auto it = m_faviconInfoMap.cbegin(), end = m_faviconInfoMap.cend(); it != end; ++it) {
- const FaviconInfo &faviconInfo = it.value();
- if (!faviconInfo.candidate || faviconInfo.type != FaviconInfo::Favicon)
+ const QList<FaviconInfo> &faviconInfoList = getFaviconInfoList(true /* candidates only */);
+ for (auto it = faviconInfoList.cbegin(), end = faviconInfoList.cend(); it != end; ++it) {
+ if (it->type != FaviconInfo::Favicon)
continue;
- if (faviconInfo.isValid())
- d->downloadIcon(faviconInfo.url, true);
+ if (it->isValid())
+ d->downloadIcon(it->url);
}
d->downloadPendingRequests();
+
+ // Reset icon if nothing was downloaded
+ if (d->m_inProgressRequests.isEmpty()) {
+ content::NavigationEntry *entry = d->m_webContents->GetController().GetVisibleEntry();
+ if (entry && !entry->GetFavicon().valid)
+ d->m_viewClient->iconChanged(QUrl());
+ }
}
void FaviconManager::updateCandidates(const QList<FaviconInfo> &candidates)
{
+ m_hasCandidate = candidates.count();
for (FaviconInfo candidateFaviconInfo : candidates) {
- QUrl candidateUrl = candidateFaviconInfo.url;
- if (m_faviconInfoMap.contains(candidateUrl)) {
- m_faviconInfoMap[candidateUrl].candidate = true;
- // Update type in case of the icon was downloaded manually
+ const QUrl &candidateUrl = candidateFaviconInfo.url;
+
+ if (!m_faviconInfoMap.contains(candidateUrl))
+ m_faviconInfoMap.insert(candidateUrl, candidateFaviconInfo);
+ else {
+ // The same icon can be used for more than one page with different types.
m_faviconInfoMap[candidateUrl].type = candidateFaviconInfo.type;
- continue;
}
- candidateFaviconInfo.candidate = true;
- m_faviconInfoMap.insert(candidateUrl, candidateFaviconInfo);
+ m_faviconInfoMap[candidateUrl].candidate = true;
}
}
void FaviconManager::resetCandidates()
{
- m_hasDownloadedIcon = false;
+ m_hasCandidate = false;
for (auto it = m_faviconInfoMap.begin(), end = m_faviconInfoMap.end(); it != end; ++it)
it->candidate = false;
}
-
-FaviconInfo FaviconManager::getProposedFaviconInfo() const
+bool FaviconManager::hasCandidate() const
{
- FaviconInfo proposedFaviconInfo = getFirstFaviconInfo();
-
- // If nothing has been downloaded yet return the first favicon
- // if there is available for dev-tools
- if (!m_hasDownloadedIcon)
- return proposedFaviconInfo;
-
- unsigned bestArea = area(proposedFaviconInfo.size);
- for (auto it = m_faviconInfoMap.cbegin(), end = m_faviconInfoMap.cend(); it != end; ++it) {
- const FaviconInfo &faviconInfo = it.value();
- if (!faviconInfo.candidate || faviconInfo.type != FaviconInfo::Favicon)
- continue;
-
- if (faviconInfo.isValid() && bestArea < area(faviconInfo.size)) {
- proposedFaviconInfo = faviconInfo;
- bestArea = area(proposedFaviconInfo.size);
- }
- }
-
- return proposedFaviconInfo;
+ return m_hasCandidate;
}
-FaviconInfo FaviconManager::getFirstFaviconInfo() const
-{
- for (auto it = m_faviconInfoMap.cbegin(), end = m_faviconInfoMap.cend(); it != end; ++it) {
- const FaviconInfo &faviconInfo = it.value();
- if (!faviconInfo.candidate || faviconInfo.type != FaviconInfo::Favicon)
- continue;
-
- if (faviconInfo.isValid())
- return faviconInfo;
- }
-
- return FaviconInfo();
-}
-
-
FaviconInfo::FaviconInfo()
: url(QUrl())
diff --git a/src/core/favicon_manager.h b/src/core/favicon_manager.h
index ff5c76a9b..dc702a0da 100644
--- a/src/core/favicon_manager.h
+++ b/src/core/favicon_manager.h
@@ -73,7 +73,7 @@ public:
QUrl url;
FaviconType type;
- // Stores the size of the highest quality in case of multi-size icon
+ // Stores the largest size in case of multi-size icon
QSize size;
bool candidate;
bool multiSize;
@@ -88,25 +88,17 @@ public:
QIcon getIcon(const QUrl &) const;
FaviconInfo getFaviconInfo(const QUrl &) const;
QList<FaviconInfo> getFaviconInfoList(bool) const;
- void downloadIcon(const QUrl &url, FaviconInfo::FaviconType iconType = FaviconInfo::Favicon);
- void removeIcon(const QUrl &);
-
-Q_SIGNALS:
- void iconDownloaded(const QUrl &url);
private:
FaviconManager(FaviconManagerPrivate *);
- bool hasAvailableCandidateIcon() const;
void update(const QList<FaviconInfo> &);
void updateCandidates(const QList<FaviconInfo> &);
void resetCandidates();
-
- FaviconInfo getProposedFaviconInfo() const;
- FaviconInfo getFirstFaviconInfo() const;
+ bool hasCandidate() const;
QMap<QUrl, FaviconInfo> m_faviconInfoMap;
- bool m_hasDownloadedIcon;
+ bool m_hasCandidate;
Q_DISABLE_COPY(FaviconManager)
Q_DECLARE_PRIVATE(FaviconManager)
diff --git a/src/core/favicon_manager_p.h b/src/core/favicon_manager_p.h
index 8358245a2..80a012474 100644
--- a/src/core/favicon_manager_p.h
+++ b/src/core/favicon_manager_p.h
@@ -82,19 +82,19 @@ public:
FaviconManagerPrivate(content::WebContents *, WebContentsAdapterClient *);
~FaviconManagerPrivate();
- int downloadIcon(const QUrl &, bool);
+ int downloadIcon(const QUrl &);
void iconDownloadFinished(int, int, const GURL &, const std::vector<SkBitmap> &, const std::vector<gfx::Size> &);
void storeIcon(int, const QIcon &);
void downloadPendingRequests();
+ void propagateIcon() const;
content::WebContents *m_webContents;
WebContentsAdapterClient *m_viewClient;
base::WeakPtrFactory<FaviconManagerPrivate> m_weakFactory;
QMap<QUrl, QIcon> m_icons;
- QMap<int, QUrl> m_inProgressCandidateRequests;
- QMap<int, QUrl> m_inProgressCustomRequests;
+ QMap<int, QUrl> m_inProgressRequests;
QMap<int, QUrl> m_pendingRequests;
Q_DECLARE_PUBLIC(FaviconManager)
diff --git a/src/core/gl_surface_qt.cpp b/src/core/gl_surface_qt.cpp
index f77bd0637..0124ae66d 100644
--- a/src/core/gl_surface_qt.cpp
+++ b/src/core/gl_surface_qt.cpp
@@ -99,7 +99,7 @@ public:
virtual bool Initialize() Q_DECL_OVERRIDE;
virtual void Destroy() Q_DECL_OVERRIDE;
virtual void* GetHandle() Q_DECL_OVERRIDE;
- virtual bool Resize(const gfx::Size &size) Q_DECL_OVERRIDE;
+ virtual bool Resize(const gfx::Size& size, float scale_factor, bool has_alpha) Q_DECL_OVERRIDE;
protected:
~GLSurfaceQtEGL();
@@ -378,6 +378,16 @@ bool GLSurfaceEGL::IsCreateContextRobustnessSupported()
return false;
}
+const char* GLSurfaceEGL::GetEGLExtensions()
+{
+ return g_extensions;
+}
+
+bool GLSurfaceEGL::HasEGLExtension(const char* name)
+{
+ return ExtensionsContain(GetEGLExtensions(), name);
+}
+
GLSurfaceQt::GLSurfaceQt(const gfx::Size& size)
: m_size(size)
{
@@ -454,7 +464,8 @@ gfx::Size GLSurfaceQt::GetSize()
return m_size;
}
-bool GLSurfaceQtEGL::Resize(const gfx::Size& size)
+
+bool GLSurfaceQtEGL::Resize(const gfx::Size& size, float scale_factor, bool has_alpha)
{
if (size == m_size)
return true;
diff --git a/src/core/gyp_run.pro b/src/core/gyp_run.pro
index dea1a2225..51fe9ad1d 100644
--- a/src/core/gyp_run.pro
+++ b/src/core/gyp_run.pro
@@ -44,11 +44,11 @@ cross_compile {
# Needed for v8, see chromium/v8/build/toolchain.gypi
GYP_CONFIG += CXX=\"$$which($$QMAKE_CXX)\"
}
+else {
+ GYP_CONFIG += sysroot=\"\"
+}
contains(QT_ARCH, "arm") {
- # Chromium will set a default sysroot on arm unless we give it one.
- !cross_compile: GYP_CONFIG += sysroot=\"\"
-
GYP_CONFIG += target_arch=arm
# Extract ARM specific compiler options that we have to pass to gyp,
@@ -83,11 +83,29 @@ contains(QT_ARCH, "arm") {
contains(QMAKE_CFLAGS, "-mthumb"): GYP_CONFIG += arm_thumb=1
}
+contains(QT_ARCH, "mips") {
+ !cross_compile: GYP_CONFIG += sysroot=\"\"
+ GYP_CONFIG += target_arch=mipsel
+
+ contains(QMAKE_CFLAGS, "mips32r6"): mips_arch_variant=\"r6\"
+ else: contains(QMAKE_CFLAGS, "mips32r2"): mips_arch_variant=\"r2\"
+ else: contains(QMAKE_CFLAGS, "mips32"): mips_arch_variant=\"r1\"
+
+ contains(QMAKE_CFLAGS, "-mdsp2"): GYP_CONFIG += mips_dsp_rev=2
+ else: contains(QMAKE_CFLAGS, "-mdsp"): GYP_CONFIG += mips_dsp_rev=1
+}
+
contains(QT_ARCH, "x86_64"): GYP_CONFIG += target_arch=x64
contains(QT_ARCH, "i386"): GYP_CONFIG += target_arch=ia32
contains(QT_ARCH, "arm64"): GYP_CONFIG += target_arch=arm64
+contains(QT_ARCH, "mips64"): GYP_CONFIG += target_arch=mips64el
contains(WEBENGINE_CONFIG, use_proprietary_codecs): GYP_CONFIG += proprietary_codecs=1 ffmpeg_branding=Chrome
+contains(WEBENGINE_CONFIG, use_appstore_compliant_code): GYP_CONFIG += appstore_compliant_code=1
+
+# Compiling with -Os makes a huge difference in binary size, and the unwind tables is another big part,
+# but the latter are necessary for useful debug binaries.
+contains(WEBENGINE_CONFIG, reduce_binary_size): GYP_CONFIG += release_optimize=s debug_optimize=s release_unwind_tables=0
!contains(QT_CONFIG, qt_framework): contains(QT_CONFIG, private_tests) {
GYP_CONFIG += qt_install_data=\"$$[QT_INSTALL_DATA/get]\"
diff --git a/src/core/media_capture_devices_dispatcher.cpp b/src/core/media_capture_devices_dispatcher.cpp
index db5caa4e1..4d1e8b200 100644
--- a/src/core/media_capture_devices_dispatcher.cpp
+++ b/src/core/media_capture_devices_dispatcher.cpp
@@ -101,7 +101,7 @@ scoped_ptr<content::MediaStreamUI> getDevicesForDesktopCapture(content::MediaStr
media::AudioManagerBase::kLoopbackInputDeviceId, "System Audio"));
}
- return ui.Pass();
+ return std::move(ui);
}
WebContentsAdapterClient::MediaRequestFlags mediaRequestFlagsForRequest(const content::MediaStreamRequest &request)
@@ -161,7 +161,7 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content:
(request.video_type && authorizationFlags & WebContentsAdapterClient::MediaVideoCapture);
if (securityOriginsMatch && (microphoneRequested || webcamRequested)) {
switch (request.request_type) {
- case content::MEDIA_OPEN_DEVICE:
+ case content::MEDIA_OPEN_DEVICE_PEPPER_ONLY:
Q_UNREACHABLE(); // only speculative as this is for Pepper
getDefaultDevices("", "", microphoneRequested, webcamRequested, &devices);
break;
@@ -248,7 +248,7 @@ void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content::
scoped_ptr<content::MediaStreamUI> ui;
if (request.video_type != content::MEDIA_DESKTOP_VIDEO_CAPTURE) {
- callback.Run(devices, content::MEDIA_DEVICE_INVALID_STATE, ui.Pass());
+ callback.Run(devices, content::MEDIA_DEVICE_INVALID_STATE, std::move(ui));
return;
}
@@ -277,7 +277,7 @@ void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content::
// Received invalid device id.
if (mediaId.type == content::DesktopMediaID::TYPE_NONE) {
- callback.Run(devices, content::MEDIA_DEVICE_INVALID_STATE, ui.Pass());
+ callback.Run(devices, content::MEDIA_DEVICE_INVALID_STATE, std::move(ui));
return;
}
@@ -289,7 +289,7 @@ void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content::
devices, mediaId, capture_audio, true,
getContentsUrl(webContents));
- callback.Run(devices, devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE : content::MEDIA_DEVICE_OK, ui.Pass());
+ callback.Run(devices, devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE : content::MEDIA_DEVICE_OK, std::move(ui));
}
void MediaCaptureDevicesDispatcher::processScreenCaptureAccessRequest(content::WebContents *webContents, const content::MediaStreamRequest &request
@@ -339,7 +339,7 @@ void MediaCaptureDevicesDispatcher::handleScreenCaptureAccessRequest(content::We
content::MediaResponseCallback callback = queue.front().callback;
queue.pop_front();
- callback.Run(devices, devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE : content::MEDIA_DEVICE_OK, ui.Pass());
+ callback.Run(devices, devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE : content::MEDIA_DEVICE_OK, std::move(ui));
}
void MediaCaptureDevicesDispatcher::enqueueMediaAccessRequest(content::WebContents *webContents, const content::MediaStreamRequest &request
diff --git a/src/core/network_delegate_qt.cpp b/src/core/network_delegate_qt.cpp
index 51acbb644..cb2a9dc58 100644
--- a/src/core/network_delegate_qt.cpp
+++ b/src/core/network_delegate_qt.cpp
@@ -60,7 +60,7 @@ namespace QtWebEngineCore {
int pageTransitionToNavigationType(ui::PageTransition transition)
{
- int32 qualifier = ui::PageTransitionGetQualifier(transition);
+ int32_t qualifier = ui::PageTransitionGetQualifier(transition);
if (qualifier & ui::PAGE_TRANSITION_FORWARD_BACK)
return WebContentsAdapterClient::BackForwardNavigation;
@@ -114,7 +114,7 @@ int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, const net::C
QWebEngineUrlRequestInfo requestInfo(infoPrivate);
interceptor->interceptRequest(requestInfo);
if (requestInfo.changed()) {
- int result = infoPrivate->shouldBlockRequest ? net::ERR_ABORTED : net::OK;
+ int result = infoPrivate->shouldBlockRequest ? net::ERR_BLOCKED_BY_CLIENT : net::OK;
if (qUrl != infoPrivate->url)
*newUrl = toGurl(infoPrivate->url);
@@ -264,15 +264,11 @@ void NetworkDelegateQt::OnResponseStarted(net::URLRequest*)
{
}
-void NetworkDelegateQt::OnNetworkBytesReceived(const net::URLRequest&, int64_t)
+void NetworkDelegateQt::OnNetworkBytesReceived(net::URLRequest*, int64_t)
{
}
-void NetworkDelegateQt::OnNetworkBytesSent(const net::URLRequest&, int64_t)
-{
-}
-
-void NetworkDelegateQt::OnURLRequestJobOrphaned(net::URLRequest*)
+void NetworkDelegateQt::OnNetworkBytesSent(net::URLRequest*, int64_t)
{
}
@@ -304,7 +300,12 @@ bool NetworkDelegateQt::OnCanEnablePrivacyMode(const GURL&, const GURL&) const
return false;
}
-bool NetworkDelegateQt::OnFirstPartyOnlyCookieExperimentEnabled() const
+bool NetworkDelegateQt::OnAreExperimentalCookieFeaturesEnabled() const
+{
+ return false;
+}
+
+bool NetworkDelegateQt::OnAreStrictSecureCookiesEnabled() const
{
return false;
}
diff --git a/src/core/network_delegate_qt.h b/src/core/network_delegate_qt.h
index 4dc6ad28e..1324e0da3 100644
--- a/src/core/network_delegate_qt.h
+++ b/src/core/network_delegate_qt.h
@@ -84,16 +84,16 @@ public:
virtual int OnHeadersReceived(net::URLRequest*, const net::CompletionCallback&, const net::HttpResponseHeaders*, scoped_refptr<net::HttpResponseHeaders>*, GURL*) override;
virtual void OnBeforeRedirect(net::URLRequest*, const GURL&) override;
virtual void OnResponseStarted(net::URLRequest*) override;
- virtual void OnNetworkBytesReceived(const net::URLRequest&, int64_t) override;
- virtual void OnNetworkBytesSent(const net::URLRequest&, int64_t) override;
- virtual void OnURLRequestJobOrphaned(net::URLRequest*) override;
+ virtual void OnNetworkBytesReceived(net::URLRequest*, int64_t) override;
+ virtual void OnNetworkBytesSent(net::URLRequest *, int64_t) override;
virtual void OnCompleted(net::URLRequest*, bool) override;
virtual void OnPACScriptError(int, const base::string16&) override;
virtual net::NetworkDelegate::AuthRequiredResponse OnAuthRequired(net::URLRequest*, const net::AuthChallengeInfo&, const AuthCallback&, net::AuthCredentials*) override;
virtual bool OnCanGetCookies(const net::URLRequest&, const net::CookieList&) override;
virtual bool OnCanAccessFile(const net::URLRequest& request, const base::FilePath& path) const override;
virtual bool OnCanEnablePrivacyMode(const GURL&, const GURL&) const override;
- virtual bool OnFirstPartyOnlyCookieExperimentEnabled() const override;
+ virtual bool OnAreExperimentalCookieFeaturesEnabled() const override;
+ virtual bool OnAreStrictSecureCookiesEnabled() const override;
virtual bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(const net::URLRequest&, const GURL&, const GURL&) const override;
};
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index a1c4c876d..1562a02c2 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -110,7 +110,7 @@ int PermissionManagerQt::RequestPermission(content::PermissionType permission,
BrowserContextAdapter::PermissionType permissionType = toQt(permission);
if (permissionType == BrowserContextAdapter::UnsupportedPermission) {
callback.Run(content::PERMISSION_STATUS_DENIED);
- return request_id;
+ return kNoPendingOperation;
}
content::WebContents *webContents = frameHost->GetRenderViewHost()->GetDelegate()->GetAsWebContents();
@@ -127,6 +127,35 @@ int PermissionManagerQt::RequestPermission(content::PermissionType permission,
return request_id;
}
+int PermissionManagerQt::RequestPermissions(const std::vector<content::PermissionType>& permissions,
+ content::RenderFrameHost* frameHost,
+ const GURL& requesting_origin,
+ bool user_gesture,
+ const base::Callback<void(const std::vector<content::PermissionStatus>&)>& callback)
+{
+ NOTIMPLEMENTED() << "RequestPermissions has not been implemented in QtWebEngine";
+ Q_UNUSED(user_gesture);
+ Q_UNUSED(frameHost);
+
+ std::vector<content::PermissionStatus> result(permissions.size());
+ for (content::PermissionType permission : permissions) {
+ const BrowserContextAdapter::PermissionType permissionType = toQt(permission);
+ if (permissionType == BrowserContextAdapter::UnsupportedPermission)
+ result.push_back(content::PERMISSION_STATUS_DENIED);
+ else {
+ QPair<QUrl, BrowserContextAdapter::PermissionType> key(toQt(requesting_origin), permissionType);
+ // TODO: Request permission from UI
+ if (m_permissions.contains(key) && m_permissions[key])
+ result.push_back(content::PERMISSION_STATUS_GRANTED);
+ else
+ result.push_back(content::PERMISSION_STATUS_DENIED);
+ }
+ }
+
+ callback.Run(result);
+ return kNoPendingOperation;
+}
+
void PermissionManagerQt::CancelPermissionRequest(int request_id)
{
// Should we add API to cancel permissions in the UI level?
diff --git a/src/core/permission_manager_qt.h b/src/core/permission_manager_qt.h
index 0caeb4bd8..7c42a06e7 100644
--- a/src/core/permission_manager_qt.h
+++ b/src/core/permission_manager_qt.h
@@ -78,6 +78,14 @@ public:
const GURL& requesting_origin,
const GURL& embedding_origin) override;
+ int RequestPermissions(
+ const std::vector<content::PermissionType>& permission,
+ content::RenderFrameHost* render_frame_host,
+ const GURL& requesting_origin,
+ bool user_gesture,
+ const base::Callback<void(
+ const std::vector<content::PermissionStatus>&)>& callback) override;
+
void RegisterPermissionUsage(
content::PermissionType permission,
const GURL& requesting_origin,
diff --git a/src/core/print_view_manager_base_qt.cpp b/src/core/print_view_manager_base_qt.cpp
index ea6345f94..60f166423 100644
--- a/src/core/print_view_manager_base_qt.cpp
+++ b/src/core/print_view_manager_base_qt.cpp
@@ -289,7 +289,7 @@ void PrintViewManagerBaseQt::OnDidPrintPage(
#else
// Update the rendered document. It will send notifications to the listener.
document->SetPage(params.page_number,
- metafile.Pass(),
+ std::move(metafile),
#if defined(OS_WIN)
1.0f, // shrink factor, needed on windows.
#endif // defined(OS_WIN)
@@ -477,7 +477,7 @@ bool PrintViewManagerBaseQt::RunInnerMessageLoop() {
base::OneShotTimer quit_timer;
quit_timer.Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(kPrinterSettingsTimeout),
- base::MessageLoop::current(), &base::MessageLoop::Quit);
+ base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle);
m_isInsideInnerMessageLoop = true;
@@ -512,7 +512,7 @@ void PrintViewManagerBaseQt::ShouldQuitFromInnerMessageLoop()
m_isInsideInnerMessageLoop) {
// We are in a message loop created by RenderAllMissingPagesNow. Quit from
// it.
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
m_isInsideInnerMessageLoop = false;
}
}
diff --git a/src/core/print_view_manager_qt.cpp b/src/core/print_view_manager_qt.cpp
index f9b9c9f29..4cb0e06eb 100644
--- a/src/core/print_view_manager_qt.cpp
+++ b/src/core/print_view_manager_qt.cpp
@@ -57,17 +57,28 @@
DEFINE_WEB_CONTENTS_USER_DATA_KEY(QtWebEngineCore::PrintViewManagerQt);
namespace {
-static int request_id = 0;
static const qreal kMicronsToMillimeter = 1000.0f;
-static scoped_refptr<base::RefCountedBytes>
-GetDataFromHandle(base::SharedMemoryHandle handle, uint32 data_size) {
+static std::vector<char>
+GetStdVectorFromHandle(base::SharedMemoryHandle handle, uint32_t data_size) {
scoped_ptr<base::SharedMemory> shared_buf(
new base::SharedMemory(handle, true));
if (!shared_buf->Map(data_size)) {
- NOTREACHED();
- return NULL;
+ return std::vector<char>();
+ }
+
+ char* data = static_cast<char*>(shared_buf->memory());
+ return std::vector<char>(data, data + data_size);
+}
+
+static scoped_refptr<base::RefCountedBytes>
+GetBytesFromHandle(base::SharedMemoryHandle handle, uint32_t data_size) {
+ scoped_ptr<base::SharedMemory> shared_buf(
+ new base::SharedMemory(handle, true));
+
+ if (!shared_buf->Map(data_size)) {
+ return NULL;
}
unsigned char* data = static_cast<unsigned char*>(shared_buf->memory());
@@ -77,8 +88,7 @@ GetDataFromHandle(base::SharedMemoryHandle handle, uint32 data_size) {
// Write the PDF file to disk.
static void SavePdfFile(scoped_refptr<base::RefCountedBytes> data,
- const base::FilePath& path,
- const base::Callback<void(bool)>& callback) {
+ const base::FilePath& path) {
DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
DCHECK_GT(data->size(), 0U);
@@ -87,29 +97,26 @@ static void SavePdfFile(scoped_refptr<base::RefCountedBytes> data,
base::File file(path,
base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
- bool ok = file.IsValid() && metafile.SaveTo(&file);
-
- if (!callback.is_null()) {
- content::BrowserThread::PostTask(content::BrowserThread::UI,
- FROM_HERE,
- base::Bind(callback, ok));
- }
+ if (file.IsValid())
+ metafile.SaveTo(&file);
}
static void applyQPageLayoutSettingsToDictionary(const QPageLayout& pageLayout, base::DictionaryValue& print_settings)
{
+ // TO DO: Check if we can use the request ID from Qt here somehow.
+ static int internalRequestId = 0;
+
+ print_settings.SetBoolean(printing::kIsFirstRequest, internalRequestId++ == 0);
+ print_settings.SetInteger(printing::kPreviewRequestID, internalRequestId);
//Set page size attributes, chromium expects these in micrometers
QSizeF pageSizeInMilimeter = pageLayout.pageSize().size(QPageSize::Millimeter);
scoped_ptr<base::DictionaryValue> sizeDict(new base::DictionaryValue);
sizeDict->SetInteger(printing::kSettingMediaSizeWidthMicrons, pageSizeInMilimeter.width() * kMicronsToMillimeter);
sizeDict->SetInteger(printing::kSettingMediaSizeHeightMicrons, pageSizeInMilimeter.height() * kMicronsToMillimeter);
- print_settings.Set(printing::kSettingMediaSize, sizeDict.Pass());
+ print_settings.Set(printing::kSettingMediaSize, std::move(sizeDict));
print_settings.SetBoolean(printing::kSettingLandscape, pageLayout.orientation() == QPageLayout::Landscape);
- print_settings.SetInteger(printing::kPreviewRequestID, request_id++);
- print_settings.SetBoolean(printing::kIsFirstRequest, request_id != 0);
-
// The following are standard settings that Chromium expects to be set.
print_settings.SetBoolean(printing::kSettingPrintToPDF, true);
print_settings.SetBoolean(printing::kSettingCloudPrintDialog, false);
@@ -144,21 +151,51 @@ PrintViewManagerQt::~PrintViewManagerQt()
#if defined(ENABLE_BASIC_PRINTING)
bool PrintViewManagerQt::PrintToPDF(const QPageLayout &pageLayout, const QString &filePath)
{
- return PrintToPDFWithCallback(pageLayout, filePath, base::Callback<void(bool)>());
+ if (m_printSettings || !filePath.length())
+ return false;
+
+ m_pdfOutputPath = toFilePath(filePath);
+ if (!PrintToPDFInternal(pageLayout)) {
+ resetPdfState();
+ return false;
+ }
+ return true;
}
-bool PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout, const QString &filePath, base::Callback<void(bool)> callback)
+bool PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout, const PrintToPDFCallback& callback)
{
+ if (callback.is_null())
+ return false;
+
// If there already is a pending print in progress, don't try starting another one.
- if (m_printSettings)
+ if (m_printSettings) {
+ content::BrowserThread::PostTask(content::BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(callback, std::vector<char>()));
return false;
+ }
+ m_pdfPrintCallback = callback;
+ if (!PrintToPDFInternal(pageLayout)) {
+ content::BrowserThread::PostTask(content::BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(callback, std::vector<char>()));
+
+ resetPdfState();
+ return false;
+ }
+ return true;
+}
+
+bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout)
+{
+ if (!pageLayout.isValid())
+ return false;
m_printSettings.reset(new base::DictionaryValue());
applyQPageLayoutSettingsToDictionary(pageLayout, *m_printSettings);
- m_pdfOutputPath = toFilePath(filePath);
-
return Send(new PrintMsg_InitiatePrintPreview(routing_id(), false));
}
+
#endif // defined(ENABLE_BASIC_PRINTING)
// PrintedPagesSource implementation.
@@ -208,24 +245,23 @@ void PrintViewManagerQt::OnMetafileReadyForPrinting(
{
StopWorker(params.document_cookie);
- scoped_refptr<base::RefCountedBytes> data_bytes =
- GetDataFromHandle(params.metafile_data_handle, params.data_size);
- if (!data_bytes || !data_bytes->size()) {
- resetPdfState();
- return;
- }
-
// Create local copies so we can reset the state and take a new pdf print job.
- base::Callback<void(bool)> pdf_print_callback = m_pdfPrintCallback;
+ base::Callback<void(const std::vector<char>&)> pdf_print_callback = m_pdfPrintCallback;
base::FilePath pdfOutputPath = m_pdfOutputPath;
- // Save the PDF file to disk and then execute the callback.
- content::BrowserThread::PostTask(content::BrowserThread::FILE,
- FROM_HERE,
- base::Bind(&SavePdfFile, data_bytes, pdfOutputPath,
- pdf_print_callback));
-
resetPdfState();
+
+ if (!pdf_print_callback.is_null()) {
+ std::vector<char> data_vector = GetStdVectorFromHandle(params.metafile_data_handle, params.data_size);
+ content::BrowserThread::PostTask(content::BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(pdf_print_callback, data_vector));
+ } else {
+ scoped_refptr<base::RefCountedBytes> data_bytes = GetBytesFromHandle(params.metafile_data_handle, params.data_size);
+ content::BrowserThread::PostTask(content::BrowserThread::FILE,
+ FROM_HERE,
+ base::Bind(&SavePdfFile, data_bytes, pdfOutputPath));
+ }
}
void PrintViewManagerQt::OnDidShowPrintDialog()
@@ -241,12 +277,22 @@ void PrintViewManagerQt::DidStartLoading()
// Cancels the print job.
void PrintViewManagerQt::NavigationStopped()
{
+ if (!m_pdfPrintCallback.is_null()) {
+ content::BrowserThread::PostTask(content::BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(m_pdfPrintCallback, std::vector<char>()));
+ }
resetPdfState();
}
void PrintViewManagerQt::RenderProcessGone(base::TerminationStatus status)
{
PrintViewManagerBaseQt::RenderProcessGone(status);
+ if (!m_pdfPrintCallback.is_null()) {
+ content::BrowserThread::PostTask(content::BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(m_pdfPrintCallback, std::vector<char>()));
+ }
resetPdfState();
}
diff --git a/src/core/print_view_manager_qt.h b/src/core/print_view_manager_qt.h
index 6ef7ec754..88a499f1b 100644
--- a/src/core/print_view_manager_qt.h
+++ b/src/core/print_view_manager_qt.h
@@ -80,11 +80,11 @@ class PrintViewManagerQt
{
public:
~PrintViewManagerQt() override;
-
+ typedef base::Callback<void(const std::vector<char> &result)> PrintToPDFCallback;
#if defined(ENABLE_BASIC_PRINTING)
// Method to print a page to a Pdf document with page size \a pageSize in location \a filePath.
bool PrintToPDF(const QPageLayout& pageLayout, const QString& filePath);
- bool PrintToPDFWithCallback(const QPageLayout& pageLayout, const QString& filePath, base::Callback<void(bool)> callback);
+ bool PrintToPDFWithCallback(const QPageLayout& pageLayout, const PrintToPDFCallback& callback);
#endif // ENABLE_BASIC_PRINTING
// PrintedPagesSource implementation.
@@ -108,8 +108,12 @@ protected:
void OnRequestPrintPreview(const PrintHostMsg_RequestPrintPreview_Params&);
void OnMetafileReadyForPrinting(const PrintHostMsg_DidPreviewDocument_Params& params);
+#if defined(ENABLE_BASIC_PRINTING)
+ bool PrintToPDFInternal(const QPageLayout &);
+#endif //
+
base::FilePath m_pdfOutputPath;
- base::Callback<void(bool)> m_pdfPrintCallback;
+ PrintToPDFCallback m_pdfPrintCallback;
private:
friend class content::WebContentsUserData<PrintViewManagerQt>;
diff --git a/src/core/printing_message_filter_qt.cpp b/src/core/printing_message_filter_qt.cpp
index b9955fbb4..fd6dc0fc2 100644
--- a/src/core/printing_message_filter_qt.cpp
+++ b/src/core/printing_message_filter_qt.cpp
@@ -217,7 +217,7 @@ void PrintingMessageFilterQt::OnUpdatePrintSettings(
printer_query = queue_->CreatePrinterQuery(host_id, routing_id);
}
printer_query->SetSettings(
- new_settings.Pass(),
+ std::move(new_settings),
base::Bind(&PrintingMessageFilterQt::OnUpdatePrintSettingsReply, this,
printer_query, reply_msg));
}
@@ -251,7 +251,7 @@ void PrintingMessageFilterQt::OnUpdatePrintSettingsReply(
}
}
-void PrintingMessageFilterQt::OnCheckForCancel(int32 preview_ui_id,
+void PrintingMessageFilterQt::OnCheckForCancel(int32_t preview_ui_id,
int preview_request_id,
bool* cancel) {
*cancel = false;
diff --git a/src/core/printing_message_filter_qt.h b/src/core/printing_message_filter_qt.h
index 004e5b86a..95d63f570 100644
--- a/src/core/printing_message_filter_qt.h
+++ b/src/core/printing_message_filter_qt.h
@@ -122,7 +122,7 @@ class PrintingMessageFilterQt : public content::BrowserMessageFilter {
IPC::Message* reply_msg);
// Check to see if print preview has been cancelled.
- void OnCheckForCancel(int32 preview_ui_id,
+ void OnCheckForCancel(int32_t preview_ui_id,
int preview_request_id,
bool* cancel);
diff --git a/src/core/process_main.cpp b/src/core/process_main.cpp
index 8ffec04e4..3a3e28707 100644
--- a/src/core/process_main.cpp
+++ b/src/core/process_main.cpp
@@ -43,7 +43,7 @@
#include "content/public/app/content_main.h"
#if defined(OS_WIN)
#include "sandbox/win/src/sandbox_types.h"
-#include "content/public/app/startup_helper_win.h"
+#include "content/public/app/sandbox_helper_win.h"
#endif // OS_WIN
namespace QtWebEngine {
diff --git a/src/core/proxy_config_service_qt.h b/src/core/proxy_config_service_qt.h
index 8f780cfb9..da24e3337 100644
--- a/src/core/proxy_config_service_qt.h
+++ b/src/core/proxy_config_service_qt.h
@@ -40,7 +40,6 @@
#ifndef PROXY_CONFIG_SERVICE_QT_H
#define PROXY_CONFIG_SERVICE_QT_H
-#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
diff --git a/src/core/qtwebengine.gypi b/src/core/qtwebengine.gypi
index 42bf43822..7ed12cadb 100644
--- a/src/core/qtwebengine.gypi
+++ b/src/core/qtwebengine.gypi
@@ -8,6 +8,7 @@
'dependencies': [
'<(chromium_src_dir)/base/base.gyp:base',
'<(chromium_src_dir)/base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
+ '<(chromium_src_dir)/chrome/tools/convert_dict/convert_dict.gyp:convert_dict',
'<(chromium_src_dir)/components/components.gyp:devtools_discovery',
'<(chromium_src_dir)/components/components.gyp:devtools_http_handler',
'<(chromium_src_dir)/components/components.gyp:error_page_renderer',
@@ -68,10 +69,6 @@
['qt_os=="embedded_linux"', {
'configurations': {
'Debug_Base': {
- # Reduce the binary size.
- 'variables': {
- 'debug_optimize%': 's',
- },
'ldflags': [
# Only link with needed input sections.
'-Wl,--gc-sections',
@@ -137,5 +134,16 @@
'renderer/print_web_view_helper_delegate_qt.h',
]
}],
+ ['icu_use_data_file_flag==1', {
+ 'defines': ['ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_FILE'],
+ }, { # else icu_use_data_file_flag !=1
+ 'conditions': [
+ ['OS=="win"', {
+ 'defines': ['ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_SHARED'],
+ }, {
+ 'defines': ['ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC'],
+ }],
+ ],
+ }],
],
}
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 308a99fd3..eaf8485d3 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -92,7 +92,7 @@ static inline ui::LatencyInfo CreateLatencyInfo(const blink::WebInputEvent& even
ui::LatencyInfo latency_info;
// The latency number should only be added if the timestamp is valid.
if (event.timeStampSeconds) {
- const int64 time_micros = static_cast<int64>(
+ const int64_t time_micros = static_cast<int64_t>(
event.timeStampSeconds * base::Time::kMicrosecondsPerSecond);
latency_info.AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
@@ -163,7 +163,7 @@ static inline bool compareTouchPoints(const QTouchEvent::TouchPoint &lhs, const
return lhs.state() < rhs.state();
}
-static uint32 s_eventId = 0;
+static uint32_t s_eventId = 0;
class MotionEventQt : public ui::MotionEvent {
public:
MotionEventQt(const QList<QTouchEvent::TouchPoint> &touchPoints, const base::TimeTicks &eventTime, Action action, const Qt::KeyboardModifiers modifiers, float dpiScale, int index = -1)
@@ -179,7 +179,7 @@ public:
Q_ASSERT((action != ACTION_DOWN && action != ACTION_UP) || index == 0);
}
- virtual uint32 GetUniqueEventId() const Q_DECL_OVERRIDE { return eventId; }
+ virtual uint32_t GetUniqueEventId() const Q_DECL_OVERRIDE { return eventId; }
virtual Action GetAction() const Q_DECL_OVERRIDE { return action; }
virtual int GetActionIndex() const Q_DECL_OVERRIDE { return index; }
virtual size_t GetPointerCount() const Q_DECL_OVERRIDE { return touchPoints.size(); }
@@ -204,6 +204,7 @@ public:
}
virtual int GetFlags() const Q_DECL_OVERRIDE { return flags; }
virtual float GetPressure(size_t pointer_index) const Q_DECL_OVERRIDE { return touchPoints.at(pointer_index).pressure(); }
+ virtual float GetTilt(size_t pointer_index) const Q_DECL_OVERRIDE { return 0; }
virtual base::TimeTicks GetEventTime() const Q_DECL_OVERRIDE { return eventTime; }
virtual size_t GetHistorySize() const Q_DECL_OVERRIDE { return 0; }
@@ -218,7 +219,7 @@ private:
QList<QTouchEvent::TouchPoint> touchPoints;
base::TimeTicks eventTime;
Action action;
- const uint32 eventId;
+ const uint32_t eventId;
int flags;
int index;
float dpiScale;
@@ -232,6 +233,7 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget
, m_needsDelegatedFrameAck(false)
, m_didFirstVisuallyNonEmptyLayout(false)
, m_adapterClient(0)
+ , m_imeInProgress(false)
, m_anchorPositionWithinSelection(0)
, m_cursorPositionWithinSelection(0)
, m_initPending(false)
@@ -594,10 +596,10 @@ void RenderWidgetHostViewQt::CopyFromCompositingSurface(const gfx::Rect& src_sub
callback.Run(SkBitmap(), content::READBACK_FAILED);
}
-void RenderWidgetHostViewQt::CopyFromCompositingSurfaceToVideoFrame(const gfx::Rect& src_subrect, const scoped_refptr<media::VideoFrame>& target, const base::Callback<void(bool)>& callback)
+void RenderWidgetHostViewQt::CopyFromCompositingSurfaceToVideoFrame(const gfx::Rect& src_subrect, const scoped_refptr<media::VideoFrame>& target, const base::Callback<void(const gfx::Rect&, bool)>& callback)
{
NOTIMPLEMENTED();
- callback.Run(false);
+ callback.Run(gfx::Rect(), false);
}
bool RenderWidgetHostViewQt::CanCopyToVideoFrame() const
@@ -610,7 +612,15 @@ bool RenderWidgetHostViewQt::HasAcceleratedSurface(const gfx::Size&)
return false;
}
-void RenderWidgetHostViewQt::OnSwapCompositorFrame(uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame)
+void RenderWidgetHostViewQt::LockCompositingSurface()
+{
+}
+
+void RenderWidgetHostViewQt::UnlockCompositingSurface()
+{
+}
+
+void RenderWidgetHostViewQt::OnSwapCompositorFrame(uint32_t output_surface_id, scoped_ptr<cc::CompositorFrame> frame)
{
bool scrollOffsetChanged = (m_lastScrollOffset != frame->metadata.root_scroll_offset);
bool contentsSizeChanged = (m_lastContentsSize != frame->metadata.root_layer_size);
@@ -621,7 +631,7 @@ void RenderWidgetHostViewQt::OnSwapCompositorFrame(uint32 output_surface_id, sco
m_pendingOutputSurfaceId = output_surface_id;
Q_ASSERT(frame->delegated_frame_data);
Q_ASSERT(!m_chromiumCompositorData->frameData || m_chromiumCompositorData->frameData->resource_list.empty());
- m_chromiumCompositorData->frameData = frame->delegated_frame_data.Pass();
+ m_chromiumCompositorData->frameData = std::move(frame->delegated_frame_data);
m_chromiumCompositorData->frameDevicePixelRatio = frame->metadata.device_scale_factor;
// Support experimental.viewport.devicePixelRatio, see GetScreenInfo implementation below.
@@ -890,6 +900,23 @@ void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev)
if (IsMouseLocked() && ev->key() == Qt::Key_Escape && ev->type() == QEvent::KeyRelease)
UnlockMouse();
+ if (m_imeInProgress) {
+ // IME composition was not finished with a valid commit string.
+ // We're getting the composition result in a key event.
+ if (ev->key() != 0) {
+ // The key event is not a result of an IME composition. Cancel IME.
+ m_host->ImeCancelComposition();
+ m_imeInProgress = false;
+ } else {
+ if (ev->type() == QEvent::KeyRelease) {
+ m_host->ImeConfirmComposition(toString16(ev->text()), gfx::Range::InvalidRange(),
+ false);
+ m_imeInProgress = false;
+ }
+ return;
+ }
+ }
+
content::NativeWebKeyboardEvent webEvent = WebEventFactory::toWebKeyboardEvent(ev);
if (webEvent.type == blink::WebInputEvent::RawKeyDown && !ev->text().isEmpty()) {
// Blink won't consume the RawKeyDown, but rather the Char event in this case.
@@ -946,11 +973,12 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev)
}
}
- if (preeditString.isEmpty()) {
+ if (!commitString.isEmpty()) {
gfx::Range replacementRange = (replacementLength > 0) ? gfx::Range(replacementStart, replacementStart + replacementLength)
: gfx::Range::InvalidRange();
m_host->ImeConfirmComposition(toString16(commitString), replacementRange, false);
- } else {
+ m_imeInProgress = false;
+ } else if (!preeditString.isEmpty()) {
if (!selectionRange.IsValid()) {
// We did not receive a valid selection range, hence the range is going to mark the cursor position.
int newCursorPosition = (cursorPositionInPreeditString < 0) ? preeditString.length() : cursorPositionInPreeditString;
@@ -958,6 +986,7 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev)
selectionRange.set_end(newCursorPosition);
}
m_host->ImeSetComposition(toString16(preeditString), underlines, selectionRange.start(), selectionRange.end());
+ m_imeInProgress = true;
}
}
@@ -1039,11 +1068,12 @@ void RenderWidgetHostViewQt::handleFocusEvent(QFocusEvent *ev)
if (ev->gotFocus()) {
m_host->GotFocus();
m_host->SetActive(true);
- Q_ASSERT(m_host->IsRenderView());
+ content::RenderViewHostImpl *viewHost = content::RenderViewHostImpl::From(m_host);
+ Q_ASSERT(viewHost);
if (ev->reason() == Qt::TabFocusReason)
- static_cast<content::RenderViewHostImpl*>(m_host)->SetInitialFocus(false);
+ viewHost->SetInitialFocus(false);
else if (ev->reason() == Qt::BacktabFocusReason)
- static_cast<content::RenderViewHostImpl*>(m_host)->SetInitialFocus(true);
+ viewHost->SetInitialFocus(true);
ev->accept();
} else if (ev->lostFocus()) {
m_host->SetActive(false);
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index 8a5a157ee..b59de6c2e 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -143,15 +143,18 @@ public:
virtual void SetTooltipText(const base::string16 &tooltip_text) Q_DECL_OVERRIDE;
virtual void SelectionBoundsChanged(const ViewHostMsg_SelectionBounds_Params&) Q_DECL_OVERRIDE;
virtual void CopyFromCompositingSurface(const gfx::Rect& src_subrect, const gfx::Size& dst_size, const content::ReadbackRequestCallback& callback, const SkColorType preferred_color_type) Q_DECL_OVERRIDE;
- virtual void CopyFromCompositingSurfaceToVideoFrame(const gfx::Rect& src_subrect, const scoped_refptr<media::VideoFrame>& target, const base::Callback<void(bool)>& callback) Q_DECL_OVERRIDE;
+ virtual void CopyFromCompositingSurfaceToVideoFrame(const gfx::Rect& src_subrect, const scoped_refptr<media::VideoFrame>& target, const base::Callback<void(const gfx::Rect&, bool)>& callback) Q_DECL_OVERRIDE;
+
virtual bool CanCopyToVideoFrame() const Q_DECL_OVERRIDE;
virtual bool HasAcceleratedSurface(const gfx::Size&) Q_DECL_OVERRIDE;
- virtual void OnSwapCompositorFrame(uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame) Q_DECL_OVERRIDE;
+ virtual void OnSwapCompositorFrame(uint32_t output_surface_id, scoped_ptr<cc::CompositorFrame> frame) Q_DECL_OVERRIDE;
virtual void GetScreenInfo(blink::WebScreenInfo* results) Q_DECL_OVERRIDE;
virtual gfx::Rect GetBoundsInRootWindow() Q_DECL_OVERRIDE;
virtual void ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, content::InputEventAckState ack_result) Q_DECL_OVERRIDE;
virtual void ClearCompositorFrame() Q_DECL_OVERRIDE;
virtual bool GetScreenColorProfile(std::vector<char>*) Q_DECL_OVERRIDE;
+ virtual void LockCompositingSurface() Q_DECL_OVERRIDE;
+ virtual void UnlockCompositingSurface() Q_DECL_OVERRIDE;
// Overridden from RenderWidgetHostViewBase.
virtual void SelectionChanged(const base::string16 &text, size_t offset, const gfx::Range &range) Q_DECL_OVERRIDE;
@@ -227,12 +230,13 @@ private:
cc::ReturnedResourceArray m_resourcesToRelease;
bool m_needsDelegatedFrameAck;
bool m_didFirstVisuallyNonEmptyLayout;
- uint32 m_pendingOutputSurfaceId;
+ uint32_t m_pendingOutputSurfaceId;
WebContentsAdapterClient *m_adapterClient;
MultipleMouseClickHelper m_clickHelper;
ui::TextInputType m_currentInputType;
+ bool m_imeInProgress;
QRect m_cursorRect;
size_t m_anchorPositionWithinSelection;
size_t m_cursorPositionWithinSelection;
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
index 3d235ff0b..4503520eb 100644
--- a/src/core/renderer/content_renderer_client_qt.cpp
+++ b/src/core/renderer/content_renderer_client_qt.cpp
@@ -85,6 +85,17 @@ namespace QtWebEngineCore {
static const char kHttpErrorDomain[] = "http";
static const char kQrcSchemeQt[] = "qrc";
+class RenderProcessObserverQt : public content::RenderProcessObserver {
+public:
+ void WebKitInitialized() override
+ {
+ // mark qrc as a secure scheme (avoids deprecation warnings)
+ // Can only be done after blink is initialized.
+ blink::WebString qrcScheme(base::ASCIIToUTF16(kQrcSchemeQt));
+ blink::WebSecurityPolicy::registerURLSchemeAsSecure(qrcScheme);
+ }
+};
+
ContentRendererClientQt::ContentRendererClientQt()
{
}
@@ -98,12 +109,12 @@ void ContentRendererClientQt::RenderThreadStarted()
content::RenderThread *renderThread = content::RenderThread::Get();
m_visitedLinkSlave.reset(new visitedlink::VisitedLinkSlave);
m_webCacheObserver.reset(new web_cache::WebCacheRenderProcessObserver());
+ m_renderProcessObserver.reset(new RenderProcessObserverQt());
renderThread->AddObserver(m_visitedLinkSlave.data());
renderThread->AddObserver(m_webCacheObserver.data());
renderThread->AddObserver(UserResourceController::instance());
+ renderThread->AddObserver(m_renderProcessObserver.data());
- // mark qrc as a secure scheme (avoids deprecation warnings)
- blink::WebSecurityPolicy::registerURLSchemeAsSecure(blink::WebString::fromLatin1(kQrcSchemeQt));
#if defined(ENABLE_SPELLCHECK)
m_spellCheck.reset(new SpellCheck());
renderThread->AddObserver(m_spellCheck.data());
@@ -150,9 +161,8 @@ bool ContentRendererClientQt::ShouldSuppressErrorPage(content::RenderFrame *fram
}
// To tap into the chromium localized strings. Ripped from the chrome layer (highly simplified).
-void ContentRendererClientQt::GetNavigationErrorStrings(content::RenderView* renderView, blink::WebFrame *frame, const blink::WebURLRequest &failedRequest, const blink::WebURLError &error, std::string *errorHtml, base::string16 *errorDescription)
+void ContentRendererClientQt::GetNavigationErrorStrings(content::RenderFrame* renderFrame, const blink::WebURLRequest &failedRequest, const blink::WebURLError &error, std::string *errorHtml, base::string16 *errorDescription)
{
- Q_UNUSED(frame)
const bool isPost = QByteArray::fromStdString(failedRequest.httpMethod().utf8()) == QByteArrayLiteral("POST");
if (errorHtml) {
@@ -164,8 +174,8 @@ void ContentRendererClientQt::GetNavigationErrorStrings(content::RenderView* ren
// TODO(elproxy): We could potentially get better diagnostics here by first calling
// NetErrorHelper::GetErrorStringsForDnsProbe, but that one is harder to untangle.
LocalizedError::GetStrings(error.reason, error.domain.utf8(), error.unreachableURL, isPost
- , error.staleCopyInCache && !isPost, false, locale, renderView->GetAcceptLanguages()
- , scoped_ptr<error_page::ErrorPageParams>(), &errorStrings);
+ , error.staleCopyInCache && !isPost, false, error_page::OfflinePageStatus::NONE, locale, renderFrame->GetRenderView()->GetAcceptLanguages()
+ , scoped_ptr<error_page::ErrorPageParams>(), &errorStrings);
resourceId = IDR_NET_ERROR_HTML;
@@ -177,7 +187,7 @@ void ContentRendererClientQt::GetNavigationErrorStrings(content::RenderView* ren
}
if (errorDescription)
- *errorDescription = LocalizedError::GetErrorDetails(error, isPost);
+ *errorDescription = LocalizedError::GetErrorDetails(error.domain.utf8(), error.reason, isPost);
}
unsigned long long ContentRendererClientQt::VisitedLinkHash(const char *canonicalUrl, size_t length)
diff --git a/src/core/renderer/content_renderer_client_qt.h b/src/core/renderer/content_renderer_client_qt.h
index c80395140..ba223d878 100644
--- a/src/core/renderer/content_renderer_client_qt.h
+++ b/src/core/renderer/content_renderer_client_qt.h
@@ -44,6 +44,10 @@
#include <QtGlobal>
#include <QScopedPointer>
+namespace content {
+class RenderProcessObserver;
+}
+
namespace visitedlink {
class VisitedLinkSlave;
}
@@ -65,7 +69,7 @@ public:
virtual void RenderFrameCreated(content::RenderFrame* render_frame) Q_DECL_OVERRIDE;
virtual bool ShouldSuppressErrorPage(content::RenderFrame *, const GURL &) Q_DECL_OVERRIDE;
virtual bool HasErrorPage(int httpStatusCode, std::string *errorDomain) Q_DECL_OVERRIDE;
- virtual void GetNavigationErrorStrings(content::RenderView* renderView, blink::WebFrame* frame, const blink::WebURLRequest& failedRequest
+ virtual void GetNavigationErrorStrings(content::RenderFrame* renderFrame, const blink::WebURLRequest& failedRequest
, const blink::WebURLError& error, std::string* errorHtml, base::string16* errorDescription) Q_DECL_OVERRIDE;
virtual unsigned long long VisitedLinkHash(const char *canonicalUrl, size_t length) Q_DECL_OVERRIDE;
@@ -75,6 +79,7 @@ public:
private:
QScopedPointer<visitedlink::VisitedLinkSlave> m_visitedLinkSlave;
QScopedPointer<web_cache::WebCacheRenderProcessObserver> m_webCacheObserver;
+ QScopedPointer<content::RenderProcessObserver> m_renderProcessObserver;
#if defined(ENABLE_SPELLCHECK)
QScopedPointer<SpellCheck> m_spellCheck;
#endif
diff --git a/src/core/renderer/pepper/pepper_flash_browser_host_qt.h b/src/core/renderer/pepper/pepper_flash_browser_host_qt.h
index d6c8e69b6..5d1107dfb 100644
--- a/src/core/renderer/pepper/pepper_flash_browser_host_qt.h
+++ b/src/core/renderer/pepper/pepper_flash_browser_host_qt.h
@@ -40,7 +40,6 @@
#ifndef PEPPER_FLASH_BROWSER_HOST_QT_H
#define PEPPER_FLASH_BROWSER_HOST_QT_H
-#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "ppapi/host/host_message_context.h"
diff --git a/src/core/renderer/pepper/pepper_flash_renderer_host_qt.h b/src/core/renderer/pepper/pepper_flash_renderer_host_qt.h
index a9de3c6b8..ae6bc0876 100644
--- a/src/core/renderer/pepper/pepper_flash_renderer_host_qt.h
+++ b/src/core/renderer/pepper/pepper_flash_renderer_host_qt.h
@@ -43,7 +43,6 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/memory/weak_ptr.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/resource_host.h"
diff --git a/src/core/renderer/pepper/pepper_renderer_host_factory_qt.h b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.h
index 956fc81dd..bc472a7c6 100644
--- a/src/core/renderer/pepper/pepper_renderer_host_factory_qt.h
+++ b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.h
@@ -40,8 +40,6 @@
#ifndef PEPPER_RENDERER_HOST_FACTORY_QT_H
#define PEPPER_RENDERER_HOST_FACTORY_QT_H
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
#include "ppapi/host/host_factory.h"
#include "content/public/renderer/render_frame_observer.h"
diff --git a/src/core/renderer/render_frame_observer_qt.h b/src/core/renderer/render_frame_observer_qt.h
index a9246f817..b1d59d8c5 100644
--- a/src/core/renderer/render_frame_observer_qt.h
+++ b/src/core/renderer/render_frame_observer_qt.h
@@ -40,7 +40,6 @@
#ifndef RENDER_FRAME_OBSERVER_QT_H
#define RENDER_FRAME_OBSERVER_QT_H
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "content/public/renderer/render_frame_observer.h"
diff --git a/src/core/renderer/user_resource_controller.cpp b/src/core/renderer/user_resource_controller.cpp
index 0927aa53a..30a04958f 100644
--- a/src/core/renderer/user_resource_controller.cpp
+++ b/src/core/renderer/user_resource_controller.cpp
@@ -85,10 +85,10 @@ void UserResourceController::RenderViewObserverHelper::runScripts(UserScriptData
content::RenderView *renderView = content::RenderView::FromWebView(frame->view());
const bool isMainFrame = (frame == renderView->GetWebView()->mainFrame());
- QList<uint64> scriptsToRun = UserResourceController::instance()->m_viewUserScriptMap.value(globalScriptsIndex).toList();
+ QList<uint64_t> scriptsToRun = UserResourceController::instance()->m_viewUserScriptMap.value(globalScriptsIndex).toList();
scriptsToRun.append(UserResourceController::instance()->m_viewUserScriptMap.value(renderView).toList());
- Q_FOREACH (uint64 id, scriptsToRun) {
+ Q_FOREACH (uint64_t id, scriptsToRun) {
const UserScriptData &script = UserResourceController::instance()->m_scripts.value(id);
if (script.injectionPoint != p
|| (!script.injectForSubframes && !isMainFrame))
@@ -208,7 +208,7 @@ void UserResourceController::renderViewDestroyed(content::RenderView *renderView
ViewUserScriptMap::iterator it = m_viewUserScriptMap.find(renderView);
if (it == m_viewUserScriptMap.end()) // ASSERT maybe?
return;
- Q_FOREACH (uint64 id, it.value()) {
+ Q_FOREACH (uint64_t id, it.value()) {
m_scripts.remove(id);
}
m_viewUserScriptMap.remove(renderView);
@@ -239,7 +239,7 @@ void UserResourceController::clearScriptsForView(content::RenderView *view)
ViewUserScriptMap::iterator it = m_viewUserScriptMap.find(view);
if (it == m_viewUserScriptMap.end())
return;
- Q_FOREACH (uint64 id, it.value())
+ Q_FOREACH (uint64_t id, it.value())
m_scripts.remove(id);
m_viewUserScriptMap.remove(view);
diff --git a/src/core/renderer/user_resource_controller.h b/src/core/renderer/user_resource_controller.h
index b2f7d92c3..bd3d0ba49 100644
--- a/src/core/renderer/user_resource_controller.h
+++ b/src/core/renderer/user_resource_controller.h
@@ -76,10 +76,10 @@ private:
void onRemoveScript(const UserScriptData &);
void onClearScripts();
- typedef QSet<uint64> UserScriptSet;
+ typedef QSet<uint64_t> UserScriptSet;
typedef QHash<const content::RenderView *, UserScriptSet> ViewUserScriptMap;
ViewUserScriptMap m_viewUserScriptMap;
- QHash<uint64, UserScriptData> m_scripts;
+ QHash<uint64_t, UserScriptData> m_scripts;
};
#endif // USER_RESOURCE_CONTROLLER_H
diff --git a/src/core/resource_dispatcher_host_delegate_qt.cpp b/src/core/resource_dispatcher_host_delegate_qt.cpp
index 907165cdd..73a640207 100644
--- a/src/core/resource_dispatcher_host_delegate_qt.cpp
+++ b/src/core/resource_dispatcher_host_delegate_qt.cpp
@@ -136,21 +136,21 @@ void ResourceDispatcherHostLoginDelegateQt::destroy()
m_request = 0;
}
-static void LaunchURL(const GURL& url, int render_process_id, int render_view_id,
+static void LaunchURL(const GURL& url, int render_process_id,
+ const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
ui::PageTransition page_transition, bool is_main_frame)
{
+ Q_UNUSED(render_process_id);
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- content::RenderViewHost *render_view_host = content::RenderViewHost::FromID(render_process_id, render_view_id);
- if (!render_view_host)
- return;
- content::WebContents* webContents = content::WebContents::FromRenderViewHost(render_view_host);
+ content::WebContents* webContents = web_contents_getter.Run();
if (!webContents)
return;
WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
contentsDelegate->launchExternalURL(toQt(url), page_transition, is_main_frame);
}
-bool ResourceDispatcherHostDelegateQt::HandleExternalProtocol(const GURL& url, int child_id, int route_id,
+bool ResourceDispatcherHostDelegateQt::HandleExternalProtocol(const GURL& url, int child_id,
+ const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
bool is_main_frame, ui::PageTransition page_transition, bool has_user_gesture)
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
@@ -161,7 +161,7 @@ bool ResourceDispatcherHostDelegateQt::HandleExternalProtocol(const GURL& url, i
content::BrowserThread::PostTask(
content::BrowserThread::UI,
FROM_HERE,
- base::Bind(&LaunchURL, url, child_id, route_id, page_transition, is_main_frame));
+ base::Bind(&LaunchURL, url, child_id, web_contents_getter, page_transition, is_main_frame));
return true;
}
diff --git a/src/core/resource_dispatcher_host_delegate_qt.h b/src/core/resource_dispatcher_host_delegate_qt.h
index ea41a2f85..6481c6438 100644
--- a/src/core/resource_dispatcher_host_delegate_qt.h
+++ b/src/core/resource_dispatcher_host_delegate_qt.h
@@ -89,8 +89,10 @@ private:
class ResourceDispatcherHostDelegateQt : public content::ResourceDispatcherHostDelegate {
public:
- virtual bool HandleExternalProtocol(const GURL& url, int child_id, int route_id,
- bool is_main_frame, ui::PageTransition page_transition, bool has_user_gesture) Q_DECL_OVERRIDE;
+ virtual bool HandleExternalProtocol(const GURL& url,int child_id,
+ const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
+ bool is_main_frame, ui::PageTransition page_transition, bool has_user_gesture)
+ Q_DECL_OVERRIDE;
virtual content::ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(net::AuthChallengeInfo *authInfo, net::URLRequest *request) Q_DECL_OVERRIDE;
};
diff --git a/src/core/resources/resources.gyp b/src/core/resources/resources.gyp
index f2acab670..4226b7561 100644
--- a/src/core/resources/resources.gyp
+++ b/src/core/resources/resources.gyp
@@ -47,6 +47,7 @@
'<(SHARED_INTERMEDIATE_DIR)/ui/resources/ui_resources_100_percent.pak',
'<(SHARED_INTERMEDIATE_DIR)/content/app/resources/content_resources_100_percent.pak',
'<(SHARED_INTERMEDIATE_DIR)/chrome/renderer_resources_100_percent.pak',
+ '<(SHARED_INTERMEDIATE_DIR)/blink/public/resources/blink_image_resources_100_percent.pak',
],
'pak_outputs': [
'<(SHARED_INTERMEDIATE_DIR)/repack/qtwebengine_resources_100p.pak'
@@ -61,6 +62,7 @@
'<(SHARED_INTERMEDIATE_DIR)/ui/resources/ui_resources_200_percent.pak',
'<(SHARED_INTERMEDIATE_DIR)/content/app/resources/content_resources_200_percent.pak',
'<(SHARED_INTERMEDIATE_DIR)/chrome/renderer_resources_200_percent.pak',
+ '<(SHARED_INTERMEDIATE_DIR)/blink/public/resources/blink_image_resources_200_percent.pak',
],
'pak_outputs': [
'<(SHARED_INTERMEDIATE_DIR)/repack/qtwebengine_resources_200p.pak'
diff --git a/src/core/ssl_host_state_delegate_qt.cpp b/src/core/ssl_host_state_delegate_qt.cpp
new file mode 100644
index 000000000..cf17b944c
--- /dev/null
+++ b/src/core/ssl_host_state_delegate_qt.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later 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 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "ssl_host_state_delegate_qt.h"
+
+#include "type_conversion.h"
+
+namespace QtWebEngineCore {
+
+// Mirrors implementation in aw_ssl_host_state_delegate.cc
+
+static net::SHA256HashValue getChainFingerprint256(const net::X509Certificate &cert)
+{
+ net::SHA256HashValue fingerprint =
+ net::X509Certificate::CalculateChainFingerprint256(cert.os_cert_handle(), cert.GetIntermediateCertificates());
+ return fingerprint;
+}
+
+CertPolicy::CertPolicy()
+{
+}
+
+CertPolicy::~CertPolicy()
+{
+}
+
+bool CertPolicy::Check(const net::X509Certificate& cert, net::CertStatus error) const
+{
+ net::SHA256HashValue fingerprint = getChainFingerprint256(cert);
+ auto allowed_iter = m_allowed.find(fingerprint);
+ if ((allowed_iter != m_allowed.end()) && (allowed_iter->second & error) && ((allowed_iter->second & error) == error))
+ return true;
+ return false;
+}
+
+void CertPolicy::Allow(const net::X509Certificate& cert, net::CertStatus error)
+{
+ net::SHA256HashValue fingerprint = getChainFingerprint256(cert);
+ m_allowed[fingerprint] |= error;
+}
+
+SSLHostStateDelegateQt::SSLHostStateDelegateQt(BrowserContextAdapter *contextAdapter)
+ : m_contextAdapter(contextAdapter)
+{
+}
+
+SSLHostStateDelegateQt::~SSLHostStateDelegateQt()
+{
+}
+
+void SSLHostStateDelegateQt::AllowCert(const std::string &host, const net::X509Certificate &cert, net::CertStatus error)
+{
+ m_certPolicyforHost[host].Allow(cert, error);
+}
+
+// Clear all allow preferences.
+void SSLHostStateDelegateQt::Clear()
+{
+ m_certPolicyforHost.clear();
+}
+
+// Queries whether |cert| is allowed for |host| and |error|. Returns true in
+// |expired_previous_decision| if a previous user decision expired immediately
+// prior to this query, otherwise false.
+content::SSLHostStateDelegate::CertJudgment SSLHostStateDelegateQt::QueryPolicy(
+ const std::string &host, const net::X509Certificate &cert,
+ net::CertStatus error,bool *expired_previous_decision)
+{
+ return m_certPolicyforHost[host].Check(cert, error) ? SSLHostStateDelegate::ALLOWED : SSLHostStateDelegate::DENIED;
+}
+
+// Records that a host has run insecure content.
+void SSLHostStateDelegateQt::HostRanInsecureContent(const std::string &host, int pid)
+{
+}
+
+// Returns whether the specified host ran insecure content.
+bool SSLHostStateDelegateQt::DidHostRunInsecureContent(const std::string &host, int pid) const
+{
+ return false;
+}
+
+// Revokes all SSL certificate error allow exceptions made by the user for
+// |host|.
+void SSLHostStateDelegateQt::RevokeUserAllowExceptions(const std::string &host)
+{
+ m_certPolicyforHost.erase(host);
+}
+
+// Returns whether the user has allowed a certificate error exception for
+// |host|. This does not mean that *all* certificate errors are allowed, just
+// that there exists an exception. To see if a particular certificate and
+// error combination exception is allowed, use QueryPolicy().
+bool SSLHostStateDelegateQt::HasAllowException(const std::string &host) const
+{
+ auto policy_iterator = m_certPolicyforHost.find(host);
+ return policy_iterator != m_certPolicyforHost.end() &&
+ policy_iterator->second.HasAllowException();
+}
+
+
+} // namespace QtWebEngineCore
diff --git a/src/core/ssl_host_state_delegate_qt.h b/src/core/ssl_host_state_delegate_qt.h
new file mode 100644
index 000000000..7c91fcb2d
--- /dev/null
+++ b/src/core/ssl_host_state_delegate_qt.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later 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 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SSL_HOST_STATE_DELEGATE_QT_H
+#define SSL_HOST_STATE_DELEGATE_QT_H
+
+#include "content/public/browser/ssl_host_state_delegate.h"
+#include "browser_context_adapter.h"
+
+namespace QtWebEngineCore {
+
+class CertPolicy {
+public:
+ CertPolicy();
+ ~CertPolicy();
+ bool Check(const net::X509Certificate& cert, net::CertStatus error) const;
+ void Allow(const net::X509Certificate& cert, net::CertStatus error);
+ bool HasAllowException() const { return m_allowed.size() > 0; }
+
+private:
+ std::map<net::SHA256HashValue, net::CertStatus, net::SHA256HashValueLessThan> m_allowed;
+};
+
+class SSLHostStateDelegateQt : public content::SSLHostStateDelegate {
+
+public:
+ SSLHostStateDelegateQt(BrowserContextAdapter *);
+ ~SSLHostStateDelegateQt();
+
+ // content::SSLHostStateDelegate implementation:
+ virtual void AllowCert(const std::string &, const net::X509Certificate &cert, net::CertStatus error) override;
+ virtual void Clear() override;
+ virtual CertJudgment QueryPolicy(const std::string &host, const net::X509Certificate &cert,
+ net::CertStatus error,bool *expired_previous_decision) override;
+ virtual void HostRanInsecureContent(const std::string &host, int pid) override;
+ virtual bool DidHostRunInsecureContent(const std::string &host, int pid) const override;
+ virtual void RevokeUserAllowExceptions(const std::string &host) override;
+ virtual bool HasAllowException(const std::string &host) const override;
+
+private:
+ BrowserContextAdapter *m_contextAdapter;
+ std::map<std::string, CertPolicy> m_certPolicyforHost;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // SSL_HOST_STATE_DELEGATE_QT_H
diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp
index bcbc5f4ef..ca79b55d4 100644
--- a/src/core/url_request_context_getter_qt.cpp
+++ b/src/core/url_request_context_getter_qt.cpp
@@ -93,7 +93,7 @@ URLRequestContextGetterQt::URLRequestContextGetterQt(BrowserContextAdapter *brow
: m_ignoreCertificateErrors(false)
, m_browserContext(browserContext)
, m_cookieDelegate(new CookieMonsterDelegateQt())
- , m_requestInterceptors(request_interceptors.Pass())
+ , m_requestInterceptors(std::move(request_interceptors))
{
std::swap(m_protocolHandlers, *protocolHandlers);
@@ -196,7 +196,7 @@ void URLRequestContextGetterQt::generateStorage()
m_storage->set_http_server_properties(scoped_ptr<net::HttpServerProperties>(new net::HttpServerPropertiesImpl));
// Give |m_storage| ownership at the end in case it's |mapped_host_resolver|.
- m_storage->set_host_resolver(host_resolver.Pass());
+ m_storage->set_host_resolver(std::move(host_resolver));
generateHttpCache();
}
@@ -385,17 +385,14 @@ void URLRequestContextGetterQt::generateHttpCache()
}
net::HttpCache *cache = 0;
- net::HttpNetworkSession *network_session = 0;
net::HttpNetworkSession::Params network_session_params = generateNetworkSessionParams();
- if (m_urlRequestContext->http_transaction_factory())
- network_session = m_urlRequestContext->http_transaction_factory()->GetSession();
-
- if (!network_session || !doNetworkSessionParamsMatch(network_session_params, network_session->params())) {
+ if (!m_httpNetworkSession || !doNetworkSessionParamsMatch(network_session_params, m_httpNetworkSession->params())) {
cancelAllUrlRequests();
- cache = new net::HttpCache(network_session_params, main_backend);
- } else
- cache = new net::HttpCache(network_session, main_backend);
+ m_httpNetworkSession.reset(new net::HttpNetworkSession(network_session_params));
+ }
+
+ cache = new net::HttpCache(m_httpNetworkSession.get(), scoped_ptr<net::HttpCache::DefaultBackend>(main_backend), false);
m_storage->set_http_transaction_factory(scoped_ptr<net::HttpCache>(cache));
m_updateHttpCache = 0;
@@ -446,14 +443,14 @@ void URLRequestContextGetterQt::generateJobFactory()
jobFactory->SetProtocolHandler(it.key().toStdString(), scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(new CustomProtocolHandler(it.value())));
// Set up interceptors in the reverse order.
- scoped_ptr<net::URLRequestJobFactory> topJobFactory = jobFactory.Pass();
+ scoped_ptr<net::URLRequestJobFactory> topJobFactory = std::move(jobFactory);
for (content::URLRequestInterceptorScopedVector::reverse_iterator i = m_requestInterceptors.rbegin(); i != m_requestInterceptors.rend(); ++i)
- topJobFactory.reset(new net::URLRequestInterceptingJobFactory(topJobFactory.Pass(), make_scoped_ptr(*i)));
+ topJobFactory.reset(new net::URLRequestInterceptingJobFactory(std::move(topJobFactory), make_scoped_ptr(*i)));
m_requestInterceptors.weak_clear();
- m_jobFactory = topJobFactory.Pass();
+ m_jobFactory = std::move(topJobFactory);
m_urlRequestContext->set_job_factory(m_jobFactory.get());
}
diff --git a/src/core/url_request_context_getter_qt.h b/src/core/url_request_context_getter_qt.h
index 8d911e4d4..13d6e2f72 100644
--- a/src/core/url_request_context_getter_qt.h
+++ b/src/core/url_request_context_getter_qt.h
@@ -110,6 +110,7 @@ private:
scoped_ptr<net::DhcpProxyScriptFetcherFactory> m_dhcpProxyScriptFetcherFactory;
scoped_refptr<CookieMonsterDelegateQt> m_cookieDelegate;
content::URLRequestInterceptorScopedVector m_requestInterceptors;
+ scoped_ptr<net::HttpNetworkSession> m_httpNetworkSession;
friend class NetworkDelegateQt;
};
diff --git a/src/core/url_request_custom_job.cpp b/src/core/url_request_custom_job.cpp
index f8a47b2b1..79a54650c 100644
--- a/src/core/url_request_custom_job.cpp
+++ b/src/core/url_request_custom_job.cpp
@@ -130,22 +130,21 @@ bool URLRequestCustomJob::IsRedirectResponse(GURL* location, int* http_status_co
return false;
}
-bool URLRequestCustomJob::ReadRawData(IOBuffer *buf, int bufSize, int *bytesRead)
+int URLRequestCustomJob::ReadRawData(IOBuffer *buf, int bufSize)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- Q_ASSERT(bytesRead);
Q_ASSERT(m_shared);
QMutexLocker lock(&m_shared->m_mutex);
+ if (m_shared->m_error)
+ return m_shared->m_error;
qint64 rv = m_shared->m_device ? m_shared->m_device->read(buf->data(), bufSize) : -1;
- if (rv >= 0) {
- *bytesRead = static_cast<int>(rv);
- return true;
- } else {
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, ERR_FAILED));
- }
- return false;
+ if (rv >= 0)
+ return static_cast<int>(rv);
+ else
+ return ERR_FAILED;
}
+
URLRequestCustomJobShared::URLRequestCustomJobShared(URLRequestCustomJob *job)
: m_mutex(QMutex::Recursive)
, m_job(job)
@@ -261,7 +260,7 @@ void URLRequestCustomJobShared::notifyCanceled()
if (!m_job)
return;
if (m_started)
- m_job->NotifyDone(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED));
+ m_job->NotifyCanceled();
else
m_job->NotifyStartError(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED));
}
@@ -296,10 +295,8 @@ void URLRequestCustomJobShared::notifyFailure()
if (m_device)
m_device->close();
const URLRequestStatus status(URLRequestStatus::FAILED, m_error);
- const bool started = m_started;
-
- if (started)
- m_job->NotifyDone(status);
+ if (m_started)
+ m_job->SetStatus(status);
else
m_job->NotifyStartError(status);
}
diff --git a/src/core/url_request_custom_job.h b/src/core/url_request_custom_job.h
index 98e2478c4..e9f48216b 100644
--- a/src/core/url_request_custom_job.h
+++ b/src/core/url_request_custom_job.h
@@ -61,7 +61,7 @@ public:
URLRequestCustomJob(net::URLRequest *request, net::NetworkDelegate *networkDelegate, QWebEngineUrlSchemeHandler *schemeHandler);
virtual void Start() Q_DECL_OVERRIDE;
virtual void Kill() Q_DECL_OVERRIDE;
- virtual bool ReadRawData(net::IOBuffer *buf, int bufSize, int *bytesRead) Q_DECL_OVERRIDE;
+ virtual int ReadRawData(net::IOBuffer* buf, int buf_size) Q_DECL_OVERRIDE;;
virtual bool GetMimeType(std::string *mimeType) const Q_DECL_OVERRIDE;
virtual bool GetCharset(std::string *charset) Q_DECL_OVERRIDE;
virtual bool IsRedirectResponse(GURL* location, int* http_status_code) Q_DECL_OVERRIDE;
diff --git a/src/core/url_request_qrc_job_qt.cpp b/src/core/url_request_qrc_job_qt.cpp
index d55b940c3..ffe9b6dc6 100644
--- a/src/core/url_request_qrc_job_qt.cpp
+++ b/src/core/url_request_qrc_job_qt.cpp
@@ -89,27 +89,22 @@ bool URLRequestQrcJobQt::GetMimeType(std::string *mimeType) const
return false;
}
-bool URLRequestQrcJobQt::ReadRawData(IOBuffer *buf, int bufSize, int *bytesRead)
+int URLRequestQrcJobQt::ReadRawData(IOBuffer *buf, int bufSize)
{
- DCHECK(bytesRead);
DCHECK_GE(m_remainingBytes, 0);
// File has been read finished.
if (!m_remainingBytes || !bufSize) {
- *bytesRead = 0;
- return true;
+ return 0;
}
if (m_remainingBytes < bufSize)
bufSize = static_cast<int>(m_remainingBytes);
qint64 rv = m_file.read(buf->data(), bufSize);
if (rv >= 0) {
- *bytesRead = static_cast<int>(rv);
m_remainingBytes -= rv;
DCHECK_GE(m_remainingBytes, 0);
- return true;
- } else {
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, ERR_FAILED));
+ return static_cast<int>(rv);
}
- return false;
+ return static_cast<int>(rv);
}
void URLRequestQrcJobQt::startGetHead()
diff --git a/src/core/url_request_qrc_job_qt.h b/src/core/url_request_qrc_job_qt.h
index bda276bad..5ad115da9 100644
--- a/src/core/url_request_qrc_job_qt.h
+++ b/src/core/url_request_qrc_job_qt.h
@@ -55,7 +55,7 @@ public:
URLRequestQrcJobQt(net::URLRequest *request, net::NetworkDelegate *networkDelegate);
virtual void Start() Q_DECL_OVERRIDE;
virtual void Kill() Q_DECL_OVERRIDE;
- virtual bool ReadRawData(net::IOBuffer *buf, int bufSize, int *bytesRead) Q_DECL_OVERRIDE;
+ virtual int ReadRawData(net::IOBuffer* buf, int buf_size) Q_DECL_OVERRIDE;;
virtual bool GetMimeType(std::string *mimeType) const Q_DECL_OVERRIDE;
protected:
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index eb4436018..71d2172fe 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -49,6 +49,7 @@
#include "browser_context_qt.h"
#include "download_manager_delegate_qt.h"
#include "media_capture_devices_dispatcher.h"
+#include "print_view_manager_qt.h"
#include "qwebenginecallback_p.h"
#include "render_view_observer_host_qt.h"
#include "type_conversion.h"
@@ -79,6 +80,7 @@
#include <QDir>
#include <QGuiApplication>
+#include <QPageLayout>
#include <QStringList>
#include <QStyleHints>
#include <QTimer>
@@ -178,6 +180,13 @@ static void callbackOnEvaluateJS(WebContentsAdapterClient *adapterClient, quint6
adapterClient->didRunJavaScript(requestId, fromJSValue(result));
}
+static void callbackOnPrintingFinished(WebContentsAdapterClient *adapterClient, int requestId, const std::vector<char>& result)
+{
+ if (requestId) {
+ adapterClient->didPrintPage(requestId, QByteArray(result.data(), result.size()));
+ }
+}
+
static content::WebContents *createBlankWebContents(WebContentsAdapterClient *adapterClient, content::BrowserContext *browserContext)
{
content::WebContents::CreateParams create_params(browserContext, NULL);
@@ -221,7 +230,7 @@ static void serializeNavigationHistory(const content::NavigationController &cont
}
}
-static void deserializeNavigationHistory(QDataStream &input, int *currentIndex, ScopedVector<content::NavigationEntry> *entries, content::BrowserContext *browserContext)
+static void deserializeNavigationHistory(QDataStream &input, int *currentIndex, std::vector<scoped_ptr<content::NavigationEntry>> *entries, content::BrowserContext *browserContext)
{
int version;
input >> version;
@@ -262,8 +271,10 @@ static void deserializeNavigationHistory(QDataStream &input, int *currentIndex,
// If we couldn't unpack the entry successfully, abort everything.
if (input.status() != QDataStream::Ok) {
*currentIndex = -1;
- for (content::NavigationEntry *entry : *entries)
- delete entry;
+ auto it = entries->begin();
+ auto end = entries->end();
+ for (; it != end; ++it)
+ it->reset();
entries->clear();
return;
}
@@ -287,7 +298,7 @@ static void deserializeNavigationHistory(QDataStream &input, int *currentIndex,
entry->SetIsOverridingUserAgent(isOverridingUserAgent);
entry->SetTimestamp(base::Time::FromInternalValue(timestamp));
entry->SetHttpStatusCode(httpStatusCode);
- entries->push_back(entry.release());
+ entries->push_back(std::move(entry));
}
}
@@ -339,7 +350,7 @@ WebContentsAdapterPrivate::~WebContentsAdapterPrivate()
QExplicitlySharedDataPointer<WebContentsAdapter> WebContentsAdapter::createFromSerializedNavigationHistory(QDataStream &input, WebContentsAdapterClient *adapterClient)
{
int currentIndex;
- ScopedVector<content::NavigationEntry> entries;
+ std::vector<scoped_ptr<content::NavigationEntry>> entries;
deserializeNavigationHistory(input, &currentIndex, &entries, adapterClient->browserContextAdapter()->browserContext());
if (currentIndex == -1)
@@ -411,6 +422,10 @@ void WebContentsAdapter::initialize(WebContentsAdapterClient *adapterClient)
// This should only be necessary after having restored the history to a new WebContentsAdapter.
d->webContents->GetController().LoadIfNecessary();
+#if defined(ENABLE_BASIC_PRINTING)
+ PrintViewManagerQt::CreateForWebContents(webContents());
+#endif // defined(ENABLE_BASIC_PRINTING)
+
// Create a RenderView with the initial empty document
content::RenderViewHost *rvh = d->webContents->GetRenderViewHost();
Q_ASSERT(rvh);
@@ -554,7 +569,7 @@ QString WebContentsAdapter::pageTitle() const
QString WebContentsAdapter::selectedText() const
{
Q_D(const WebContentsAdapter);
- return toQt(d->webContents->GetRenderViewHost()->GetView()->GetSelectedText());
+ return toQt(d->webContents->GetRenderWidgetHostView()->GetSelectedText());
}
void WebContentsAdapter::undo()
@@ -817,7 +832,7 @@ void WebContentsAdapter::download(const QUrl &url, const QString &suggestedFileN
scoped_ptr<content::DownloadUrlParameters> params(
content::DownloadUrlParameters::FromWebContents(webContents(), toGurl(url)));
params->set_suggested_name(toString16(suggestedFileName));
- dlm->DownloadUrl(params.Pass());
+ dlm->DownloadUrl(std::move(params));
}
bool WebContentsAdapter::isAudioMuted() const
@@ -897,6 +912,25 @@ void WebContentsAdapter::wasHidden()
d->webContents->WasHidden();
}
+void WebContentsAdapter::printToPDF(const QPageLayout &pageLayout, const QString &filePath)
+{
+#if defined(ENABLE_BASIC_PRINTING)
+ PrintViewManagerQt::FromWebContents(webContents())->PrintToPDF(pageLayout, filePath);
+#endif // if defined(ENABLE_BASIC_PRINTING)
+}
+
+quint64 WebContentsAdapter::printToPDFCallbackResult(const QPageLayout &pageLayout)
+{
+#if defined(ENABLE_BASIC_PRINTING)
+ Q_D(WebContentsAdapter);
+ PrintViewManagerQt::PrintToPDFCallback callback = base::Bind(&callbackOnPrintingFinished, d->adapterClient, d->nextRequestId);
+ PrintViewManagerQt::FromWebContents(webContents())->PrintToPDFWithCallback(pageLayout, callback);
+ return d->nextRequestId++;
+#else
+ return 0;
+#endif // if defined(ENABLE_BASIC_PRINTING)
+}
+
QPointF WebContentsAdapter::lastScrollOffset() const
{
Q_D(const WebContentsAdapter);
@@ -944,7 +978,7 @@ void WebContentsAdapter::dpiScaleChanged()
Q_D(WebContentsAdapter);
content::RenderWidgetHostImpl* impl = NULL;
if (d->webContents->GetRenderViewHost())
- impl = content::RenderWidgetHostImpl::From(d->webContents->GetRenderViewHost());
+ impl = content::RenderWidgetHostImpl::From(d->webContents->GetRenderViewHost()->GetWidget());
if (impl)
impl->NotifyScreenInfoChanged();
}
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index c7c2c1edf..600e759e2 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -57,6 +57,8 @@ QT_BEGIN_NAMESPACE
class QAccessibleInterface;
class QDragEnterEvent;
class QDragMoveEvent;
+class QPageLayout;
+class QString;
class QWebChannel;
QT_END_NAMESPACE
@@ -169,6 +171,8 @@ public:
void endDragging(const QPoint &clientPos, const QPoint &screenPos);
void leaveDrag();
void initUpdateDragCursorMessagePollingTimer();
+ void printToPDF(const QPageLayout&, const QString&);
+ quint64 printToPDFCallbackResult(const QPageLayout &);
// meant to be used within WebEngineCore only
content::WebContents *webContents() const;
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index a5c7a756b..9d2054859 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -237,6 +237,7 @@ public:
virtual void didFetchDocumentMarkup(quint64 requestId, const QString& result) = 0;
virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) = 0;
virtual void didFindText(quint64 requestId, int matchCount) = 0;
+ virtual void didPrintPage(quint64 requestId, const QByteArray &result) = 0;
virtual void passOnFocus(bool reverse) = 0;
// returns the last QObject (QWidget/QQuickItem) based object in the accessibility
// hierarchy before going into the BrowserAccessibility tree
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 1dbb38e97..51b9d5bd0 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -60,7 +60,6 @@
#include "components/web_cache/browser/web_cache_manager.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
-#include "content/public/browser/favicon_status.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_view_host.h"
@@ -79,7 +78,7 @@
namespace QtWebEngineCore {
// Maps the LogSeverity defines in base/logging.h to the web engines message levels.
-static WebContentsAdapterClient::JavaScriptConsoleMessageLevel mapToJavascriptConsoleMessageLevel(int32 messageLevel) {
+static WebContentsAdapterClient::JavaScriptConsoleMessageLevel mapToJavascriptConsoleMessageLevel(int32_t messageLevel) {
if (messageLevel < 1)
return WebContentsAdapterClient::Info;
else if (messageLevel > 1)
@@ -115,9 +114,6 @@ content::WebContents *WebContentsDelegateQt::OpenURLFromTab(content::WebContents
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
load_url_params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
- if (params.transferred_global_request_id != content::GlobalRequestID())
- load_url_params.transferred_global_request_id = params.transferred_global_request_id;
-
target->GetController().LoadURLWithParams(load_url_params);
return target;
}
@@ -211,7 +207,15 @@ void WebContentsDelegateQt::DidFailProvisionalLoad(content::RenderFrameHost* ren
void WebContentsDelegateQt::DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code, const base::string16& error_description, bool was_ignored_by_handler)
{
Q_UNUSED(was_ignored_by_handler);
- if (m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID()) || render_frame_host->GetParent())
+ if (validated_url.spec() == content::kUnreachableWebDataURL) {
+ m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID());
+ qCritical("Loading error-page failed. This shouldn't happen.");
+ if (!render_frame_host->GetParent())
+ m_viewClient->loadFinished(false /* success */, toQt(validated_url), true /* isErrorPage */);
+ return;
+ }
+
+ if (render_frame_host->GetParent())
return;
m_viewClient->iconChanged(QUrl());
@@ -221,8 +225,9 @@ void WebContentsDelegateQt::DidFailLoad(content::RenderFrameHost* render_frame_h
void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url)
{
- if (m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID())) {
- Q_ASSERT(validated_url.is_valid() && validated_url.spec() == content::kUnreachableWebDataURL);
+ Q_ASSERT(validated_url.is_valid());
+ if (validated_url.spec() == content::kUnreachableWebDataURL) {
+ m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID());
m_viewClient->iconChanged(QUrl());
// Trigger LoadFinished signal for main frame's error page only.
@@ -235,15 +240,11 @@ void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame
if (render_frame_host->GetParent())
return;
- m_viewClient->loadFinished(true, toQt(validated_url));
-
- content::NavigationEntry *entry = web_contents()->GetController().GetVisibleEntry();
- if (!entry)
- return;
-
- // No available icon for the current entry
- if (!entry->GetFavicon().valid && !m_faviconManager->hasAvailableCandidateIcon())
+ if (!m_faviconManager->hasCandidate())
m_viewClient->iconChanged(QUrl());
+
+ m_viewClient->loadProgressChanged(100);
+ m_viewClient->loadFinished(true, toQt(validated_url));
}
void WebContentsDelegateQt::DidUpdateFaviconURL(const std::vector<content::FaviconURL> &candidates)
@@ -256,14 +257,6 @@ void WebContentsDelegateQt::DidUpdateFaviconURL(const std::vector<content::Favic
}
m_faviconManager->update(faviconCandidates);
-
- content::NavigationEntry *entry = web_contents()->GetController().GetVisibleEntry();
- if (entry) {
- FaviconInfo proposedFaviconInfo = m_faviconManager->getProposedFaviconInfo();
- content::FaviconStatus &favicon = entry->GetFavicon();
- favicon.url = toGurl(proposedFaviconInfo.url);
- favicon.valid = proposedFaviconInfo.isValid();
- }
}
content::ColorChooser *WebContentsDelegateQt::OpenColorChooser(content::WebContents *source, SkColor color, const std::vector<content::ColorSuggestion> &suggestion)
@@ -314,7 +307,7 @@ void WebContentsDelegateQt::RunFileChooser(content::WebContents *web_contents, c
m_viewClient->runFileChooser(controller);
}
-bool WebContentsDelegateQt::AddMessageToConsole(content::WebContents *source, int32 level, const base::string16 &message, int32 line_no, const base::string16 &source_id)
+bool WebContentsDelegateQt::AddMessageToConsole(content::WebContents *source, int32_t level, const base::string16 &message, int32_t line_no, const base::string16 &source_id)
{
Q_UNUSED(source)
m_viewClient->javaScriptConsoleMessage(mapToJavascriptConsoleMessageLevel(level), toQt(message), static_cast<int>(line_no), toQt(source_id));
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index cc00f1f44..12e33eb1e 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -93,7 +93,7 @@ public:
virtual void ExitFullscreenModeForTab(content::WebContents*) Q_DECL_OVERRIDE;
virtual bool IsFullscreenForTabOrPending(const content::WebContents* web_contents) const Q_DECL_OVERRIDE;
virtual void RunFileChooser(content::WebContents *, const content::FileChooserParams &params) Q_DECL_OVERRIDE;
- virtual bool AddMessageToConsole(content::WebContents* source, int32 level, const base::string16& message, int32 line_no, const base::string16& source_id) Q_DECL_OVERRIDE;
+ virtual bool AddMessageToConsole(content::WebContents* source, int32_t level, const base::string16& message, int32_t line_no, const base::string16& source_id) Q_DECL_OVERRIDE;
virtual void FindReply(content::WebContents *source, int request_id, int number_of_matches, const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update) Q_DECL_OVERRIDE;
virtual void RequestMediaAccessPermission(content::WebContents* web_contents, const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback) Q_DECL_OVERRIDE;
virtual void MoveContents(content::WebContents *source, const gfx::Rect &pos) Q_DECL_OVERRIDE;
@@ -130,7 +130,7 @@ private:
WebContentsAdapterClient *m_viewClient;
QString m_lastSearchedString;
int m_lastReceivedFindReply;
- QVector<int64> m_loadingErrorFrameList;
+ QVector<int64_t> m_loadingErrorFrameList;
QScopedPointer<FaviconManager> m_faviconManager;
};
diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp
index 9614aa0f8..370f1e78f 100644
--- a/src/core/web_contents_view_qt.cpp
+++ b/src/core/web_contents_view_qt.cpp
@@ -96,7 +96,7 @@ void WebContentsViewQt::RenderViewCreated(content::RenderViewHost* host)
// The render process is done creating the RenderView and it's ready to be routed
// messages at this point.
if (m_client)
- host->GetView()->SetBackgroundColor(toSk(m_client->backgroundColor()));
+ m_webContents->GetRenderWidgetHostView()->SetBackgroundColor(toSk(m_client->backgroundColor()));
}
void WebContentsViewQt::CreateView(const gfx::Size& initial_size, gfx::NativeView context)
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index f4574f8b3..09e131272 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -58,6 +58,7 @@
#include "content/public/app/content_main.h"
#include "content/public/app/content_main_runner.h"
#include "content/public/browser/browser_main_runner.h"
+#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
@@ -70,7 +71,7 @@
#include "ui/gl/gl_switches.h"
#if defined(OS_WIN)
#include "sandbox/win/src/sandbox_types.h"
-#include "content/public/app/startup_helper_win.h"
+#include "content/public/app/sandbox_helper_win.h"
#endif // OS_WIN
#include "browser_context_adapter.h"
@@ -149,6 +150,12 @@ bool usingQtQuick2DRenderer()
return device == QLatin1String("softwarecontext");
}
+#if defined(ENABLE_PLUGINS)
+void dummyGetPluginCallback(const std::vector<content::WebPluginInfo>&)
+{
+}
+#endif
+
} // namespace
namespace QtWebEngineCore {
@@ -236,8 +243,7 @@ WebEngineContext::WebEngineContext()
parsedCommandLine->AppendSwitch(switches::kInProcessGPU);
// These are currently only default on OS X, and we don't support them:
parsedCommandLine->AppendSwitch(switches::kDisableZeroCopy);
- parsedCommandLine->AppendSwitch(switches::kDisableNativeGpuMemoryBuffers);
- parsedCommandLine->AppendSwitch(switches::kDisableGpuMemoryBufferVideoFrames);
+ parsedCommandLine->AppendSwitch(switches::kDisableGpuMemoryBufferCompositorResources);
if (useEmbeddedSwitches) {
// Inspired by the Android port's default switches
@@ -291,6 +297,16 @@ WebEngineContext::WebEngineContext()
// first gets referenced on the IO thread.
MediaCaptureDevicesDispatcher::GetInstance();
+#if defined(ENABLE_PLUGINS)
+ // Creating pepper plugins from the page (which calls PluginService::GetPluginInfoArray)
+ // might fail unless the page queried the list of available plugins at least once
+ // (which ends up calling PluginService::GetPlugins). Since the plugins list can only
+ // be created from the FILE thread, and that GetPluginInfoArray is synchronous, it
+ // can't loads plugins synchronously from the IO thread to serve the render process' request
+ // and we need to make sure that it happened beforehand.
+ content::PluginService::GetInstance()->GetPlugins(base::Bind(&dummyGetPluginCallback));
+#endif
+
#if defined(ENABLE_BASIC_PRINTING)
m_printJobManager.reset(new printing::PrintJobManager());
#endif // defined(ENABLE_BASIC_PRINTING)
diff --git a/src/process/process.pro b/src/process/process.pro
index 6174e53bf..eab11189e 100644
--- a/src/process/process.pro
+++ b/src/process/process.pro
@@ -8,23 +8,9 @@ load(qt_build_paths)
contains(QT_CONFIG, qt_framework) {
# Deploy the QtWebEngineProcess app bundle into the QtWebEngineCore framework.
DESTDIR = $$MODULE_BASE_OUTDIR/lib/QtWebEngineCore.framework/Versions/5/Helpers
- # FIXME: remove the following workaround with proper rpath handling or
- # patching of the installed QtWebEngineProcess binary.
- # Since QtWebEngineCore is now built as a framework, we need to pull
- # in and fixup its dependencies as well.
+
QT += webenginecore
- QMAKE_POST_LINK = \
- "xcrun install_name_tool -change " \
- "`xcrun otool -X -L $(TARGET) | grep QtWebEngineCore | cut -d ' ' -f 1` " \
- "@executable_path/../../../../QtWebEngineCore " \
- "$(TARGET); "
- linked_frameworks = QtQuick QtQml QtNetwork QtCore QtGui QtWebChannel
- for (current_framework, linked_frameworks) {
- QMAKE_POST_LINK += "xcrun install_name_tool -change " \
- "`xcrun otool -X -L $(TARGET) | grep $${current_framework} | cut -d ' ' -f 1` " \
- "@executable_path/../../../../../../../$${current_framework}.framework/$${current_framework} " \
- "$(TARGET);"
- }
+ QMAKE_RPATHDIR += @loader_path/../../../../../../../../Frameworks
} else {
CONFIG -= app_bundle
win32: DESTDIR = $$MODULE_BASE_OUTDIR/bin
diff --git a/src/webengine/api/qquickwebenginecertificateerror.cpp b/src/webengine/api/qquickwebenginecertificateerror.cpp
index 9570add65..561d1daf4 100644
--- a/src/webengine/api/qquickwebenginecertificateerror.cpp
+++ b/src/webengine/api/qquickwebenginecertificateerror.cpp
@@ -69,8 +69,19 @@ public:
\brief A utility type for ignoring certificate errors or rejecting erroneous certificates.
- This QML type contains information about a certificate error that occurred and provides a way
- to ignore the error or reject the certificate.
+ This QML type contains information about a certificate error that occurred. The \l error
+ property holds the reason that the error occurred and the \l description property holds a
+ short localized description of the error. The \l url property holds the URL that triggered
+ the error.
+
+ The certificate can be rejected by calling \l rejectCertificate, which will stop loading the
+ web engine request. By default, an invalid certificate will be automatically rejected.
+
+ The certificate error can be ignored by calling \l ignoreCertificateError, which will
+ resume loading the request.
+
+ It is possible to defer the decision of rejecting a certificate by calling \l defer,
+ which is useful when waiting for user input.
\sa WebEngineView::certificateError
*/
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index 14405251e..0275d8a2a 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -62,17 +62,29 @@ ASSERT_ENUMS_MATCH(QQuickWebEngineDownloadItem::MimeHtmlSaveFormat, QtWebEngineC
/*!
\class QQuickWebEngineProfile
- \brief The QQuickWebEngineProfile class provides a web-engine profile shared by multiple pages.
+ \brief The QQuickWebEngineProfile class provides a web engine profile shared by multiple pages.
\since 5.6
\inmodule QtWebEngine
- QQuickWebEngineProfile contains settings, scripts, and the list of visited links shared by all
- web engine pages that belong to the profile. As such, profiles can be used to isolate pages
- from each other. A typical use case is a dedicated profile for a 'private browsing' mode.
+ A web engine profile contains properties and functionality shared by a group of web engine
+ pages.
+
+ Information about visited links is stored together with persistent cookies and other persistent
+ data in a storage described by the persistentStoragePath property.
+
+ Profiles can be used to isolate pages from each other. A typical use case is a dedicated
+ \e {off-the-record profile} for a \e {private browsing} mode. An off-the-record profile forces
+ cookies, the HTTP cache, and other normally persistent data to be stored only in memory. The
+ offTheRecord property holds whether a profile is off-the-record.
+
+ The default profile can be accessed by defaultProfile(). It is a built-in profile that all
+ web pages not specifically created with another profile belong to.
- The default profile is a built-in profile that all web pages not specifically created with
- another profile belong to.
+ A WebEngineProfile instance can be created and accessed from C++ through the
+ QQuickWebEngineProfile class, which exposes further functionality in C++. This allows Qt Quick
+ applications to intercept URL requests (QQuickWebEngineProfile::setRequestInterceptor), or
+ register custom URL schemes (QQuickWebEngineProfile::installUrlSchemeHandler).
*/
/*!
diff --git a/src/webengine/api/qquickwebenginesettings_p.h b/src/webengine/api/qquickwebenginesettings_p.h
index 2914e1191..a870f7b0b 100644
--- a/src/webengine/api/qquickwebenginesettings_p.h
+++ b/src/webengine/api/qquickwebenginesettings_p.h
@@ -75,15 +75,12 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineSettings : public QObject {
Q_PROPERTY(bool hyperlinkAuditingEnabled READ hyperlinkAuditingEnabled WRITE setHyperlinkAuditingEnabled NOTIFY hyperlinkAuditingEnabledChanged)
Q_PROPERTY(bool errorPageEnabled READ errorPageEnabled WRITE setErrorPageEnabled NOTIFY errorPageEnabledChanged)
Q_PROPERTY(bool pluginsEnabled READ pluginsEnabled WRITE setPluginsEnabled NOTIFY pluginsEnabledChanged)
- // FIXME(QTBUG-40043): Mark fullScreenSupportEnabled with REVISION 1
- Q_PROPERTY(bool fullScreenSupportEnabled READ fullScreenSupportEnabled WRITE setFullScreenSupportEnabled NOTIFY fullScreenSupportEnabledChanged)
- // FIXME: add back REVISION when QTBUG-40043 has been fixed.
- Q_PROPERTY(QString defaultTextEncoding READ defaultTextEncoding WRITE setDefaultTextEncoding NOTIFY defaultTextEncodingChanged)
- // FIXME: Mark the following properties with REVISION 2
- Q_PROPERTY(bool screenCaptureEnabled READ screenCaptureEnabled WRITE setScreenCaptureEnabled NOTIFY screenCaptureEnabledChanged)
- Q_PROPERTY(bool webGLEnabled READ webGLEnabled WRITE setWebGLEnabled NOTIFY webGLEnabledChanged)
- Q_PROPERTY(bool webAudioEnabled READ webAudioEnabled WRITE setWebAudioEnabled NOTIFY webAudioEnabledChanged)
- Q_PROPERTY(bool accelerated2dCanvasEnabled READ accelerated2dCanvasEnabled WRITE setAccelerated2dCanvasEnabled NOTIFY accelerated2dCanvasEnabledChanged)
+ Q_PROPERTY(bool fullScreenSupportEnabled READ fullScreenSupportEnabled WRITE setFullScreenSupportEnabled NOTIFY fullScreenSupportEnabledChanged REVISION 1)
+ Q_PROPERTY(QString defaultTextEncoding READ defaultTextEncoding WRITE setDefaultTextEncoding NOTIFY defaultTextEncodingChanged REVISION 1)
+ Q_PROPERTY(bool screenCaptureEnabled READ screenCaptureEnabled WRITE setScreenCaptureEnabled NOTIFY screenCaptureEnabledChanged REVISION 2)
+ Q_PROPERTY(bool webGLEnabled READ webGLEnabled WRITE setWebGLEnabled NOTIFY webGLEnabledChanged REVISION 2)
+ Q_PROPERTY(bool webAudioEnabled READ webAudioEnabled WRITE setWebAudioEnabled NOTIFY webAudioEnabledChanged REVISION 2)
+ Q_PROPERTY(bool accelerated2dCanvasEnabled READ accelerated2dCanvasEnabled WRITE setAccelerated2dCanvasEnabled NOTIFY accelerated2dCanvasEnabledChanged REVISION 2)
public:
~QQuickWebEngineSettings();
@@ -139,14 +136,12 @@ signals:
void hyperlinkAuditingEnabledChanged();
void errorPageEnabledChanged();
void pluginsEnabledChanged();
- // FIXME(QTBUG-40043): Mark fullScreenSupportEnabledChanged with Q_REVISION(1)
- void fullScreenSupportEnabledChanged();
- // FIXME: add back Q_REVISION when QTBUG-40043 has been fixed.
- void screenCaptureEnabledChanged();
- void webGLEnabledChanged();
- void webAudioEnabledChanged();
- void accelerated2dCanvasEnabledChanged();
- void defaultTextEncodingChanged();
+ Q_REVISION(1) void fullScreenSupportEnabledChanged();
+ Q_REVISION(1) void defaultTextEncodingChanged();
+ Q_REVISION(2) void screenCaptureEnabledChanged();
+ Q_REVISION(2) void webGLEnabledChanged();
+ Q_REVISION(2) void webAudioEnabledChanged();
+ Q_REVISION(2) void accelerated2dCanvasEnabledChanged();
private:
explicit QQuickWebEngineSettings(QQuickWebEngineSettings *parentSettings = 0);
diff --git a/src/webengine/api/qquickwebenginetestsupport.cpp b/src/webengine/api/qquickwebenginetestsupport.cpp
index 33f48471a..46ffb06f4 100644
--- a/src/webengine/api/qquickwebenginetestsupport.cpp
+++ b/src/webengine/api/qquickwebenginetestsupport.cpp
@@ -51,6 +51,7 @@ void QQuickWebEngineErrorPage::loadFinished(bool success, const QUrl &url)
{
// Loading of the error page should not fail.
Q_ASSERT(success);
+ Q_UNUSED(success);
QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus);
Q_EMIT loadingChanged(&loadRequest);
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 70a85f5f3..6d1060661 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -70,7 +70,10 @@
#include <QClipboard>
#include <QGuiApplication>
#include <QLoggingCategory>
+#include <QMarginsF>
#include <QMimeData>
+#include <QPageLayout>
+#include <QPageSize>
#include <QQmlComponent>
#include <QQmlContext>
#include <QQmlEngine>
@@ -398,7 +401,9 @@ void QQuickWebEngineViewPrivate::urlChanged(const QUrl &url)
void QQuickWebEngineViewPrivate::iconChanged(const QUrl &url)
{
Q_Q(QQuickWebEngineView);
- icon = url;
+ if (iconUrl == url)
+ return;
+ iconUrl = url;
Q_EMIT q->iconChanged();
}
@@ -843,7 +848,7 @@ void QQuickWebEngineView::setUrl(const QUrl& url)
QUrl QQuickWebEngineView::icon() const
{
Q_D(const QQuickWebEngineView);
- return d->icon;
+ return d->iconUrl;
}
void QQuickWebEngineView::loadHtml(const QString &html, const QUrl &baseUrl)
@@ -1003,6 +1008,15 @@ void QQuickWebEngineViewPrivate::didFindText(quint64 requestId, int matchCount)
args.append(QJSValue(matchCount));
callback.call(args);
}
+
+void QQuickWebEngineViewPrivate::didPrintPage(quint64 requestId, const QByteArray &result)
+{
+ QJSValue callback = m_callbacks.take(requestId);
+ QJSValueList args;
+ args.append(QJSValue(result.data()));
+ callback.call(args);
+}
+
void QQuickWebEngineViewPrivate::showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText)
{
#ifdef ENABLE_QML_TESTSUPPORT_API
@@ -1179,6 +1193,30 @@ bool QQuickWebEngineView::wasRecentlyAudible()
return d->adapter->wasRecentlyAudible();
}
+void QQuickWebEngineView::printToPdf(const QString& filePath, PrintedPageSizeId pageSizeId, PrintedPageOrientation orientation)
+{
+ Q_D(const 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->adapter->printToPDF(pageLayout, filePath);
+}
+
+void QQuickWebEngineView::printToPdf(PrintedPageSizeId pageSizeId, PrintedPageOrientation orientation, const QJSValue &callback)
+{
+ 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));
+
+ if (callback.isUndefined())
+ return;
+
+ quint64 requestId = d->adapter->printToPDFCallbackResult(pageLayout);
+ d->m_callbacks.insert(requestId, callback);
+}
+
bool QQuickWebEngineView::isFullScreen() const
{
Q_D(const QQuickWebEngineView);
@@ -1525,7 +1563,7 @@ void QQuickWebEngineView::triggerWebAction(WebAction action)
break;
case ToggleMediaMute:
if (d->contextMenuData.mediaUrl.isValid() && d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio) {
- bool enable = (d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaMuted);
+ bool enable = !(d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaMuted);
d->adapter->executeMediaPlayerActionAt(d->contextMenuData.pos, WebContentsAdapter::MediaPlayerMute, enable);
}
break;
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index 4c6cbbaff..390b46429 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -273,6 +273,166 @@ public:
};
Q_DECLARE_FLAGS(FindFlags, FindFlag)
+ // must match QPageSize::PageSizeId
+ enum PrintedPageSizeId {
+ // Existing Qt sizes
+ A4,
+ B5,
+ Letter,
+ Legal,
+ Executive,
+ A0,
+ A1,
+ A2,
+ A3,
+ A5,
+ A6,
+ A7,
+ A8,
+ A9,
+ B0,
+ B1,
+ B10,
+ B2,
+ B3,
+ B4,
+ B6,
+ B7,
+ B8,
+ B9,
+ C5E,
+ Comm10E,
+ DLE,
+ Folio,
+ Ledger,
+ Tabloid,
+ Custom,
+
+ // New values derived from PPD standard
+ A10,
+ A3Extra,
+ A4Extra,
+ A4Plus,
+ A4Small,
+ A5Extra,
+ B5Extra,
+
+ JisB0,
+ JisB1,
+ JisB2,
+ JisB3,
+ JisB4,
+ JisB5,
+ JisB6,
+ JisB7,
+ JisB8,
+ JisB9,
+ JisB10,
+
+ // AnsiA = Letter,
+ // AnsiB = Ledger,
+ AnsiC,
+ AnsiD,
+ AnsiE,
+ LegalExtra,
+ LetterExtra,
+ LetterPlus,
+ LetterSmall,
+ TabloidExtra,
+
+ ArchA,
+ ArchB,
+ ArchC,
+ ArchD,
+ ArchE,
+
+ Imperial7x9,
+ Imperial8x10,
+ Imperial9x11,
+ Imperial9x12,
+ Imperial10x11,
+ Imperial10x13,
+ Imperial10x14,
+ Imperial12x11,
+ Imperial15x11,
+
+ ExecutiveStandard,
+ Note,
+ Quarto,
+ Statement,
+ SuperA,
+ SuperB,
+ Postcard,
+ DoublePostcard,
+ Prc16K,
+ Prc32K,
+ Prc32KBig,
+
+ FanFoldUS,
+ FanFoldGerman,
+ FanFoldGermanLegal,
+
+ EnvelopeB4,
+ EnvelopeB5,
+ EnvelopeB6,
+ EnvelopeC0,
+ EnvelopeC1,
+ EnvelopeC2,
+ EnvelopeC3,
+ EnvelopeC4,
+ // EnvelopeC5 = C5E,
+ EnvelopeC6,
+ EnvelopeC65,
+ EnvelopeC7,
+ // EnvelopeDL = DLE,
+
+ Envelope9,
+ // Envelope10 = Comm10E,
+ Envelope11,
+ Envelope12,
+ Envelope14,
+ EnvelopeMonarch,
+ EnvelopePersonal,
+
+ EnvelopeChou3,
+ EnvelopeChou4,
+ EnvelopeInvite,
+ EnvelopeItalian,
+ EnvelopeKaku2,
+ EnvelopeKaku3,
+ EnvelopePrc1,
+ EnvelopePrc2,
+ EnvelopePrc3,
+ EnvelopePrc4,
+ EnvelopePrc5,
+ EnvelopePrc6,
+ EnvelopePrc7,
+ EnvelopePrc8,
+ EnvelopePrc9,
+ EnvelopePrc10,
+ EnvelopeYou4,
+
+ // Last item, with commonly used synynoms from QPagedPrintEngine / QPrinter
+ LastPageSize = EnvelopeYou4,
+ NPageSize = LastPageSize,
+ NPaperSize = LastPageSize,
+
+ // Convenience overloads for naming consistency
+ AnsiA = Letter,
+ AnsiB = Ledger,
+ EnvelopeC5 = C5E,
+ EnvelopeDL = DLE,
+ Envelope10 = Comm10E
+ };
+ Q_ENUM(PrintedPageSizeId)
+
+ // must match QPageLayout::Orientation
+ enum PrintedPageOrientation {
+ Portrait,
+ Landscape
+ };
+ Q_ENUM(PrintedPageOrientation)
+
// QmlParserStatus
virtual void componentComplete() Q_DECL_OVERRIDE;
@@ -312,6 +472,8 @@ public Q_SLOTS:
Q_REVISION(3) bool isAudioMuted() const;
Q_REVISION(3) void setAudioMuted(bool muted);
Q_REVISION(3) bool wasRecentlyAudible();
+ Q_REVISION(3) void printToPdf(const QString &filePath, PrintedPageSizeId pageSizeId = PrintedPageSizeId::A4, PrintedPageOrientation orientation = PrintedPageOrientation::Portrait);
+ Q_REVISION(3) void printToPdf(PrintedPageSizeId pageSizeId = PrintedPageSizeId::A4, PrintedPageOrientation orientation = PrintedPageOrientation::Portrait, const QJSValue &callback = QJSValue());
private Q_SLOTS:
void lazyInitialize();
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index e4313a4bd..05c2228c4 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -160,6 +160,7 @@ public:
virtual void didFetchDocumentMarkup(quint64, const QString&) Q_DECL_OVERRIDE { }
virtual void didFetchDocumentInnerText(quint64, const QString&) Q_DECL_OVERRIDE { }
virtual void didFindText(quint64, int) Q_DECL_OVERRIDE;
+ virtual void didPrintPage(quint64 requestId, const QByteArray &result) Q_DECL_OVERRIDE;
virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE;
virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE;
virtual void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) Q_DECL_OVERRIDE;
@@ -209,7 +210,7 @@ public:
QQmlComponent *contextMenuExtraItems;
QtWebEngineCore::WebEngineContextMenuData contextMenuData;
QUrl explicitUrl;
- QUrl icon;
+ QUrl iconUrl;
int loadProgress;
bool m_fullscreenMode;
bool isLoading;
diff --git a/src/webengine/doc/images/qtwebengine-architecture.png b/src/webengine/doc/images/qtwebengine-architecture.png
index 37ca2da16..1c94d385f 100644
--- a/src/webengine/doc/images/qtwebengine-architecture.png
+++ b/src/webengine/doc/images/qtwebengine-architecture.png
Binary files differ
diff --git a/src/webengine/doc/images/qtwebengine-model.png b/src/webengine/doc/images/qtwebengine-model.png
new file mode 100644
index 000000000..0bbd556f1
--- /dev/null
+++ b/src/webengine/doc/images/qtwebengine-model.png
Binary files differ
diff --git a/src/webengine/doc/images/qtwebenginewidgets-model.png b/src/webengine/doc/images/qtwebenginewidgets-model.png
new file mode 100644
index 000000000..c334b84c9
--- /dev/null
+++ b/src/webengine/doc/images/qtwebenginewidgets-model.png
Binary files differ
diff --git a/src/webengine/doc/qtwebengine.qdocconf b/src/webengine/doc/qtwebengine.qdocconf
index 2fbdef93e..baa4a9859 100644
--- a/src/webengine/doc/qtwebengine.qdocconf
+++ b/src/webengine/doc/qtwebengine.qdocconf
@@ -43,6 +43,7 @@ tagfile = ../../../doc/qtwebengine/qtwebengine.tags
depends += qtcore \
qtgui \
qtnetwork \
+ qtprintsupport \
qtqml \
qtquick \
qtquickcontrols \
@@ -69,7 +70,7 @@ exampledirs += . \
imagedirs += images
navigation.landingpage = "Qt WebEngine"
-navigation.cppclassespage = "Qt WebEngine C++ Classes"
+navigation.cppclassespage = "Qt WebEngine C++ Classes and Namespaces"
navigation.qmltypespage = "Qt WebEngine QML Types"
Cpp.ignoretokens += Q_WEBENGINE_EXPORT QWEBENGINEWIDGETS_EXPORT
diff --git a/src/webengine/doc/src/qtwebengine-index.qdoc b/src/webengine/doc/src/qtwebengine-index.qdoc
index fd6010da6..809e10c72 100644
--- a/src/webengine/doc/src/qtwebengine-index.qdoc
+++ b/src/webengine/doc/src/qtwebengine-index.qdoc
@@ -61,7 +61,7 @@
\section1 API References
\list
- \li \l{Qt WebEngine C++ Classes}
+ \li \l{Qt WebEngine C++ Classes and Namespaces}
\li \l{Qt WebEngine QML Types}
\endlist
*/
diff --git a/src/webengine/doc/src/qtwebengine-modules.qdoc b/src/webengine/doc/src/qtwebengine-modules.qdoc
index 4dbba5e4e..7b8ced728 100644
--- a/src/webengine/doc/src/qtwebengine-modules.qdoc
+++ b/src/webengine/doc/src/qtwebengine-modules.qdoc
@@ -27,7 +27,7 @@
/*!
\page qtwebengine-modules.html
- \title Qt WebEngine C++ Classes
+ \title Qt WebEngine C++ Classes and Namespaces
\brief Provides functionality for rendering regions of dynamic web content.
\e {Qt WebEngine} provides functionality for rendering regions of dynamic web content.
diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc
index 0cf4a43c6..cf757a6d5 100644
--- a/src/webengine/doc/src/qtwebengine-overview.qdoc
+++ b/src/webengine/doc/src/qtwebengine-overview.qdoc
@@ -46,6 +46,13 @@
application to use Qt WebEngine widgets, see \l{Porting from Qt WebKit to Qt WebEngine}. For new
applications, we recommend using Qt Quick and the WebEngineView QML type.
+ For more information about the requirements for building Qt WebEngine from source on the
+ supported platforms and for other platform-specific information, see
+ \l{Qt WebEngine Platform Notes}.
+
+ The \l {Qt WebChannel} module can be used to create a bi-directional communication channel
+ between QObject objects on the C++ side and JavaScript on the QML side.
+
\section1 Qt WebEngine Architecture
\image qtwebengine-architecture.png
@@ -53,14 +60,38 @@
The functionality in Qt WebEngine is divided into the following modules:
\list
- \li \l{Qt WebEngine Widgets}, which provides a web browser engine and C++ classes to render
- web content and to interact with it
- \li \l{Qt WebEngine}, which provides QML types for rendering web content within a QML
- application
- \li \l{Qt WebEngine Core}, which provides common API used by Qt WebEngine and
- Qt WebEngine Widgets
+ \li \l{Qt WebEngine Widgets} for creating widget-based web applications
+ \li \l{Qt WebEngine} for creating Qt Quick based web applications
+ \li \l{Qt WebEngine Core} for interacting with Chromium
\endlist
+ Page rendering and JavaScript execution are separated from the GUI process into the Qt WebEngine
+ Process. It is a library that must be shipped with the application if the Qt libraries are
+ bundled into the application.
+
+ \section2 Qt WebEngine Widgets
+
+ \image qtwebenginewidgets-model.png
+
+ A \e {web engine view} is the main widget component of the Qt WebEngine module. It can be used
+ in various applications to load web content. Within a view, a \e {web engine page} holds a main
+ frame that is responsible for web content, the \e history of navigated links, and \e actions.
+ The view and page are quite similar, as they provide a set of common functions.
+
+ All pages belong to a \e {web engine profile} that contains shared \e settings, \e scripts, and
+ \e cookies. Profiles can be used to isolate pages from each other. A typical use case is a
+ dedicated profile for a \e {private browsing} mode, where no information is permanently saved.
+
+ \section2 Qt WebEngine
+
+ \image qtwebengine-model.png
+
+ The Qt WebEngine QML implementation contains the same elements as the C++ implementation,
+ except that there is no separately accessible web engine page. The supported page functionality
+ is integrated into the web engine view.
+
+ \section2 Qt WebEngine Core
+
The Qt WebEngine core is based on the \l {Chromium Project}. Chromium provides its own network
and painting engines and is developed tightly together with its dependent modules, and
therefore Qt WebEngine provides better and more reliable support for the latest HTML5
@@ -73,12 +104,32 @@
\l{https://chromium.googlesource.com/chromium/src/+/master/docs/chromium_browser_vs_google_chrome.md}{overview}
that is part of the documentation in the \l {Chromium Project} upstream source tree.
+ This version of Qt WebEngine is based on Chromium snapshot version 45.0.2554.101, with
+ additional security fixes from the 46, 47 and 48 branches of the \l {Chromium Project}.
+
+ \section2 Qt WebEngine Process
+
+ The Qt WebEngine Process renders web pages and executes JavaScript.
+
Chromium is tightly integrated to the \l{Qt Quick Scene Graph}{Qt Quick scene graph}, which is
based on OpenGL ES 2.0 or OpenGL 2.0 for its rendering. This provides you with one-pass
compositing of web content and all the Qt Quick UI. The integration to Chromium is transparent
to developers, who just work with Qt and JavaScript.
- To expose QObjects to JavaScript, developers can use the \l {Qt WebChannel} module.
+ The document object model (DOM) of a page is constructed when the document is ready, typically
+ when the page is completely loaded. Therefore, executing scripts as soon as a document is
+ created is not suitable for DOM operations, where one has to wait until the DOM is ready.
+
+ In addition, an injected script shares the same \e world as the other scripts executed on the
+ page, which might lead to conflicts. To avoid this, the Chromium API for
+ \e{Content Script Extensions} is implemented by \e {web engine script}. It specifies the
+ script to run, the injection point, and the world where the script is run. This enables
+ accessing the DOM to manipulate it within a world.
+
+ Because the render process is separated from the GUI process, they should ideally share an
+ OpenGL context to enable one process to access the resources uploaded by the other, such as
+ images or textures. However, some inter-process communication is needed for safety and
+ reliability, because it enables restarting a crashed process.
\section1 Embedding Web Content into Widget Based Applications
@@ -92,23 +143,48 @@
view->show();
\endcode
- An instance of QWebEngineView has one QWebEnginePage. QWebEnginePage provides access to the
- page's navigation history and the ability to run JavaScript code in the context of the page's
- main frame and enables customization of handlers for specific events like showing custom
- authentication dialogs.
+ An instance of QWebEngineView has one QWebEnginePage. QWebEnginePage can have a
+ QWebEngineHistory that provides access to the page's navigation history and several QAction
+ objects that apply actions on the web page. In addition, a QWebEnginePage has the ability to
+ run JavaScript code in the context of the page's main frame and to enable customization of
+ handlers for specific events like showing custom authentication dialogs.
+
+ Each QWebEnginePage belongs to a QWebEngineProfile that can have a QWebEngineSettings
+ for specifying page settings, a QWebEngineScriptCollection for running scripts on the page, and
+ a QWebEngineCookieStore for accessing the HTTP cookies of Chromium. A QWebEnginePage can also
+ directly point to a script collection or cookie store.
\section1 Embedding Web Content into Qt Quick Applications
- The WebEngineView QML type allows QML applications to render regions of dynamic web content. A
- \e{WebEngineView} type may share the screen with other QML types or encompass the full screen
- as specified within the QML application.
+ The WebEngineView QML type allows Qt Quick applications to render regions of dynamic web
+ content. A \e{WebEngineView} type may share the screen with other QML types or encompass the
+ full screen as specified within the Qt Quick application.
+
+ To make sure that OpenGL context can be shared between the GUI and render processes, the web
+ engine must be initialized by using \l QtWebEngine::initialize in the application main source
+ file, as illustrated by the following code snippet:
+
+ \code
+ int main(int argc, char **argv)
+ {
+ Application app(argc, argv);
+
+ QtWebEngine::initialize();
+
+ QQmlApplicationEngine appEngine;
+ appEngine.load(QUrl("qrc:/main.qml"));
+
+ return app.exec();
+ }
+ \endcode
An application can load pages into the WebEngineView, using either an URL or HTML string, and
navigate within session history. By default, links to different pages load within the same
WebEngineView object, but web sites may request them to be opened as a new tab, window, or
dialog.
- The following sample QML application loads a web page and responds to session history context:
+ The following sample QML application loads a web page using the \l{WebEngineView::}{url}
+ property:
\qml
import QtQuick 2.1
@@ -168,7 +244,7 @@
Qt WebEngine takes advantage of the multi process model that the Chromium project offers.
The multi process model requires the QtWebEngineProcess executable to be deployed alongside your application.
- To do this, we recommend the use of Qt’s cross-platform deployment tools.
+ To do this, we recommend the use of Qt's cross-platform deployment tools.
Alternatively, if you are carrying out manual deployment, you will find the QtWebEngineProcess executable in the
libexec directory of your Qt installation.
diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
index 1f2d9dcf2..5a81c7775 100644
--- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
+++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
@@ -31,6 +31,19 @@
\brief Contains information about issues that are specific to the Qt WebEngine module.
+ \section1 Target Platforms
+
+ Qt WebEngine does try to support all \l{Supported Platforms} of Qt. However, due to
+ different requirements of Chromium this is not always possible. Known limitations are:
+
+ \list
+ \li Qt WebEngine currently supports only Windows, Linux, and OS X.
+
+ \li On Windows, Qt WebEngine only supports Windows Vista or newer as target platform.
+ Due to use of newer API in Chromium, Windows XP is not supported. WinRT is
+ not supported, either.
+ \endlist
+
\section1 Building Qt WebEngine from Source
The requirements for building Qt 5 modules from source are listed separately for each supported
@@ -50,6 +63,9 @@
\li OS X: Xcode version 5.1 or later on OS X 10.9 or later
\endlist
+ \note Qt WebEngine cannot be built for the 32-bit mode of OS X (using the
+ macx-clang-32 mkspec).
+
\section1 Pepper Plugin API Support
Qt WebEngine supports loading Pepper Plugin API (PPAPI) plugins. The plugins must be loaded
@@ -69,11 +85,11 @@
The MIME type is important because it determines which embeds the plugin is used for.
- This process has been automated for the Adobe Flash Player Plugin.
+ This process has been automated for the Pepper Flash player plugin.
- \section2 Adobe Flash Player Plugin Support
+ \section2 Pepper Flash Player Plugin Support
- The Adobe Flash player plugin can be loaded automatically if it is installed in one of the
+ The Pepper Flash player plugin can be loaded automatically if it is installed in one of the
following locations, depending on the platform:
\list
@@ -94,12 +110,21 @@
\endcode
\endlist
- You can also load the Flash player from a specific location by using command line arguments:
+ You can also load the Pepper Flash player from a specific location by using command line
+ arguments:
\code
--ppapi-flash-path=./libpepflashplayer.so
\endcode
+ By default, the Flash version is set to \c{11.2.999.999}. You can use the
+ \c{ppapi-flash-version=} argument to set another Flash version in the
+ in the format \c{major.minor.build.revision}:
+
+ \code
+ --ppapi-flash-version=16.0.0.235
+ \endcode
+
\section1 Audio and Video Codec Support
Qt WebEngine supports the MPEG-4 Part 14 (MP4) file format only if the required proprietary
@@ -117,6 +142,25 @@
with the codec libraries. For some codecs, open source implementations, such as \l {OpenH264},
are available.
+ \section1 Mac App Store Compatibility
+
+ By default, Qt WebEngine uses private OS X API, which might cause an application to be
+ rejected when submitted to the Mac App Store. To configure Qt WebEngine not to use these API
+ calls, Qt WebEngine has to be recompiled:
+
+ \code
+ qmake WEBENGINE_CONFIG += use_appstore_compliant_code
+ \endcode
+
+ However, this will cause some behavioral changes, such as:
+
+ \list
+ \li The OS X Kill Ring functionality will no longer work (emacs-like copy pasting).
+ \li Certain Chromium sandboxing cleanup is not done.
+ \li Text areas will be painted with a different style.
+ \li Text fields might be painted with a different style on Mountain Lion (OS X 10.8).
+ \endlist
+
\section1 Default QSurfaceFormat OpenGL Profile Support
If a new default QSurfaceFormat with a modified OpenGL profile has to be set, it should be set
diff --git a/src/webengine/doc/src/webengineview.qdoc b/src/webengine/doc/src/webengineview.qdoc
index 8e09d2b89..bcabe2152 100644
--- a/src/webengine/doc/src/webengineview.qdoc
+++ b/src/webengine/doc/src/webengineview.qdoc
@@ -34,11 +34,126 @@
may share the screen with other QML types, such as a TabView, or fill the screen, as specified
within the QML application.
- \section1 Rendering to OpenGL Surface
+ \section2 Initializing Web Engine
+
+ For the web engine view to be rendered, the web engine must be initialized by using
+ \l QtWebEngine::initialize in the application main source file, as illustrated by the
+ following code snippet:
+
+ \code
+ int main(int argc, char **argv)
+ {
+ Application app(argc, argv);
+
+ QtWebEngine::initialize();
+
+ QQmlApplicationEngine appEngine;
+ appEngine.load(QUrl("qrc:/main.qml"));
+
+ return app.exec();
+ }
+ \endcode
+
+ \section2 Loading Web Pages
+
+ An application can load pages into the WebEngineView, using either the \l url property or the
+ \l loadHtml method and navigate within the view's session history. The history is represented
+ by a WebEngineHistory data model that is held by the \l navigationHistory property.
+
+ The following sample QML application loads a web page using the \c url property:
+
+ \qml
+ import QtQuick 2.1
+ import QtQuick.Controls 1.1
+ import QtWebEngine 1.1
+
+ ApplicationWindow {
+ width: 1280
+ height: 720
+ visible: true
+ WebEngineView {
+ id: webview
+ url: "http://www.qt.io"
+ anchors.fill: parent
+ }
+ }
+ \endqml
+
+ The \l loadingChanged() signal is emitted when loading a page begins, ends, or fails. The
+ \l loading property holds whether the HTML page is currently loading and the load status is
+ reflected in the \l LoadStatus property.
+
+ The title of an HTML page can be accessed with the \l title property. Additionally, a web
+ page may specify an icon, which can be accessed using the \l icon property. The \l zoomFactor
+ property holds the overall size of the contents of the web page.
+
+ If a certificate error is raised while loading a web page, the \l certificateError() signal is
+ emitted. Certificate errors are handled by using the methods of the WebEngineCertificateError
+ type.
+
+ \section2 Interaction
+
+ By default, links to different pages load within the same WebEngineView object, but web sites
+ may request them to be opened as a new tab, window, or dialog. The \l newViewRequested() signal
+ is emitted when a request to load the page in a separate web engine view is issued. The
+ NewViewDestination property describes how the new view should be opened. In addition, the
+ WebEngineNewViewRequest utility type can be used to load web pages in separate web engine views.
+
+ The \l findText() method can be used to search for a string on a web page, using the options
+ described by \l FindFlags.
+
+ The \l setActiveFocusOnPress() method can be used to create a UI element that should not get
+ focus. This can be useful in a hybrid UI.
+
+ The \l linkHovered() signal is emitted when a mouse pointer passes over a link and thus
+ corresponds to the \c{mouseover} DOM event.
+
+ Actions, such as selecting and editing content, can be performed on a web page by using the
+ \l triggerWebAction() method. The available actions are described by the \l WebAction property.
+
+ The \l backgroundColorChanged() signal is emitted when the web page background color changes.
+
+ \section2 User Scripts
+
+ During the loading of a page, so called \e {user scripts} can be injected in the JavaScript
+ engine at different points. The script objects attached to the web engine view are held by the
+ \l userScripts property and injected by using the WebEngineScript type. Scripts can also be run
+ by using the runJavaScript() method in the same world as other scripts that are part of the
+ loaded site.
+
+ The \l webChannel property can be used to expose a WebChannel instance in the JavaScript context
+ of the page it is rendering as \c qt.webChannelTransport.
+
+ \section2 Fullscreen Mode
+
+ A web page can request through the JavaScript API to be loaded in fullscreen mode. The
+ \l fullScreenRequested() signal is emitted when the web page issues the request. The
+ WebEngineFullScreenRequest utility type can be used to toggle fullscreen requests. The
+ \l fullScreenCancelled method can be used to notify the browser engine when the windowing
+ system forces the application to leave fullscreen mode.
+
+ \section2 Profiles
+
+ Web engine views can be isolated from each other by using the WebEngineProfile type. A profile
+ contains settings, scripts, and the list of visited links shared by all views that belong to the
+ profile. For example, a dedicated profile could be created for a \e {private browsing} mode. The
+ current profile for the view is held by the \l profile property and the current settings are
+ held by the \l settings property. The settings are specified by using the WebEngineSettings
+ type.
+
+ \section2 Platform Features
+
+ Web pages can request access to platform features, such as geolocation or audio and video
+ capture devices. The \l featurePermissionRequested() signal is emitted when a web page requests
+ to make use of a resource. The supported platform features are described by the \l Feature
+ property. If users grant the permission, the \l grantFeaturePermission() method is used to set
+ it to \e granted.
+
+ \section2 Rendering to OpenGL Surface
When using a QQuickRenderControl to render a Qt Quick user interface to an OpenGL surface, the
WebEngineView type is not rendered correctly. The web engine view attempts to use a global
- OpenGL context created by \l QtWebEngine::initialize(), but there is no public API for accessing
+ OpenGL context created by \l QtWebEngine::initialize, but there is no public API for accessing
that context in order to share it with the \c QQuickRenderControl context.
To have the web engine view rendered correctly, it is possible to manually create a new
@@ -418,15 +533,8 @@
This signal is emitted when an invalid certificate error is raised while loading a given request.
- The certificate error can be rejected by calling WebEngineCertificateError::rejectCertificate,
- which will stop loading the request.
-
- The certificate error can be ignored by calling
- WebEngineCertificateError::ignoreCertificateError, which will resume loading the request.
-
- It is possible to defer the decision of rejecting the given certificate by calling
- WebEngineCertificateError::defer, which is useful when waiting for user input.
- By default, the invalid certificate will be automatically rejected.
+ The certificate error can be handled by using the methods of the WebEngineCertificateError
+ type.
The corresponding handler is \c onCertificateError.
@@ -717,6 +825,165 @@
*/
/*!
+ \qmlproperty enumeration WebEngineView::PrintedPageSizeId
+ \since QtWebEngine 1.3
+
+ This enum type lists the available page sizes as defined in the Postscript
+ PPD standard.
+
+ The enumeration values are mapped from and must match QPageSize::PageSizeId. They are also
+ duplicated in QPagedPaintDevice and QPrinter.
+
+ The defined sizes are:
+
+ \value A0 841 x 1189 mm
+ \value A1 594 x 841 mm
+ \value A2 420 x 594 mm
+ \value A3 297 x 420 mm
+ \value A4 210 x 297 mm, 8.26 x 11.69 inches
+ \value A5 148 x 210 mm
+ \value A6 105 x 148 mm
+ \value A7 74 x 105 mm
+ \value A8 52 x 74 mm
+ \value A9 37 x 52 mm
+ \value B0 1000 x 1414 mm
+ \value B1 707 x 1000 mm
+ \value B2 500 x 707 mm
+ \value B3 353 x 500 mm
+ \value B4 250 x 353 mm
+ \value B5 176 x 250 mm, 6.93 x 9.84 inches
+ \value B6 125 x 176 mm
+ \value B7 88 x 125 mm
+ \value B8 62 x 88 mm
+ \value B9 44 x 62 mm
+ \value B10 31 x 44 mm
+ \value C5E 163 x 229 mm
+ \value Comm10E 105 x 241 mm, U.S. Common 10 Envelope
+ \value DLE 110 x 220 mm
+ \value Executive 7.5 x 10 inches, 190.5 x 254 mm
+ \value Folio 210 x 330 mm
+ \value Ledger 431.8 x 279.4 mm
+ \value Legal 8.5 x 14 inches, 215.9 x 355.6 mm
+ \value Letter 8.5 x 11 inches, 215.9 x 279.4 mm
+ \value Tabloid 279.4 x 431.8 mm
+ \value Custom Unknown, or a user defined size.
+ \value A10
+ \value A3Extra
+ \value A4Extra
+ \value A4Plus
+ \value A4Small
+ \value A5Extra
+ \value B5Extra
+ \value JisB0
+ \value JisB1
+ \value JisB2
+ \value JisB3
+ \value JisB4
+ \value JisB5
+ \value JisB6
+ \value JisB7
+ \value JisB8
+ \value JisB9
+ \value JisB10
+ \value AnsiA = \c Letter
+ \value AnsiB = \c Ledger
+ \value AnsiC
+ \value AnsiD
+ \value AnsiE
+ \value LegalExtra
+ \value LetterExtra
+ \value LetterPlus
+ \value LetterSmall
+ \value TabloidExtra
+ \value ArchA
+ \value ArchB
+ \value ArchC
+ \value ArchD
+ \value ArchE
+ \value Imperial7x9
+ \value Imperial8x10
+ \value Imperial9x11
+ \value Imperial9x12
+ \value Imperial10x11
+ \value Imperial10x13
+ \value Imperial10x14
+ \value Imperial12x11
+ \value Imperial15x11
+ \value ExecutiveStandard
+ \value Note
+ \value Quarto
+ \value Statement
+ \value SuperA
+ \value SuperB
+ \value Postcard
+ \value DoublePostcard
+ \value Prc16K
+ \value Prc32K
+ \value Prc32KBig
+ \value FanFoldUS
+ \value FanFoldGerman
+ \value FanFoldGermanLegal
+ \value EnvelopeB4
+ \value EnvelopeB5
+ \value EnvelopeB6
+ \value EnvelopeC0
+ \value EnvelopeC1
+ \value EnvelopeC2
+ \value EnvelopeC3
+ \value EnvelopeC4
+ \value EnvelopeC5 = \c C5E
+ \value EnvelopeC6
+ \value EnvelopeC65
+ \value EnvelopeC7
+ \value EnvelopeDL = \c DLE
+ \value Envelope9
+ \value Envelope10 = \c Comm10E
+ \value Envelope11
+ \value Envelope12
+ \value Envelope14
+ \value EnvelopeMonarch
+ \value EnvelopePersonal
+ \value EnvelopeChou3
+ \value EnvelopeChou4
+ \value EnvelopeInvite
+ \value EnvelopeItalian
+ \value EnvelopeKaku2
+ \value EnvelopeKaku3
+ \value EnvelopePrc1
+ \value EnvelopePrc2
+ \value EnvelopePrc3
+ \value EnvelopePrc4
+ \value EnvelopePrc5
+ \value EnvelopePrc6
+ \value EnvelopePrc7
+ \value EnvelopePrc8
+ \value EnvelopePrc9
+ \value EnvelopePrc10
+ \value EnvelopeYou4
+ \value LastPageSize = \c EnvelopeYou4
+ \omitvalue NPageSize
+ \omitvalue NPaperSize
+
+ \sa WebEngineView::printToPdf()
+*/
+
+/*!
+ \qmlproperty enumeration WebEngineView::PrintedPageOrientation
+ \since QtWebEngine 1.3
+
+ Describes the orientation of a PDF document that gets created from the WebEngineView's contents.
+ The enumeration values are mapped from and must match QPageLayout::Orientation.
+
+ \value Portrait
+ The document will be created using portrait orientation.
+
+ \value Landscape
+ The document will be created using landscape orientation.
+
+ \sa WebEngineView::printToPdf()
+*/
+
+/*!
\qmltype WebEngineFullScreenRequest
\instantiates QQuickWebEngineFullScreenRequest
\inqmlmodule QtWebEngine
@@ -785,6 +1052,26 @@
*/
/*!
+ \qmlmethod void WebEngineView::printToPdf(const QString &filePath, PrintedPageSizeId pageSizeId, PrintedPageOrientation orientation)
+ \since QtWebEngine 1.3
+
+ Prints the WebEngineView's current content to a PDF document and stores it under \a filePath. The document's size will be determined
+ by the value of \a pageSizeId and its orientation will be determined using \a orientation.
+*/
+
+/*!
+ \qmlmethod void WebEngineView::printToPdf(PrintedPageSizeId pageSizeId, PrintedPageOrientation orientation, variant resultCallback)
+ \since QtWebEngine 1.3
+
+ Prints the WebEngineView's current content to a PDF document and returns it in a byte array. The document's size will be determined
+ by the value of \a pageSizeId and its orientation will be determined using \a orientation.
+
+ The \a resultCallback must take a string parameter. This string will contain the document's data upon successful printing and an empty
+ string otherwise.
+*/
+
+
+/*!
\qmlsignal void WebEngineView::wasRecentlyAudibleChanged(bool wasRecentlyAudible)
\since QtWebEngine 1.3
diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp
index 2feb3d195..9025d248f 100644
--- a/src/webengine/plugin/plugin.cpp
+++ b/src/webengine/plugin/plugin.cpp
@@ -85,7 +85,8 @@ public:
tr("Cannot create a separate instance of WebEngineDownloadItem"));
qmlRegisterUncreatableType<QQuickWebEngineNewViewRequest>(uri, 1, 1, "WebEngineNewViewRequest", tr("Cannot create separate instance of WebEngineNewViewRequest"));
qmlRegisterUncreatableType<QQuickWebEngineSettings>(uri, 1, 1, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings"));
- // FIXME(QTBUG-40043): qmlRegisterUncreatableType<QQuickWebEngineSettings, 1>(uri, 1, 2, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings"));
+ qmlRegisterUncreatableType<QQuickWebEngineSettings, 1>(uri, 1, 2, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings"));
+ qmlRegisterUncreatableType<QQuickWebEngineSettings, 2>(uri, 1, 3, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings"));
qmlRegisterSingletonType<QQuickWebEngineSingleton>(uri, 1, 1, "WebEngine", webEngineSingletonProvider);
qmlRegisterUncreatableType<QQuickWebEngineHistory>(uri, 1, 1, "NavigationHistory",
tr("Cannot create a separate instance of NavigationHistory"));
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 13dee09f4..7f7cba431 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -216,13 +216,21 @@ void QWebEnginePagePrivate::loadFinished(bool success, const QUrl &url, bool isE
Q_UNUSED(errorCode);
Q_UNUSED(errorDescription);
- if (isErrorPage)
+ if (isErrorPage) {
+ Q_ASSERT(settings->testAttribute(QWebEngineSettings::ErrorPageEnabled));
+ Q_ASSERT(success);
+ Q_EMIT q->loadFinished(false);
return;
+ }
isLoading = false;
if (success)
explicitUrl = QUrl();
- Q_EMIT q->loadFinished(success);
+ // Delay notifying failure until the error-page is done loading.
+ // Error-pages are not loaded on failures due to abort.
+ if (success || errorCode == -3 /* ERR_ABORTED*/ || !settings->testAttribute(QWebEngineSettings::ErrorPageEnabled)) {
+ Q_EMIT q->loadFinished(success);
+ }
updateNavigationActions();
}
@@ -306,6 +314,11 @@ void QWebEnginePagePrivate::didFindText(quint64 requestId, int matchCount)
m_callbacks.invoke(requestId, matchCount > 0);
}
+void QWebEnginePagePrivate::didPrintPage(quint64 requestId, const QByteArray &result)
+{
+ m_callbacks.invoke(requestId, result);
+}
+
void QWebEnginePagePrivate::passOnFocus(bool reverse)
{
if (view)
@@ -490,6 +503,7 @@ QWebEnginePage::QWebEnginePage(QObject* parent)
/*!
\enum QWebEnginePage::RenderProcessTerminationStatus
+ \since 5.6
This enum describes the status with which the render process terminated:
@@ -505,6 +519,7 @@ QWebEnginePage::QWebEnginePage(QObject* parent)
/*!
\fn QWebEnginePage::renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode)
+ \since 5.6
This signal is emitted when the render process is terminated with a non-zero exit status.
\a terminationStatus is the termination status of the process and \a exitCode is the status code
@@ -1625,6 +1640,38 @@ QSizeF QWebEnginePage::contentsSize() const
return d->adapter->lastContentsSize();
}
+/*!
+ Renders the current content of the page into a PDF document and saves it in the location specified in \a filePath.
+ The page size and orientation of the produced PDF document are taken from the values specified in \a pageLayout.
+
+ If a file already exists at the provided file path, it will be overwritten.
+ \since 5.7
+*/
+void QWebEnginePage::printToPdf(const QString &filePath, const QPageLayout &pageLayout)
+{
+ Q_D(const QWebEnginePage);
+ d->adapter->printToPDF(pageLayout, filePath);
+}
+
+
+/*!
+ \fn void QWebEnginePage::printToPdf(const QPageLayout &pageLayout, FunctorOrLambda resultCallback)
+ Renders the current content of the page into a PDF document and returns a byte array containing the PDF data
+ as parameter to \a resultCallback.
+ The page size and orientation of the produced PDF document are taken from the values specified in \a pageLayout.
+
+ The \a resultCallback must take a const reference to a QByteArray as parameter. If printing was successful, this byte array
+ will contain the PDF data, otherwise, the byte array will be empty.
+
+ \since 5.7
+*/
+void QWebEnginePage::printToPdf(const QPageLayout &pageLayout, const QWebEngineCallback<const QByteArray&> &resultCallback)
+{
+ Q_D(QWebEnginePage);
+ quint64 requestId = d->adapter->printToPDFCallbackResult(pageLayout);
+ d->m_callbacks.registerCallback(requestId, resultCallback);
+}
+
QT_END_NAMESPACE
#include "moc_qwebenginepage.cpp"
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index 08663a05e..8d6da4459 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -40,13 +40,14 @@
#ifndef QWEBENGINEPAGE_H
#define QWEBENGINEPAGE_H
-#include <qtwebenginewidgetsglobal.h>
-#include <qwebenginecertificateerror.h>
-#include <qwebenginecallback.h>
+#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h>
+#include <QtWebEngineWidgets/qwebenginecertificateerror.h>
+#include <QtWebEngineCore/qwebenginecallback.h>
#include <QtCore/qobject.h>
#include <QtCore/qurl.h>
#include <QtCore/qvariant.h>
+#include <QtGui/qpagelayout.h>
#include <QtNetwork/qnetworkaccessmanager.h>
#include <QtWidgets/qwidget.h>
@@ -267,6 +268,12 @@ public:
void setAudioMuted(bool muted);
bool wasRecentlyAudible();
+ void printToPdf(const QString &filePath, const QPageLayout &layout);
+#ifdef Q_QDOC
+ void printToPdf(const QPageLayout &layout, FunctorOrLambda resultCallback);
+#else
+ void printToPdf(const QPageLayout &layout, const QWebEngineCallback<const QByteArray&> &resultCallback);
+#endif
Q_SIGNALS:
void loadStarted();
void loadProgress(int progress);
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 6d4b857eb..b08c19821 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -112,6 +112,7 @@ public:
virtual void didFetchDocumentMarkup(quint64 requestId, const QString& result) Q_DECL_OVERRIDE;
virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) Q_DECL_OVERRIDE;
virtual void didFindText(quint64 requestId, int matchCount) Q_DECL_OVERRIDE;
+ virtual void didPrintPage(quint64 requestId, const QByteArray &result) Q_DECL_OVERRIDE;
virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE;
virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE;
virtual void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) Q_DECL_OVERRIDE;
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index 62836c5f9..50da38f22 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -63,17 +63,39 @@ using QtWebEngineCore::BrowserContextAdapter;
/*!
\class QWebEngineProfile
- \brief The QWebEngineProfile class provides a web-engine profile shared by multiple pages.
+ \brief The QWebEngineProfile class provides a web engine profile shared by multiple pages.
\since 5.5
\inmodule QtWebEngineWidgets
- QWebEngineProfile contains settings, scripts, and the list of visited links shared by all
- web engine pages that belong to the profile. As such, profiles can be used to isolate pages
- from each other. A typical use case is a dedicated profile for a 'private browsing' mode.
+ A web engine profile contains settings, scripts, persistent cookie policy, and the list of
+ visited links shared by all web engine pages that belong to the profile.
- The default profile is a built-in profile that all web pages not specifically created with
- another profile belong to.
+ All pages that belong to the profile share a common QWebEngineSettings instance, which can
+ be accessed with the settings() method. Likewise, the scripts() method provides access
+ to a common QWebEngineScriptCollection instance.
+
+ Information about visited links is stored together with persistent cookies and other persistent
+ data in a storage returned by persistentStoragePath(). The cache can be cleared of links by
+ clearVisitedLinks() or clearAllVisitedLinks(). PersistentCookiesPolicy describes whether
+ session and persistent cookies are saved to and restored from memory or disk.
+
+ Profiles can be used to isolate pages from each other. A typical use case is a dedicated
+ \e {off-the-record profile} for a \e {private browsing} mode. Using QWebEngineProfile() without
+ defining a storage name constructs a new off-the-record profile that leaves no record on the
+ local machine, and has no persistent data or cache. The isOffTheRecord() method can be used
+ to check whether a profile is off-the-record.
+
+ The default profile can be accessed by defaultProfile(). It is a built-in profile that all
+ web pages not specifically created with another profile belong to.
+
+ Implementing the QWebEngineUrlRequestInterceptor interface and registering the interceptor on a
+ profile by setRequestInterceptor() enables intercepting, blocking, and modifying URL
+ requests (QWebEngineUrlRequestInfo) before they reach the networking stack of Chromium.
+
+ A QWebEngineUrlSchemeHandler can be registered for a profile by installUrlSchemeHandler()
+ to add support for custom URL schemes. Requests for the scheme are then issued to
+ QWebEngineUrlSchemeHandler::requestStarted() as QWebEngineUrlRequestJob objects.
*/
/*!
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index 8f2c3cbf7..add2000d1 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -51,6 +51,7 @@
#include <QMenu>
#include <QContextMenuEvent>
#include <QStackedLayout>
+#include <QPageLayout>
QT_BEGIN_NAMESPACE
@@ -113,6 +114,7 @@ QWebEngineViewPrivate::QWebEngineViewPrivate()
/*!
\fn QWebEngineView::renderProcessTerminated(QWebEnginePage::RenderProcessTerminationStatus terminationStatus, int exitCode)
+ \since 5.6
This signal is emitted when the render process is terminated with a non-zero exit status.
\a terminationStatus is the termination status of the process and \a exitCode is the status code
@@ -262,7 +264,6 @@ QWebEngineView *QWebEngineView::createWindow(QWebEnginePage::WebWindowType type)
return 0;
}
-
qreal QWebEngineView::zoomFactor() const
{
return page()->zoomFactor();
diff --git a/src/webenginewidgets/api/qwebengineview.h b/src/webenginewidgets/api/qwebengineview.h
index 7181509d2..91410fd2d 100644
--- a/src/webenginewidgets/api/qwebengineview.h
+++ b/src/webenginewidgets/api/qwebengineview.h
@@ -49,6 +49,8 @@
QT_BEGIN_NAMESPACE
class QContextMenuEvent;
+class QPageLayout;
+class QString;
class QUrl;
class QWebEnginePage;
class QWebEngineSettings;
diff --git a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
index 99723c105..e6236ec98 100644
--- a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
+++ b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
@@ -94,8 +94,17 @@
\section1 QWebFrame Has Been Merged into QWebEnginePage
- It is not possible to access sub-frames. Methods of the main QWebFrame are
- now available directly through the QWebEnginePage itself.
+ HTML frames can be used to divide web pages into several areas where the content can be
+ represented individually.
+
+ In Qt WebKit, QWebFrame represents a frame inside a web page. Each QWebPage object contains at
+ least one frame, the main frame, obtained using QWebPage::mainFrame(). Additional frames will
+ be created for the HTML \c <frame> element, which defines the appearance and contents of a
+ single frame, or the \c <iframe> element, which inserts a frame within a block of text.
+
+ In Qt WebEngine, frame handling has been merged into the QWebEnginePage class. All child frames
+ are now considered part of the content, and only accessible through JavaScript. Methods of the
+ QWebFrame class, such as \c load() are now available directly through the QWebEnginePage itself.
\b {Qt WebKit}
\code
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index 2d928b0f5..d6b89cb57 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -30,8 +30,8 @@
\since 5.4
\inmodule QtWebEngineWidgets
- A web engine page holds a main frame responsible for web content, the history
- of navigated links, and actions.
+ A \e {web engine page} holds the contents of an HTML document, the history of navigated
+ links, and actions.
QWebEnginePage's API is very similar to QWebEngineView, as you are still provided with
common functions like action() (known as
@@ -42,7 +42,7 @@
the HTML content readily available, you can use setHtml().
The QWebEnginePage class also offers methods to retrieve both the URL currently
- loaded by its main frame (see url()) as well as the URL originally requested
+ loaded by the page (see url()) as well as the URL originally requested
to be loaded (see requestedUrl()). These methods make possible the retrieval
of the URL before and after a DNS resolution or a redirection occurs during
the load process. The requestedUrl() also matches to the URL added to the
@@ -62,6 +62,22 @@
Its argument, either \c true or \c false, indicates whether or not the load
operation succeeded.
+ An HTML document is loaded in a \e {main frame} within the web page. If it references
+ \e {child frames} (as defined by the \c <frame> or \c <iframe> elements), they are considered
+ part of the content. Child frames are individually accessible only through JavaScript.
+
+ Web sites define \e {security origin} for safely accessing each other's resources for
+ client-side scripting or databases. An origin consist of a host name, a scheme, and a port
+ number. For example, the sites \c http://www.example.com/my/page.html and
+ \c http://www.example.com/my/overview.html are allowed to share the same database or access
+ each other's documents when used in HTML frame sets and JavaScript. At the same time,
+ \c http://www.malicious.com/evil.html is prevented from accessing the resources of
+ \c http://www.example.com/, because they are of a different security origin.
+ By default, local schemes like \c file:// and \c qrc:// are considered to be in the same
+ security origin, and can access each other's resources. Local resources are by default
+ restricted from accessing remote content, which means that \c file:// will not be able to
+ access \c http://domain.com/foo.html.
+
Scripts can be executed on the web page by using runJavaScript(), either in the main
JavaScript \e world, along with the rest of the JavaScript coming from the web contents, or in
their own isolated world. While the DOM of the page can be accessed from any world, JavaScript
@@ -292,7 +308,7 @@
\since 5.5
This function is called upon receiving a request to navigate to the specified \a url by means of
the specified navigation type \a type. \a isMainFrame indicates whether the request corresponds
- to the main frame or a sub frame. If the function returns \c true, the navigation request is
+ to the main frame or a child frame. If the function returns \c true, the navigation request is
accepted and \c url is loaded. The default implementation accepts all navigation requests.
This function is called for absolute URLs that are prefixed with \c {http://} or \c {https://}
@@ -543,14 +559,14 @@
/*!
\property QWebEnginePage::title
- \brief the title of the frame as defined by the HTML &lt;title&gt; element
+ \brief the title of the page as defined by the HTML \c <title> element
\sa titleChanged()
*/
/*!
\property QWebEnginePage::url
- \brief the URL of the frame currently viewed
+ \brief the URL of the page currently viewed
Setting this property clears the view and loads the URL.
@@ -561,14 +577,14 @@
/*!
\property QWebEnginePage::iconUrl
- \brief the URL of the icon associated with the frame currently viewed.
+ \brief the URL of the icon associated with the page currently viewed.
\sa iconUrlChanged()
*/
/*!
\property QWebEnginePage::requestedUrl
- \brief the URL that was originally requested to be loaded by the frame
+ \brief the URL that was originally requested to be loaded by the page
that is currently viewed
\note The URL may differ from the one returned by url(), which is the actual
@@ -579,7 +595,7 @@
/*!
\fn void QWebEnginePage::load(const QUrl &url)
- Loads \a url into this frame.
+ Loads \a url into this page.
\note The view remains the same until enough data has arrived to display the new URL.
@@ -588,7 +604,7 @@
/*!
\fn void QWebEnginePage::setHtml(const QString &html, const QUrl &baseUrl)
- Sets the content of this page's main frame to \a html. \a baseUrl is optional and used to resolve relative
+ Sets the content of this page to \a html. \a baseUrl is optional and used to resolve relative
URLs in the document, such as referenced images or stylesheets.
The \a html is loaded immediately; external objects are loaded asynchronously.
@@ -604,7 +620,7 @@
This is a convenience function equivalent to setContent(html, "text/html", baseUrl).
- \note This method will not affect session or global history for the frame.
+ \note This method will not affect session or global history for the page.
\warning This function works only for HTML, for other mime types (such as XHTML and SVG)
setContent() should be used instead.
@@ -614,7 +630,7 @@
/*!
\fn void QWebEnginePage::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl)
- Sets the content of this page's main frame to the specified content \a data. If the \a mimeType argument
+ Sets the content of this page to \a data. If the \a mimeType argument
is empty, it is currently assumed that the content is HTML but in future versions we may introduce
auto-detection.
@@ -622,14 +638,14 @@
The \a data is loaded immediately; external objects are loaded asynchronously.
- \note This method will not affect session or global history for the frame.
+ \note This method will not affect session or global history for the page.
\sa toHtml(), setHtml()
*/
/*!
\property QWebEnginePage::zoomFactor
- \brief the zoom factor for the main frame
+ \brief the zoom factor for the page content
*/
/*!
@@ -724,7 +740,7 @@
/*!
\fn void QWebEnginePage::titleChanged(const QString &title)
- This signal is emitted whenever the title of the main frame changes.
+ This signal is emitted whenever the title of the page changes.
The \a title string specifies the new title.
\sa title()
@@ -733,7 +749,7 @@
/*!
\fn void QWebEnginePage::urlChanged(const QUrl &url)
- This signal is emitted with the URL of the main frame when the main frame's title is
+ This signal is emitted with the URL of the page when the page title is
received. The new URL is specified by \a url.
\sa url()
@@ -742,7 +758,7 @@
/*!
\fn void QWebEnginePage::iconUrlChanged(const QUrl &url)
- This signal is emitted when the icon ("favicon") associated with the main frame is
+ This signal is emitted when the icon ("favicon") associated with the page is
found or changed. The new URL is specified by \a url.
diff --git a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
index 1ec831ac2..d7ecdb246 100644
--- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
@@ -134,7 +134,8 @@
through the \c charset attribute of the HTML script tag. Alternatively, the
encoding can be specified by the web server.
- This is a convenience function equivalent to setContent(html, "text/html", baseUrl).
+ This is a convenience function equivalent to
+ \c{setContent(html, "text/html;charset=UTF-8", baseUrl)}.
\warning This function works only for HTML. For other MIME types (such as XHTML or SVG),
setContent() should be used instead.
@@ -310,7 +311,7 @@
/*!
\fn void QWebEngineView::titleChanged(const QString &title)
- This signal is emitted whenever the \a title of the main frame changes.
+ This signal is emitted whenever the \a title of the view changes.
\sa title()
*/
@@ -359,10 +360,9 @@
/*!
\fn void QWebEngineView::loadProgress(int progress)
- This signal is emitted every time an element in the web page
- completes loading and the overall loading progress advances.
-
- This signal tracks the progress of all child frames.
+ This signal is emitted every time an element in the web view
+ completes loading, such as an embedded image or a script. Therefore, it
+ tracks the collective progress of loading the web view.
The current value is provided by \a progress and scales from 0 to 100,
which is the default range of QProgressBar.
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
index 90eb0e76e..161983b70 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -86,9 +86,11 @@ RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(Rende
#endif
// Make sure the OpenGL profile of the QOpenGLWidget matches the shared context profile.
- format.setMajorVersion(sharedFormat.majorVersion());
- format.setMinorVersion(sharedFormat.minorVersion());
- format.setProfile(sharedFormat.profile());
+ if (sharedFormat.profile() == QSurfaceFormat::CoreProfile) {
+ format.setMajorVersion(sharedFormat.majorVersion());
+ format.setMinorVersion(sharedFormat.minorVersion());
+ format.setProfile(sharedFormat.profile());
+ }
}
setFormat(format);
diff --git a/tests/auto/quick/inspectorserver/BLACKLIST b/tests/auto/quick/inspectorserver/BLACKLIST
new file mode 100644
index 000000000..f80823bf3
--- /dev/null
+++ b/tests/auto/quick/inspectorserver/BLACKLIST
@@ -0,0 +1,5 @@
+[testRemoteDebuggingMessage]
+osx
+
+[openRemoteDebuggingSession]
+osx
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index 15c1680f9..47d44cd7f 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -230,10 +230,12 @@ static QStringList expectedAPI = QStringList()
<< "QQuickWebEngineDownloadItem.state --> DownloadState"
<< "QQuickWebEngineDownloadItem.totalBytes --> qlonglong"
<< "QQuickWebEngineDownloadItem.receivedBytes --> qlonglong"
+ << "QQuickWebEngineDownloadItem.mimeType --> QString"
<< "QQuickWebEngineDownloadItem.path --> QString"
<< "QQuickWebEngineDownloadItem.stateChanged() --> void"
<< "QQuickWebEngineDownloadItem.receivedBytesChanged() --> void"
<< "QQuickWebEngineDownloadItem.totalBytesChanged() --> void"
+ << "QQuickWebEngineDownloadItem.mimeTypeChanged() --> void"
<< "QQuickWebEngineDownloadItem.pathChanged() --> void"
<< "QQuickWebEngineDownloadItem.accept() --> void"
<< "QQuickWebEngineDownloadItem.cancel() --> void"
@@ -278,7 +280,6 @@ static QStringList expectedAPI = QStringList()
<< "QQuickWebEngineProfile.httpAcceptLanguageChanged() --> void"
<< "QQuickWebEngineProfile.downloadRequested(QQuickWebEngineDownloadItem*) --> void"
<< "QQuickWebEngineProfile.downloadFinished(QQuickWebEngineDownloadItem*) --> void"
- << "QQuickWebEngineProfile.cookieStore() --> QWebEngineCookieStore*"
<< "QQuickWebEngineScript.Deferred --> InjectionPoint"
<< "QQuickWebEngineScript.DocumentReady --> InjectionPoint"
<< "QQuickWebEngineScript.DocumentCreation --> InjectionPoint"
diff --git a/tests/auto/quick/qmltests/BLACKLIST b/tests/auto/quick/qmltests/BLACKLIST
new file mode 100644
index 000000000..3abcd82d0
--- /dev/null
+++ b/tests/auto/quick/qmltests/BLACKLIST
@@ -0,0 +1,9 @@
+[DesktopWebEngineViewLinkHovered::test_linkHovered]
+*
+
+[WebViewGeopermission::test_deniedGeolocationByUser]
+osx
+
+[WebViewGeopermission::test_geoPermissionRequest]
+osx
+windows
diff --git a/tests/auto/quick/qmltests/data/tst_download.qml b/tests/auto/quick/qmltests/data/tst_download.qml
index 6df654ae6..7d1e24b4d 100644
--- a/tests/auto/quick/qmltests/data/tst_download.qml
+++ b/tests/auto/quick/qmltests/data/tst_download.qml
@@ -114,7 +114,7 @@ TestWebEngineView {
compare(downloadState[1], WebEngineDownloadItem.DownloadInProgress)
downloadFinishedSpy.wait()
compare(totalBytes, receivedBytes)
- compare(downloadState[2], WebEngineDownloadItem.DownloadCompleted)
+ tryCompare(downloadState, 2, WebEngineDownloadItem.DownloadCompleted)
}
function test_downloadCancelled() {
diff --git a/tests/auto/quick/qmltests/data/tst_favicon.qml b/tests/auto/quick/qmltests/data/tst_favicon.qml
index fab2e9755..8448960dd 100644
--- a/tests/auto/quick/qmltests/data/tst_favicon.qml
+++ b/tests/auto/quick/qmltests/data/tst_favicon.qml
@@ -56,6 +56,11 @@ TestWebEngineView {
signalName: "iconChanged"
}
+ Image {
+ id: favicon
+ source: webEngineView.icon
+ }
+
TestCase {
id: test
name: "WebEngineFavicon"
@@ -72,16 +77,43 @@ TestWebEngineView {
iconChangedSpy.clear()
}
- function test_noFavicon() {
+ function test_faviconLoad() {
compare(iconChangedSpy.count, 0)
- var url = Qt.resolvedUrl("test1.html")
+ var url = Qt.resolvedUrl("favicon.html")
webEngineView.url = url
verify(webEngineView.waitForLoadSucceeded())
iconChangedSpy.wait()
compare(iconChangedSpy.count, 1)
+ compare(favicon.width, 48)
+ compare(favicon.height, 48)
+ }
+
+ function test_faviconLoadEncodedUrl() {
+ compare(iconChangedSpy.count, 0)
+
+ var url = Qt.resolvedUrl("favicon2.html?favicon=load should work with#whitespace!")
+ webEngineView.url = url
+ verify(webEngineView.waitForLoadSucceeded())
+
+ iconChangedSpy.wait()
+ compare(iconChangedSpy.count, 1)
+
+ compare(favicon.width, 16)
+ compare(favicon.height, 16)
+ }
+
+ function test_noFavicon() {
+ compare(iconChangedSpy.count, 0)
+
+ var url = Qt.resolvedUrl("test1.html")
+ webEngineView.url = url
+ verify(webEngineView.waitForLoadSucceeded())
+
+ compare(iconChangedSpy.count, 0)
+
var iconUrl = webEngineView.icon
compare(iconUrl, Qt.resolvedUrl(""))
}
@@ -93,8 +125,7 @@ TestWebEngineView {
webEngineView.url = url
verify(webEngineView.waitForLoadSucceeded())
- iconChangedSpy.wait()
- compare(iconChangedSpy.count, 1)
+ compare(iconChangedSpy.count, 0)
var iconUrl = webEngineView.icon
compare(iconUrl, Qt.resolvedUrl(""))
@@ -107,11 +138,10 @@ TestWebEngineView {
webEngineView.url = url
verify(webEngineView.waitForLoadSucceeded())
- iconChangedSpy.wait()
- compare(iconChangedSpy.count, 1)
+ compare(iconChangedSpy.count, 0)
var iconUrl = webEngineView.icon
- compare(iconUrl, Qt.resolvedUrl("icons/unavailable.ico"))
+ compare(iconUrl, Qt.resolvedUrl(""))
}
function test_errorPageEnabled() {
@@ -120,14 +150,11 @@ TestWebEngineView {
compare(iconChangedSpy.count, 0)
- var url = Qt.resolvedUrl("http://non.existent/url")
+ var url = Qt.resolvedUrl("invalid://url")
webEngineView.url = url
verify(webEngineView.testSupport.waitForErrorPageLoadSucceeded())
- iconChangedSpy.wait()
- // Icon is reseted at load start.
- // Load is started twice: once for unavailale page then error page
- compare(iconChangedSpy.count, 2)
+ compare(iconChangedSpy.count, 0)
var iconUrl = webEngineView.icon
compare(iconUrl, Qt.resolvedUrl(""))
@@ -138,27 +165,64 @@ TestWebEngineView {
compare(iconChangedSpy.count, 0)
- var url = Qt.resolvedUrl("http://non.existent/url")
+ var url = Qt.resolvedUrl("invalid://url")
webEngineView.url = url
verify(webEngineView.waitForLoadFailed())
- iconChangedSpy.wait()
- compare(iconChangedSpy.count, 1)
+ compare(iconChangedSpy.count, 0)
var iconUrl = webEngineView.icon
compare(iconUrl, Qt.resolvedUrl(""))
}
- function test_touchIcon() {
+ function test_bestFavicon() {
compare(iconChangedSpy.count, 0)
+ var url, iconUrl
- var url = Qt.resolvedUrl("favicon-touch.html")
+ url = Qt.resolvedUrl("favicon-misc.html")
webEngineView.url = url
verify(webEngineView.waitForLoadSucceeded())
iconChangedSpy.wait()
compare(iconChangedSpy.count, 1)
+ iconUrl = webEngineView.icon
+ // Touch icon is ignored
+ compare(iconUrl, Qt.resolvedUrl("icons/qt32.ico"))
+ compare(favicon.width, 32)
+ compare(favicon.height, 32)
+
+ iconChangedSpy.clear()
+
+ url = Qt.resolvedUrl("favicon-shortcut.html")
+ webEngineView.url = url
+ verify(webEngineView.waitForLoadSucceeded())
+
+ iconChangedSpy.wait()
+ verify(iconChangedSpy.count >= 1)
+ iconUrl = webEngineView.icon
+
+ // If the icon URL is empty we have to wait for
+ // the second iconChanged signal that propagates the expected URL
+ if (iconUrl == Qt.resolvedUrl("")) {
+ tryCompare(iconChangedSpy, "count", 2)
+ iconUrl = webEngineView.icon
+ }
+
+ compare(iconUrl, Qt.resolvedUrl("icons/qt144.png"))
+ compare(favicon.width, 144)
+ compare(favicon.height, 144)
+ }
+
+ function test_touchIcon() {
+ compare(iconChangedSpy.count, 0)
+
+ var url = Qt.resolvedUrl("favicon-touch.html")
+ webEngineView.url = url
+ verify(webEngineView.waitForLoadSucceeded())
+
+ compare(iconChangedSpy.count, 0)
+
var iconUrl = webEngineView.icon
compare(iconUrl, Qt.resolvedUrl(""))
}
diff --git a/tests/auto/quick/qmltests/data/tst_faviconImage.qml b/tests/auto/quick/qmltests/data/tst_faviconImage.qml
deleted file mode 100644
index 603f76954..000000000
--- a/tests/auto/quick/qmltests/data/tst_faviconImage.qml
+++ /dev/null
@@ -1,125 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.0
-import QtTest 1.0
-import QtWebEngine 1.3
-
-TestWebEngineView {
- id: webEngineView
- width: 200
- height: 400
-
- SignalSpy {
- id: iconChangedSpy
- target: webEngineView
- signalName: "iconChanged"
- }
-
- Image {
- id: faviconImage
- source: webEngineView.icon
- }
-
- TestCase {
- id: test
- name: "WebEngineFaviconImage"
- when: windowShown
-
- function init() {
- if (webEngineView.icon != '') {
- // If this is not the first test, then load a blank page without favicon, restoring the initial state.
- webEngineView.url = 'about:blank'
- verify(webEngineView.waitForLoadSucceeded())
- iconChangedSpy.wait()
- }
-
- iconChangedSpy.clear()
- }
-
- function test_faviconImageLoad() {
- compare(iconChangedSpy.count, 0)
-
- var url = Qt.resolvedUrl("favicon.html")
- webEngineView.url = url
- verify(webEngineView.waitForLoadSucceeded())
-
- iconChangedSpy.wait()
- compare(iconChangedSpy.count, 1)
-
- compare(faviconImage.width, 48)
- compare(faviconImage.height, 48)
- }
-
- function test_faviconImageLoadEncodedUrl() {
- compare(iconChangedSpy.count, 0)
-
- var url = Qt.resolvedUrl("favicon2.html?favicon=load should work with#whitespace!")
- webEngineView.url = url
- verify(webEngineView.waitForLoadSucceeded())
-
- iconChangedSpy.wait()
- compare(iconChangedSpy.count, 1)
-
- compare(faviconImage.width, 16)
- compare(faviconImage.height, 16)
- }
-
- function test_bestFaviconImage() {
- compare(iconChangedSpy.count, 0)
- var url, iconUrl
-
- url = Qt.resolvedUrl("favicon-misc.html")
- webEngineView.url = url
- verify(webEngineView.waitForLoadSucceeded())
-
- iconChangedSpy.wait()
- compare(iconChangedSpy.count, 1)
-
- iconUrl = webEngineView.icon
- // Touch icon is ignored
- compare(iconUrl, Qt.resolvedUrl("icons/qt32.ico"))
- compare(faviconImage.width, 32)
- compare(faviconImage.height, 32)
-
- iconChangedSpy.clear()
-
- url = Qt.resolvedUrl("favicon-shortcut.html")
- webEngineView.url = url
- verify(webEngineView.waitForLoadSucceeded())
-
- iconChangedSpy.wait()
- compare(iconChangedSpy.count, 1)
-
- iconUrl = webEngineView.icon
- compare(iconUrl, Qt.resolvedUrl("icons/qt144.png"))
- compare(faviconImage.width, 144)
- compare(faviconImage.height, 144)
- }
- }
-}
diff --git a/tests/auto/quick/qmltests/data/tst_geopermission.qml b/tests/auto/quick/qmltests/data/tst_geopermission.qml
index 1d4703e95..5e5e1a321 100644
--- a/tests/auto/quick/qmltests/data/tst_geopermission.qml
+++ b/tests/auto/quick/qmltests/data/tst_geopermission.qml
@@ -37,7 +37,7 @@ TestWebEngineView {
property bool deniedGeolocation: false
property bool geoPermissionRequested: false
- property string consoleErrorMessage: ""
+ signal consoleErrorMessage(string message)
SignalSpy {
id: featurePermissionSpy
@@ -45,6 +45,12 @@ TestWebEngineView {
signalName: "featurePermissionRequested"
}
+ SignalSpy {
+ id: consoleErrorMessageSpy
+ target: webEngineView
+ signalName: "consoleErrorMessage"
+ }
+
onFeaturePermissionRequested: {
if (feature === WebEngineView.Geolocation) {
geoPermissionRequested = true
@@ -59,7 +65,7 @@ TestWebEngineView {
onJavaScriptConsoleMessage: {
if (level === WebEngineView.ErrorMessageLevel)
- consoleErrorMessage = message
+ consoleErrorMessage(message)
}
TestCase {
@@ -68,8 +74,8 @@ TestWebEngineView {
function init() {
deniedGeolocation = false
- consoleErrorMessage = ""
featurePermissionSpy.clear()
+ consoleErrorMessageSpy.clear()
}
function test_geoPermissionRequest() {
@@ -78,15 +84,16 @@ TestWebEngineView {
featurePermissionSpy.wait()
verify(geoPermissionRequested)
compare(featurePermissionSpy.count, 1)
- if (consoleErrorMessage) // Print the error message if it fails to get user's location
- fail(consoleErrorMessage)
+ if (consoleErrorMessageSpy.count) // Print the error message if it fails to get user's location
+ fail(consoleErrorMessageSpy.signalArguments[0][0])
}
function test_deniedGeolocationByUser() {
deniedGeolocation = true
webEngineView.url = Qt.resolvedUrl("geolocation.html")
featurePermissionSpy.wait()
- compare(consoleErrorMessage, "User denied Geolocation")
+ consoleErrorMessageSpy.wait()
+ compare(consoleErrorMessageSpy.signalArguments[0][0], "User denied Geolocation")
}
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml b/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml
index 7d0cc47b4..117df5776 100644
--- a/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml
+++ b/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml
@@ -110,6 +110,7 @@ TestWebEngineView {
webEngineView.reload()
verify(webEngineView.waitForLoadSucceeded())
compare(JSDialogParams.dialogCount, 2)
+ expectFail("", "QTBUG-51749")
compare(webEngineView.title, "prompt.html")
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml b/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml
index ae60e5f5e..86fb9281c 100644
--- a/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml
+++ b/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml
@@ -53,6 +53,7 @@ TestWebEngineView {
}
function test_keyboardModifierMapping() {
+ skip("runJavaScript bug: QTBUG-51746")
webEngineView.url = Qt.resolvedUrl("keyboardModifierMapping.html")
waitForLoadSucceeded();
titleSpy.wait()
diff --git a/tests/auto/quick/qmltests/data/tst_loadFail.qml b/tests/auto/quick/qmltests/data/tst_loadFail.qml
index 0da9e841b..9b18870e4 100644
--- a/tests/auto/quick/qmltests/data/tst_loadFail.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadFail.qml
@@ -140,7 +140,7 @@ TestWebEngineView {
verify(loadRequest.isErrorPage)
compare(webEngineView.url, unavailableUrl)
- compare(webEngineView.title, unavailableUrl + " is not found")
+ compare(webEngineView.title, unavailableUrl + " failed to load")
}
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_runJavaScript.qml b/tests/auto/quick/qmltests/data/tst_runJavaScript.qml
index beeebc049..2011d2a5c 100644
--- a/tests/auto/quick/qmltests/data/tst_runJavaScript.qml
+++ b/tests/auto/quick/qmltests/data/tst_runJavaScript.qml
@@ -44,6 +44,7 @@ TestWebEngineView {
TestCase {
name: "WebEngineViewRunJavaScript"
function test_runJavaScript() {
+ skip("runJavaScript bug: QTBUG-51746")
var testTitle = "Title to test runJavaScript";
runJavaScript("document.title = \"" + testTitle +"\"");
_waitFor(function() { spy.count > 0; });
diff --git a/tests/auto/quick/qmltests/qmltests.pro b/tests/auto/quick/qmltests/qmltests.pro
index d1849d020..d3307a339 100644
--- a/tests/auto/quick/qmltests/qmltests.pro
+++ b/tests/auto/quick/qmltests/qmltests.pro
@@ -39,7 +39,6 @@ OTHER_FILES += \
$$PWD/data/tst_desktopBehaviorLoadHtml.qml \
$$PWD/data/tst_download.qml \
$$PWD/data/tst_favicon.qml \
- $$PWD/data/tst_faviconImage.qml \
$$PWD/data/tst_filePicker.qml \
$$PWD/data/tst_formValidation.qml \
$$PWD/data/tst_geopermission.qml \
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index a1900a77d..f2f5b31f9 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -60,6 +60,7 @@ private Q_SLOTS:
void inputMethod();
void inputMethodHints();
void basicRenderingSanity();
+ void printToPdf();
private:
inline QQuickWebEngineView *newWebEngineView();
@@ -461,5 +462,28 @@ void tst_QQuickWebEngineView::inputMethodHints()
#endif
}
+void tst_QQuickWebEngineView::printToPdf()
+{
+ QTemporaryDir tempDir(QDir::tempPath() + "/tst_qwebengineview-XXXXXX");
+ QVERIFY(tempDir.isValid());
+ QQuickWebEngineView *view = webEngineView();
+ view->setUrl(urlFromTestPath("html/basic_page.html"));
+ QVERIFY(waitForLoadSucceeded(view));
+
+ QString path = tempDir.path() + "/print_success.pdf";
+ view->printToPdf(path, QQuickWebEngineView::A4, QQuickWebEngineView::Portrait);
+ QTest::qWait(500);
+ QVERIFY(QFile::exists(path));
+
+#if !defined(Q_OS_WIN)
+ path = tempDir.path() + "/print_//fail.pdf";
+#else
+ path = tempDir.path() + "/print_|fail.pdf";
+#endif // #if !defined(Q_OS_WIN)
+ view->printToPdf(path, QQuickWebEngineView::A4, QQuickWebEngineView::Portrait);
+ QTest::qWait(500);
+ QVERIFY(!QFile::exists(path));
+}
+
QTEST_MAIN(tst_QQuickWebEngineView)
#include "tst_qquickwebengineview.moc"
diff --git a/tests/auto/quick/qquickwebengineviewgraphics/qquickwebengineviewgraphics.pro b/tests/auto/quick/qquickwebengineviewgraphics/qquickwebengineviewgraphics.pro
index cbd11cdca..9471def00 100644
--- a/tests/auto/quick/qquickwebengineviewgraphics/qquickwebengineviewgraphics.pro
+++ b/tests/auto/quick/qquickwebengineviewgraphics/qquickwebengineviewgraphics.pro
@@ -1,3 +1,4 @@
include(../tests.pri)
+CONFIG -= testcase # remove, once this passes in the CI
exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc
QT_PRIVATE += webengine-private
diff --git a/tests/auto/quick/tests.pri b/tests/auto/quick/tests.pri
index 56eee7199..3c56aef97 100644
--- a/tests/auto/quick/tests.pri
+++ b/tests/auto/quick/tests.pri
@@ -1,8 +1,6 @@
TEMPLATE = app
-# FIXME: Re-enable once we want to run tests on the CI
-# CONFIG += testcase
-
+CONFIG += testcase
CONFIG += c++11
VPATH += $$_PRO_FILE_PWD_
diff --git a/tests/auto/widgets/positionplugin/positionplugin.pro b/tests/auto/widgets/positionplugin/positionplugin.pro
index bca3e5756..6f2e736c6 100644
--- a/tests/auto/widgets/positionplugin/positionplugin.pro
+++ b/tests/auto/widgets/positionplugin/positionplugin.pro
@@ -1,12 +1,13 @@
TARGET = qtwebengine_positioning_testplugin
-QT += positioning
-PLUGIN_TYPE = position
-PLUGIN_CLASS_NAME = TestPositionPlugin
-PLUGIN_EXTENDS = -
-load(qt_plugin)
+QT += positioning
SOURCES += plugin.cpp
OTHER_FILES += \
plugin.json
+
+PLUGIN_TYPE = position
+PLUGIN_CLASS_NAME = TestPositionPlugin
+PLUGIN_EXTENDS = -
+load(qt_plugin)
diff --git a/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp b/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp
index 016c4f98c..63ca25396 100644
--- a/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp
+++ b/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp
@@ -112,9 +112,9 @@ void tst_QWebEngineView::hierarchy()
QCOMPARE(text->parent(), grouping);
QCOMPARE(grouping->indexOfChild(text), 0);
QCOMPARE(text->childCount(), 0);
- QCOMPARE(text->text(QAccessible::Name), QString());
+ QCOMPARE(text->text(QAccessible::Name), QStringLiteral("Hello world"));
QCOMPARE(text->text(QAccessible::Description), QString());
- QCOMPARE(text->text(QAccessible::Value), QStringLiteral("Hello world"));
+ QCOMPARE(text->text(QAccessible::Value), QString());
QAccessibleInterface *input = grouping->child(1);
QCOMPARE(input->role(), QAccessible::EditableText);
@@ -182,9 +182,9 @@ void tst_QWebEngineView::text()
QAccessibleInterface *grouping2 = document->child(1);
QAccessibleInterface *label1 = grouping2->child(0);
QCOMPARE(label1->role(), QAccessible::StaticText);
- QCOMPARE(label1->text(QAccessible::Name), QString());
+ QCOMPARE(label1->text(QAccessible::Name), QStringLiteral("Enter your name here:"));
QCOMPARE(label1->text(QAccessible::Description), QString());
- QCOMPARE(label1->text(QAccessible::Value), QStringLiteral("Enter your name here:"));
+ QCOMPARE(label1->text(QAccessible::Value), QString());
QAccessibleInterface *grouping3 = document->child(2);
QAccessibleInterface *input2 = grouping3->child(0);
QCOMPARE(input2->role(), QAccessible::EditableText);
@@ -194,9 +194,9 @@ void tst_QWebEngineView::text()
QAccessibleInterface *grouping4 = document->child(3);
QAccessibleInterface *label2 = grouping4->child(0);
QCOMPARE(label2->role(), QAccessible::StaticText);
- QCOMPARE(label2->text(QAccessible::Name), QString());
+ QCOMPARE(label2->text(QAccessible::Name), QStringLiteral("Provide both first and last name."));
QCOMPARE(label2->text(QAccessible::Description), QString());
- QCOMPARE(label2->text(QAccessible::Value), QStringLiteral("Provide both first and last name."));
+ QCOMPARE(label2->text(QAccessible::Value), QString());
// Good day! [edit]
QAccessibleInterface *grouping5 = document->child(4);
diff --git a/tests/auto/widgets/qwebenginedefaultsurfaceformat/tst_qwebenginedefaultsurfaceformat.cpp b/tests/auto/widgets/qwebenginedefaultsurfaceformat/tst_qwebenginedefaultsurfaceformat.cpp
index e42a8a75e..3757a7842 100644
--- a/tests/auto/widgets/qwebenginedefaultsurfaceformat/tst_qwebenginedefaultsurfaceformat.cpp
+++ b/tests/auto/widgets/qwebenginedefaultsurfaceformat/tst_qwebenginedefaultsurfaceformat.cpp
@@ -51,6 +51,9 @@ private Q_SLOTS:
void tst_QWebEngineDefaultSurfaceFormat::customDefaultSurfaceFormat()
{
+#if defined(Q_OS_WIN)
+ QSKIP("Crashes on Windows");
+#endif
// Setting a new default QSurfaceFormat with a core OpenGL profile before
// app instantiation should succeed, without abort() being called.
int argc = 1;
diff --git a/tests/auto/widgets/qwebenginefaviconmanager/tst_qwebenginefaviconmanager.cpp b/tests/auto/widgets/qwebenginefaviconmanager/tst_qwebenginefaviconmanager.cpp
index f435288f7..a0f864a6f 100644
--- a/tests/auto/widgets/qwebenginefaviconmanager/tst_qwebenginefaviconmanager.cpp
+++ b/tests/auto/widgets/qwebenginefaviconmanager/tst_qwebenginefaviconmanager.cpp
@@ -105,7 +105,7 @@ void tst_QWebEngineFaviconManager::faviconLoadFromResources()
QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
- QUrl url = QUrl("qrc:/resources/favicon-single.html");
+ QUrl url("qrc:/resources/favicon-single.html");
m_page->load(url);
QTRY_COMPARE(loadFinishedSpy.count(), 1);
@@ -124,7 +124,7 @@ void tst_QWebEngineFaviconManager::faviconLoadEncodedUrl()
QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
QString urlString = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginefaviconmanager/resources/favicon-single.html")).toString();
- QUrl url = QUrl(urlString + QLatin1String("?favicon=load should work with#whitespace!"));
+ QUrl url(urlString + QLatin1String("?favicon=load should work with#whitespace!"));
m_page->load(url);
QTRY_COMPARE(loadFinishedSpy.count(), 1);
@@ -157,11 +157,11 @@ void tst_QWebEngineFaviconManager::aboutBlank()
QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
- QUrl url = QUrl("about:blank");
+ QUrl url("about:blank");
m_page->load(url);
QTRY_COMPARE(loadFinishedSpy.count(), 1);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 0);
+ QCOMPARE(iconUrlChangedSpy.count(), 0);
QVERIFY(m_page->iconUrl().isEmpty());
}
@@ -178,11 +178,9 @@ void tst_QWebEngineFaviconManager::unavailableFavicon()
m_page->load(url);
QTRY_COMPARE(loadFinishedSpy.count(), 1);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
+ QCOMPARE(iconUrlChangedSpy.count(), 0);
- QUrl iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
- QCOMPARE(m_page->iconUrl(), iconUrl);
- QCOMPARE(iconUrl, QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginefaviconmanager/resources/icons/unavailable.ico")));
+ QVERIFY(m_page->iconUrl().isEmpty());
}
void tst_QWebEngineFaviconManager::errorPageEnabled()
@@ -192,7 +190,7 @@ void tst_QWebEngineFaviconManager::errorPageEnabled()
QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
- QUrl url = QUrl(QUrl("http://non.existent/url"));
+ QUrl url("invalid://url");
m_page->load(url);
QTRY_COMPARE(loadFinishedSpy.count(), 1);
@@ -208,7 +206,7 @@ void tst_QWebEngineFaviconManager::errorPageDisabled()
QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
- QUrl url = QUrl(QUrl("http://non.existent/url"));
+ QUrl url("invalid://url");
m_page->load(url);
QTRY_COMPARE(loadFinishedSpy.count(), 1);
@@ -246,6 +244,14 @@ void tst_QWebEngineFaviconManager::bestFavicon()
QTRY_VERIFY(iconUrlChangedSpy.count() >= 1);
iconUrl = iconUrlChangedSpy.last().at(0).toString();
+
+ // If the icon URL is empty we have to wait for
+ // the second iconChanged signal that propagates the expected URL
+ if (iconUrl.isEmpty()) {
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 2);
+ iconUrl = iconUrlChangedSpy.last().at(0).toString();
+ }
+
QCOMPARE(iconUrl, QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginefaviconmanager/resources/icons/qt144.png")));
}
diff --git a/tests/auto/widgets/qwebenginepage/BLACKLIST b/tests/auto/widgets/qwebenginepage/BLACKLIST
index 91858f299..d4481dc3f 100644
--- a/tests/auto/widgets/qwebenginepage/BLACKLIST
+++ b/tests/auto/widgets/qwebenginepage/BLACKLIST
@@ -3,3 +3,6 @@
[macCopyUnicodeToClipboard]
osx
+
+[getUserMediaRequest]
+windows
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 690cf70e4..8b93c7169 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -20,6 +20,7 @@
*/
#include "../util.h"
+#include <QByteArray>
#include <QClipboard>
#include <QDir>
#include <QGraphicsWidget>
@@ -128,7 +129,6 @@ private Q_SLOTS:
void modified();
void contextMenuCrash();
void updatePositionDependentActionsCrash();
- void database();
void createPluginWithPluginsEnabled();
void createPluginWithPluginsDisabled();
void destroyPlugin_data();
@@ -159,8 +159,6 @@ private Q_SLOTS:
void renderWidgetHostViewNotShowTopLevel();
void getUserMediaRequest();
- void viewModes();
-
void crashTests_LazyInitializationOfMainFrame();
void screenshot_data();
@@ -213,10 +211,6 @@ private Q_SLOTS:
void setHtmlWithStylesheetResource();
void setHtmlWithBaseURL();
void setHtmlWithJSAlert();
- void metaData();
-#if !defined(QT_NO_COMBOBOX)
- void popupFocus();
-#endif
void inputFieldFocus();
void hitTestContent();
void baseUrl_data();
@@ -241,6 +235,10 @@ private Q_SLOTS:
void loadInSignalHandlers();
void restoreHistory();
+ void toPlainTextLoadFinishedRace_data();
+ void toPlainTextLoadFinishedRace();
+
+ void printToPdf();
private:
QWebEngineView* m_view;
@@ -669,25 +667,6 @@ void tst_QWebEnginePage::loadHtml5Video()
#endif
}
-void tst_QWebEnginePage::viewModes()
-{
-#if !defined(QWEBENGINEPAGE_VIEW_MODES)
- QSKIP("QWEBENGINEPAGE_VIEW_MODES");
-#else
- m_view->setHtml("<body></body>");
- m_page->setProperty("_q_viewMode", "minimized");
-
- QVariant empty = evaluateJavaScriptSync(m_page, "window.styleMedia.matchMedium(\"(-webengine-view-mode)\")");
- QVERIFY(empty.type() == QVariant::Bool && empty.toBool());
-
- QVariant minimized = evaluateJavaScriptSync(m_page, "window.styleMedia.matchMedium(\"(-webengine-view-mode: minimized)\")");
- QVERIFY(minimized.type() == QVariant::Bool && minimized.toBool());
-
- QVariant maximized = evaluateJavaScriptSync(m_page, "window.styleMedia.matchMedium(\"(-webengine-view-mode: maximized)\")");
- QVERIFY(maximized.type() == QVariant::Bool && !maximized.toBool());
-#endif
-}
-
void tst_QWebEnginePage::modified()
{
#if !defined(QWEBENGINEPAGE_ISMODIFIED)
@@ -790,64 +769,6 @@ void tst_QWebEnginePage::contextMenuCrash()
#endif
}
-void tst_QWebEnginePage::database()
-{
-#if !defined(QWEBENGINEDATABASE)
- QSKIP("QWEBENGINEDATABASE");
-#else
- QString path = tmpDirPath();
- m_page->settings()->setOfflineStoragePath(path);
- QVERIFY(m_page->settings()->offlineStoragePath() == path);
-
- QWebEngineSettings::setOfflineStorageDefaultQuota(1024 * 1024);
- QVERIFY(QWebEngineSettings::offlineStorageDefaultQuota() == 1024 * 1024);
-
- m_page->settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true);
- m_page->settings()->setAttribute(QWebEngineSettings::OfflineStorageDatabaseEnabled, true);
-
- QString dbFileName = path + "Databases.db";
-
- if (QFile::exists(dbFileName))
- QFile::remove(dbFileName);
-
- qRegisterMetaType<QWebEngineFrame*>("QWebEngineFrame*");
- QSignalSpy spy(m_page, SIGNAL(databaseQuotaExceeded(QWebEngineFrame*,QString)));
- m_view->setHtml(QString("<html><head><script>var db; db=openDatabase('testdb', '1.0', 'test database API', 50000); </script></head><body><div></div></body></html>"), QUrl("http://www.myexample.com"));
- QTRY_COMPARE(spy.count(), 1);
- evaluateJavaScriptSync(m_page, "var db2; db2=openDatabase('testdb', '1.0', 'test database API', 50000);");
- QTRY_COMPARE(spy.count(),1);
-
- evaluateJavaScriptSync(m_page, "localStorage.test='This is a test for local storage';");
- m_view->setHtml(QString("<html><body id='b'>text</body></html>"), QUrl("http://www.myexample.com"));
-
- QVariant s1 = evaluateJavaScriptSync(m_page, "localStorage.test");
- QCOMPARE(s1.toString(), QString("This is a test for local storage"));
-
- evaluateJavaScriptSync(m_page, "sessionStorage.test='This is a test for session storage';");
- m_view->setHtml(QString("<html><body id='b'>text</body></html>"), QUrl("http://www.myexample.com"));
- QVariant s2 = evaluateJavaScriptSync(m_page, "sessionStorage.test");
- QCOMPARE(s2.toString(), QString("This is a test for session storage"));
-
- m_view->setHtml(QString("<html><head></head><body><div></div></body></html>"), QUrl("http://www.myexample.com"));
- evaluateJavaScriptSync(m_page, "var db3; db3=openDatabase('testdb', '1.0', 'test database API', 50000);db3.transaction(function(tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS Test (text TEXT)', []); }, function(tx, result) { }, function(tx, error) { });");
- QTest::qWait(200);
-
- // Remove all databases.
- QWebEngineSecurityOrigin origin = m_page->mainFrame()->securityOrigin();
- QList<QWebEngineDatabase> dbs = origin.databases();
- for (int i = 0; i < dbs.count(); i++) {
- QString fileName = dbs[i].fileName();
- QVERIFY(QFile::exists(fileName));
- QWebEngineDatabase::removeDatabase(dbs[i]);
- QVERIFY(!QFile::exists(fileName));
- }
- QVERIFY(!origin.databases().size());
- // Remove removed test :-)
- QWebEngineDatabase::removeAllDatabases();
- QVERIFY(!origin.databases().size());
-#endif
-}
-
#if defined(QWEBENGINEPAGE_CREATEPLUGIN)
class PluginPage : public QWebEnginePage
{
@@ -3388,9 +3309,9 @@ void tst_QWebEnginePage::loadSignalsOrder()
QFETCH(QUrl, url);
QWebEnginePage page;
SpyForLoadSignalsOrder loadSpy(&page);
- waitForSignal(&loadSpy, SIGNAL(started()));
+ waitForSignal(&loadSpy, SIGNAL(started()), 500);
page.load(url);
- QTRY_VERIFY(loadSpy.isFinished());
+ QTRY_VERIFY_WITH_TIMEOUT(loadSpy.isFinished(), 500);
}
void tst_QWebEnginePage::undoActionHaveCustomText()
@@ -4157,90 +4078,6 @@ void tst_QWebEnginePage::setHtmlWithJSAlert()
QCOMPARE(toHtmlSync(&page), html);
}
-void tst_QWebEnginePage::metaData()
-{
-#if !defined(QWEBENGINEPAGE_METADATA)
- QSKIP("QWEBENGINEPAGE_METADATA");
-#else
- m_view->setHtml("<html>"
- " <head>"
- " <meta name=\"description\" content=\"Test description\">"
- " <meta name=\"keywords\" content=\"HTML, JavaScript, Css\">"
- " </head>"
- "</html>");
-
- QMultiMap<QString, QString> metaData = m_view->page()->metaData();
-
- QCOMPARE(metaData.count(), 2);
-
- QCOMPARE(metaData.value("description"), QString("Test description"));
- QCOMPARE(metaData.value("keywords"), QString("HTML, JavaScript, Css"));
- QCOMPARE(metaData.value("nonexistent"), QString());
-
- m_view->setHtml("<html>"
- " <head>"
- " <meta name=\"samekey\" content=\"FirstValue\">"
- " <meta name=\"samekey\" content=\"SecondValue\">"
- " </head>"
- "</html>");
-
- metaData = m_view->page()->metaData();
-
- QCOMPARE(metaData.count(), 2);
-
- QStringList values = metaData.values("samekey");
- QCOMPARE(values.count(), 2);
-
- QVERIFY(values.contains("FirstValue"));
- QVERIFY(values.contains("SecondValue"));
-
- QCOMPARE(metaData.value("nonexistent"), QString());
-#endif
-}
-
-#if !defined(QT_NO_COMBOBOX)
-void tst_QWebEnginePage::popupFocus()
-{
-#if !defined(QWEBENGINEELEMENT)
- QSKIP("QWEBENGINEELEMENT");
-#else
- QWebEngineView view;
- view.setHtml("<html>"
- " <body>"
- " <select name=\"select\">"
- " <option>1</option>"
- " <option>2</option>"
- " </select>"
- " <input type=\"text\"> </input>"
- " <textarea name=\"text_area\" rows=\"3\" cols=\"40\">"
- "This test checks whether showing and hiding a popup"
- "takes the focus away from the webpage."
- " </textarea>"
- " </body>"
- "</html>");
- view.resize(400, 100);
- // Call setFocus before show to work around http://bugreports.qt.nokia.com/browse/QTBUG-14762
- view.setFocus();
- view.show();
- QTest::qWaitForWindowExposed(&view);
- view.activateWindow();
- QTRY_VERIFY(view.hasFocus());
-
- // open the popup by clicking. check if focus is on the popup
- const QWebEngineElement webCombo = view.page()->documentElement().findFirst(QLatin1String("select[name=select]"));
- QTest::mouseClick(&view, Qt::LeftButton, 0, webCombo.geometry().center());
-
- QComboBox* combo = view.findChild<QComboBox*>();
- QVERIFY(combo != 0);
- QTRY_VERIFY(!view.hasFocus() && combo->view()->hasFocus()); // Focus should be on the popup
-
- // hide the popup and check if focus is on the page
- combo->hidePopup();
- QTRY_VERIFY(view.hasFocus()); // Focus should be back on the WebView
-#endif
-}
-#endif
-
void tst_QWebEnginePage::inputFieldFocus()
{
#if !defined(QWEBENGINEELEMENT)
@@ -5115,5 +4952,67 @@ void tst_QWebEnginePage::restoreHistory()
delete channel;
}
+void tst_QWebEnginePage::toPlainTextLoadFinishedRace_data()
+{
+ QTest::addColumn<bool>("enableErrorPage");
+ QTest::newRow("disableErrorPage") << false;
+ QTest::newRow("enableErrorPage") << true;
+}
+
+void tst_QWebEnginePage::toPlainTextLoadFinishedRace()
+{
+ QFETCH(bool, enableErrorPage);
+
+ QWebEnginePage *page = new QWebEnginePage;
+ page->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, enableErrorPage);
+ QSignalSpy spy(page, SIGNAL(loadFinished(bool)));
+
+ page->load(QUrl("data:text/plain,foobarbaz"));
+ QTRY_VERIFY(spy.count() == 1);
+ QCOMPARE(toPlainTextSync(page), QString("foobarbaz"));
+
+ page->load(QUrl("fail:unknown/scheme"));
+ QTRY_VERIFY(spy.count() == 2);
+ QString s = toPlainTextSync(page);
+ QVERIFY(s.contains("foobarbaz") == !enableErrorPage);
+
+ page->load(QUrl("data:text/plain,lalala"));
+ QTRY_VERIFY(spy.count() == 3);
+ QCOMPARE(toPlainTextSync(page), QString("lalala"));
+ delete page;
+ QVERIFY(spy.count() == 3);
+}
+
+void tst_QWebEnginePage::printToPdf()
+{
+ QTemporaryDir tempDir(QDir::tempPath() + "/tst_qwebengineview-XXXXXX");
+ QVERIFY(tempDir.isValid());
+ QWebEnginePage page;
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+ page.load(QUrl("qrc:///resources/basic_printing_page.html"));
+ QTRY_VERIFY(spy.count() == 1);
+
+ QPageLayout layout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0.0, 0.0, 0.0, 0.0));
+ QString path = tempDir.path() + "/print_1_success.pdf";
+ page.printToPdf(path, layout);
+ QTRY_VERIFY(QFile::exists(path));
+
+#if !defined(Q_OS_WIN)
+ path = tempDir.path() + "/print_//2_failed.pdf";
+#else
+ path = tempDir.path() + "/print_|2_failed.pdf";
+#endif
+ page.printToPdf(path, QPageLayout());
+ QTRY_VERIFY(!QFile::exists(path));
+
+ CallbackSpy<QByteArray> successfulSpy;
+ page.printToPdf(layout, successfulSpy.ref());
+ QTRY_VERIFY(successfulSpy.waitForResult().length() > 0);
+
+ CallbackSpy<QByteArray> failedInvalidLayoutSpy;
+ page.printToPdf(QPageLayout(), failedInvalidLayoutSpy.ref());
+ QTRY_VERIFY(!failedInvalidLayoutSpy.waitForResult().length() > 0);
+}
+
QTEST_MAIN(tst_QWebEnginePage)
#include "tst_qwebenginepage.moc"
diff --git a/tests/auto/widgets/qwebengineprofile/BLACKLIST b/tests/auto/widgets/qwebengineprofile/BLACKLIST
new file mode 100644
index 000000000..fc1c957dd
--- /dev/null
+++ b/tests/auto/widgets/qwebengineprofile/BLACKLIST
@@ -0,0 +1,5 @@
+[clearDataFromCache]
+*
+[disableCache]
+*
+
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index 26980df7b..e73ab637b 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -247,9 +247,10 @@ void tst_QWebEngineProfile::urlSchemeHandlerFailRequest()
QWebEngineView view;
QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
view.setPage(new QWebEnginePage(&profile, &view));
+ view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
view.load(QUrl(QStringLiteral("foo://bar")));
QVERIFY(loadFinishedSpy.wait());
- QVERIFY(toPlainTextSync(view.page()).isEmpty());
+ QCOMPARE(toPlainTextSync(view.page()), QString());
}
QTEST_MAIN(tst_QWebEngineProfile)
diff --git a/tests/auto/widgets/qwebengineview/resources/basic_printing_page.html b/tests/auto/widgets/qwebengineview/resources/basic_printing_page.html
new file mode 100644
index 000000000..0c6ff379f
--- /dev/null
+++ b/tests/auto/widgets/qwebengineview/resources/basic_printing_page.html
@@ -0,0 +1,8 @@
+<html>
+<head>
+<title> Basic Printing Page </title>
+</head>
+<body>
+<h1>Hello Paper World</h1>
+</body>
+</html>
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 1ebb22cc9..773550922 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -23,11 +23,13 @@
#include "../util.h"
#include <qpainter.h>
+#include <qpagelayout.h>
#include <qwebengineview.h>
#include <qwebenginepage.h>
#include <qwebenginesettings.h>
#include <qnetworkrequest.h>
#include <qdiriterator.h>
+#include <qtemporarydir.h>
#define VERIFY_INPUTMETHOD_HINTS(actual, expect) \
QVERIFY(actual == expect);
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc b/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc
index 6685a8086..b32b533c2 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc
@@ -1,8 +1,9 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource>
- <file>resources/index.html</file>
- <file>resources/frame_a.html</file>
- <file>resources/input_types.html</file>
- <file>resources/scrolltest_page.html</file>
-</qresource>
+<RCC>
+ <qresource prefix="/">
+ <file>resources/index.html</file>
+ <file>resources/frame_a.html</file>
+ <file>resources/input_types.html</file>
+ <file>resources/scrolltest_page.html</file>
+ <file>resources/basic_printing_page.html</file>
+ </qresource>
</RCC>
diff --git a/tools/qmake/mkspecs/features/configure.prf b/tools/qmake/mkspecs/features/configure.prf
index 5674ea3a5..7703e3414 100644
--- a/tools/qmake/mkspecs/features/configure.prf
+++ b/tools/qmake/mkspecs/features/configure.prf
@@ -41,10 +41,16 @@ defineTest(runConfigure) {
else: log("System libwebp or libwebpdemux not found. Using Chromium's copies.$${EOL}")
packagesExist(libxml-2.0,libxslt): WEBENGINE_CONFIG += use_system_libxslt
else: log("System libxml2 or libxslt not found. Using Chromium's copies.$${EOL}")
- for(package, $$list("libevent jsoncpp opus")) {
+ for(package, $$list("libevent jsoncpp opus protobuf")) {
packagesExist($$package): WEBENGINE_CONFIG += use_system_$$package
else: log("System $$package not found. Using Chromium's copy.$${EOL}")
}
+ use?(system_protobuf) {
+ !system("which protoc > /dev/null") {
+ log("Protobuf compiler not found. Using Chromium's copy of protobuf.$${EOL}")
+ WEBENGINE_CONFIG -= use_system_protobuf
+ }
+ }
config_libvpx: WEBENGINE_CONFIG += use_system_vpx
else: log("Compatible system libvpx not found. Using Chromium's copy.$${EOL}")
config_srtp: WEBENGINE_CONFIG += use_system_libsrtp
@@ -107,5 +113,12 @@ defineTest(finalizeConfigure) {
} else {
log("Proprietary codecs (H264, MP3).... Not enabled (Default, enable with WEBENGINE_CONFIG += use_proprietary_codecs)$${EOL}")
}
+ osx {
+ use?(appstore_compliant_code) {
+ log("AppStore Compliant ............... Enabled$${EOL}")
+ } else {
+ log("AppStore Compliant ............... Not enabled (Default, enable with WEBENGINE_CONFIG += use_appstore_compliant_code)$${EOL}")
+ }
+ }
}
diff --git a/tools/qmake/mkspecs/features/default_pre.prf b/tools/qmake/mkspecs/features/default_pre.prf
index 6506e67ad..cb0625c2e 100644
--- a/tools/qmake/mkspecs/features/default_pre.prf
+++ b/tools/qmake/mkspecs/features/default_pre.prf
@@ -19,6 +19,9 @@ load(functions)
equals(_PRO_FILE_, "$$QTWEBENGINE_ROOT/qtwebengine.pro"): CONFIG += root_project_file
root_project_file:isPlatformSupported() {
+ !exists($$QTWEBENGINE_ROOT/src/3rdparty/chromium) {
+ error("Submodule qtwebengine-chromium does not exist. Run 'git submodule update --init'.")
+ }
load(configure)
runConfigure()
}
diff --git a/tools/qmake/mkspecs/features/functions.prf b/tools/qmake/mkspecs/features/functions.prf
index 2df689bca..26db26f44 100644
--- a/tools/qmake/mkspecs/features/functions.prf
+++ b/tools/qmake/mkspecs/features/functions.prf
@@ -19,6 +19,9 @@ defineTest(isPlatformSupported) {
skipBuild("Qt WebEngine on Windows requires MSVC 2013 or MSVC 2015.")
return(false)
}
+ isBuildingOnWin32() {
+ skipBuild("Qt WebEngine on Windows must be built on a 64-bit machine.")
+ }
} else:osx {
lessThan(QMAKE_XCODE_VERSION, 5.1) {
skipBuild("Using XCode version $$QMAKE_XCODE_VERSION, but at least version 5.1 is required to build Qt WebEngine.")
@@ -30,6 +33,10 @@ defineTest(isPlatformSupported) {
skipBuild("Qt WebEngine requires OS X version 10.9 or newer.")
return(false)
}
+ !isMinOSXSDKVersion(10, 10, 3): {
+ skipBuild("Qt WebEngine requires an OS X SDK version 10.10.3 or newer. Current version is $${WEBENGINE_OSX_SDK_PRODUCT_VERSION}.")
+ return(false)
+ }
} else {
skipBuild("Unknown platform. Qt WebEngine only supports Linux, Windows, and OS X.")
return(false)
@@ -77,6 +84,36 @@ defineTest(isQMLTestSupportApiEnabled) {
return(false)
}
+defineTest(isBuildingOnWin32) {
+ # The check below is ugly, but necessary, as it seems to be the only reliable way to detect if the host
+ # architecture is 32 bit. QMAKE_HOST.arch does not work as it returns the architecture that the toolchain
+ # is building for, not the system's actual architecture.
+ PROGRAM_FILES_X86 = $$(ProgramW6432)
+ isEmpty(PROGRAM_FILES_X86): return(true)
+ return(false)
+}
+
+defineTest(isMinOSXSDKVersion) {
+ requested_major = $$1
+ requested_minor = $$2
+ requested_patch = $$3
+ WEBENGINE_OSX_SDK_PRODUCT_VERSION = $$system("/usr/bin/xcodebuild -sdk $$QMAKE_MAC_SDK -version ProductVersion 2>/dev/null")
+ export(WEBENGINE_OSX_SDK_PRODUCT_VERSION)
+ isEmpty(WEBENGINE_OSX_SDK_PRODUCT_VERSION) {
+ skipBuild("Could not resolve SDK product version for \'$$QMAKE_MAC_SDK\'.")
+ return(false)
+ }
+ major_version = $$section(WEBENGINE_OSX_SDK_PRODUCT_VERSION, ., 0, 0)
+ minor_version = $$section(WEBENGINE_OSX_SDK_PRODUCT_VERSION, ., 1, 1)
+ patch_version = $$section(WEBENGINE_OSX_SDK_PRODUCT_VERSION, ., 2, 2)
+
+ greaterThan(major_version, $$requested_major):return(true)
+ equals(major_version, $$requested_major):greaterThan(minor_version, $$requested_minor):return(true)
+ equals(major_version, $$requested_major):equals(minor_version, $$requested_minor):!lessThan(patch_version, $$requested_patch):return(true)
+
+ return(false)
+}
+
# Map to the correct target type for gyp
defineReplace(toGypTargetType) {
equals(TEMPLATE, "app"):return("executable")
diff --git a/tools/scripts/take_snapshot.py b/tools/scripts/take_snapshot.py
index 04f53de88..f5a1ed9d9 100755
--- a/tools/scripts/take_snapshot.py
+++ b/tools/scripts/take_snapshot.py
@@ -84,7 +84,7 @@ def isInChromiumBlacklist(file_path):
not '/app/theme/' in file_path and
not '/app/resources/' in file_path and
not '/browser/printing/' in file_path and
- not '/browser/resources/' in file_path and
+ not ('/browser/resources/' in file_path and not '/chromeos/' in file_path) and
not '/renderer/resources/' in file_path and
not 'repack_locales' in file_path and
not 'third_party/chromevox' in file_path and
@@ -94,6 +94,7 @@ def isInChromiumBlacklist(file_path):
not 'common/localized_error.' in file_path and
not 'common/spellcheck_' in file_path and
not '/spellchecker/' in file_path and
+ not '/tools/convert_dict/' in file_path and
not file_path.endswith('cf_resources.rc') and
not file_path.endswith('version.py') and
not file_path.endswith('.grd') and
@@ -110,18 +111,22 @@ def isInChromiumBlacklist(file_path):
not file_path.startswith('components/error_page') and
not file_path.startswith('components/keyed_service') and
not file_path.startswith('components/mime_util') and
+ not file_path.startswith('components/precache') and
not file_path.startswith('components/pref_registry') and
not file_path.startswith('components/printing') and
not file_path.startswith('components/resources') and
not file_path.startswith('components/scheduler') and
not file_path.startswith('components/security_interstitials') and
+ not file_path.startswith('components/startup_metric_utils') and
not file_path.startswith('components/strings') and
not file_path.startswith('components/tracing') and
not file_path.startswith('components/url_formatter') and
not file_path.startswith('components/user_prefs') and
+ not file_path.startswith('components/version_') and
not file_path.startswith('components/visitedlink') and
not file_path.startswith('components/web_cache') and
not file_path.startswith('components/webcrypto') and
+ not file_path.startswith('components/webusb') and
not file_path.endswith('.grd') and
not file_path.endswith('.grdp') and
not 'components_strings' in file_path)
@@ -157,12 +162,12 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('third_party/bison')
or (file_path.startswith('third_party/cacheinvalidation') and
not file_path.endswith('isolate'))
+ or file_path.startswith('third_party/boringssl/src/fuzz')
or file_path.startswith('third_party/catapult')
or file_path.startswith('third_party/chromite')
or file_path.startswith('third_party/cld_2')
or file_path.startswith('third_party/codesighs')
or file_path.startswith('third_party/colorama')
- or file_path.startswith('third_party/cros_system_api')
or file_path.startswith('third_party/cygwin')
or file_path.startswith('third_party/cython')
or file_path.startswith('third_party/deqp')
@@ -174,13 +179,13 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('third_party/google_appengine_cloudstorage')
or file_path.startswith('third_party/google_toolbox_for_mac')
or file_path.startswith('third_party/hunspell_dictionaries')
+ or (file_path.startswith('third_party/icu') and file_path.endswith('icudtl_dat.S'))
or file_path.startswith('third_party/instrumented_libraries')
or file_path.startswith('third_party/jsr-305/src')
or file_path.startswith('third_party/junit')
or file_path.startswith('third_party/libphonenumber')
or file_path.startswith('third_party/libaddressinput')
or file_path.startswith('third_party/libc++')
- or file_path.startswith('third_party/libc++abi')
or file_path.startswith('third_party/liblouis')
or file_path.startswith('third_party/lighttpd')
or file_path.startswith('third_party/markdown')
@@ -188,6 +193,7 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('third_party/nacl_sdk_binaries')
or (file_path.startswith('third_party/polymer') and
not file_path.startswith('third_party/polymer/v1_0/components-chromium/'))
+ or file_path.startswith('third_party/openh264/src/res')
or file_path.startswith('third_party/pdfsqueeze')
or file_path.startswith('third_party/pefile')
or file_path.startswith('third_party/perl')
diff --git a/tools/scripts/version_resolver.py b/tools/scripts/version_resolver.py
index 66a09e15d..d07ca67da 100644
--- a/tools/scripts/version_resolver.py
+++ b/tools/scripts/version_resolver.py
@@ -38,8 +38,8 @@ import json
import urllib2
import git_submodule as GitSubmodule
-chromium_version = '47.0.2526.109'
-chromium_branch = '2526'
+chromium_version = '49.0.2623.91'
+chromium_branch = '2623'
ninja_version = 'v1.6.0'
json_url = 'http://omahaproxy.appspot.com/all.json'