summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-11-20 16:01:37 +0100
committerAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-11-20 16:04:42 +0100
commit1f474fcc4cd47a85ce8d99f07d18b46ef2af5898 (patch)
treed4e52b5ac98343b4c2417d622164bf320d781a59
parent4cc28c7c89f794d469f5e8f778ff05effe8c646f (diff)
parent1173d48149a8133b607894b67e1ec32de68e21e8 (diff)
Merge branch '5.6' into dev
-rw-r--r--dist/changes-5.5.246
-rw-r--r--examples/examples.pro3
-rw-r--r--examples/webengine/quicknanobrowser/BrowserWindow.qml21
-rw-r--r--examples/webengine/quicknanobrowser/FullScreenNotification.qml99
-rw-r--r--examples/webengine/quicknanobrowser/quicknanobrowser.pro3
-rw-r--r--examples/webengine/quicknanobrowser/resources.qrc1
-rw-r--r--examples/webenginewidgets/demobrowser/demobrowser.pro2
-rw-r--r--examples/webenginewidgets/demobrowser/doc/images/browser-demo.pngbin156342 -> 199354 bytes
-rw-r--r--examples/webenginewidgets/demobrowser/downloadmanager.h2
-rw-r--r--examples/webenginewidgets/demobrowser/fullscreennotification.cpp112
-rw-r--r--examples/webenginewidgets/demobrowser/fullscreennotification.h76
-rw-r--r--examples/webenginewidgets/demobrowser/tabwidget.cpp29
-rw-r--r--examples/webenginewidgets/demobrowser/tabwidget.h6
-rw-r--r--examples/webenginewidgets/demobrowser/webview.cpp17
-rw-r--r--examples/webenginewidgets/demobrowser/webview.h5
-rw-r--r--examples/webenginewidgets/markdowneditor/3RDPARTY.md23
-rw-r--r--examples/webenginewidgets/markdowneditor/doc/images/markdowneditor-example.pngbin0 -> 41883 bytes
-rw-r--r--examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc164
-rw-r--r--examples/webenginewidgets/markdowneditor/document.cpp50
-rw-r--r--examples/webenginewidgets/markdowneditor/document.h64
-rw-r--r--examples/webenginewidgets/markdowneditor/main.cpp56
-rw-r--r--examples/webenginewidgets/markdowneditor/mainwindow.cpp172
-rw-r--r--examples/webenginewidgets/markdowneditor/mainwindow.h77
-rw-r--r--examples/webenginewidgets/markdowneditor/mainwindow.ui115
-rw-r--r--examples/webenginewidgets/markdowneditor/markdowneditor.pro28
-rw-r--r--examples/webenginewidgets/markdowneditor/previewpage.cpp55
-rw-r--r--examples/webenginewidgets/markdowneditor/previewpage.h57
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/default.md12
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/index.html32
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/markdown.css260
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc9
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/marked.min.js6
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/qwebchannel.js413
-rw-r--r--src/core/api/qwebenginecallback.h7
-rw-r--r--src/core/api/qwebenginecallback_p.h6
-rw-r--r--src/core/api/qwebenginecookiestoreclient.cpp4
-rw-r--r--src/core/api/qwebenginecookiestoreclient.h2
-rw-r--r--src/core/api/qwebenginecookiestoreclient_p.h11
-rw-r--r--src/core/api/qwebengineurlschemehandler.cpp1
-rw-r--r--src/core/api/qwebengineurlschemehandler.h3
-rw-r--r--src/core/chrome_qt.gyp14
-rw-r--r--src/core/common/qt_messages.h12
-rw-r--r--src/core/common/user_script_data.h6
-rw-r--r--src/core/config/linux.pri4
-rw-r--r--src/core/cookie_monster_delegate_qt.h1
-rw-r--r--src/core/core_gyp_generator.pro12
-rw-r--r--src/core/delegated_frame_node.cpp27
-rw-r--r--src/core/delegated_frame_node.h6
-rw-r--r--src/core/gl_context_qt.cpp8
-rw-r--r--src/core/location_provider_qt.cpp26
-rw-r--r--src/core/permission_manager_qt.cpp3
-rw-r--r--src/core/qtwebengine.gypi2
-rw-r--r--src/core/render_view_observer_host_qt.cpp (renamed from src/core/qt_render_view_observer_host.cpp)28
-rw-r--r--src/core/render_view_observer_host_qt.h (renamed from src/core/qt_render_view_observer_host.h)10
-rw-r--r--src/core/render_widget_host_view_qt.cpp17
-rw-r--r--src/core/renderer/content_renderer_client_qt.cpp11
-rw-r--r--src/core/renderer/content_renderer_client_qt.h5
-rw-r--r--src/core/renderer/render_frame_observer_qt.cpp (renamed from src/core/renderer/qt_render_frame_observer.cpp)8
-rw-r--r--src/core/renderer/render_frame_observer_qt.h (renamed from src/core/renderer/qt_render_frame_observer.h)14
-rw-r--r--src/core/renderer/render_view_observer_qt.cpp (renamed from src/core/renderer/qt_render_view_observer.cpp)38
-rw-r--r--src/core/renderer/render_view_observer_qt.h (renamed from src/core/renderer/qt_render_view_observer.h)20
-rw-r--r--src/core/resources/devtools_discovery_page.html106
-rw-r--r--src/core/stream_video_node.cpp39
-rw-r--r--src/core/stream_video_node.h19
-rw-r--r--src/core/web_contents_adapter.cpp4
-rw-r--r--src/core/web_contents_adapter_p.h4
-rw-r--r--src/core/web_contents_delegate_qt.cpp7
-rw-r--r--src/core/web_contents_delegate_qt.h4
-rw-r--r--src/core/web_engine_context.cpp2
-rw-r--r--src/core/web_engine_settings.cpp120
-rw-r--r--src/core/web_engine_settings.h4
-rw-r--r--src/core/yuv_video_node.cpp4
-rw-r--r--src/core/yuv_video_node.h14
-rw-r--r--src/process/main.cpp8
-rw-r--r--src/process/process.pro22
-rw-r--r--src/process/support_win.cpp155
-rw-r--r--src/webengine/api/qquickwebenginecertificateerror_p.h2
-rw-r--r--src/webengine/api/qquickwebenginedownloaditem_p.h2
-rw-r--r--src/webengine/api/qquickwebenginenewviewrequest.cpp2
-rw-r--r--src/webengine/api/qquickwebengineprofile_p.h4
-rw-r--r--src/webengine/api/qquickwebenginescript_p.h4
-rw-r--r--src/webengine/api/qquickwebenginesettings_p.h6
-rw-r--r--src/webengine/api/qquickwebengineview.cpp41
-rw-r--r--src/webengine/api/qquickwebengineview_p.h18
-rw-r--r--src/webengine/doc/src/external-resources.qdoc5
-rw-r--r--src/webengine/doc/src/qtwebengine-debugging.qdoc (renamed from src/webengine/doc/src/qtwebengine-devtools.qdoc)20
-rw-r--r--src/webengine/doc/src/qtwebengine-index.qdoc2
-rw-r--r--src/webengine/doc/src/qtwebengine-overview.qdoc6
-rw-r--r--src/webengine/doc/src/webengineview.qdoc5
-rw-r--r--src/webengine/plugin/plugin.cpp2
-rw-r--r--src/webengine/plugin/plugins.qmltypes12
-rw-r--r--src/webengine/ui/AuthenticationDialog.qml77
-rw-r--r--src/webengine/ui_delegates_manager.cpp12
-rw-r--r--src/webengine/ui_delegates_manager.h12
-rw-r--r--src/webenginewidgets/api/qwebenginedownloaditem.h2
-rw-r--r--src/webenginewidgets/api/qwebenginefullscreenrequest.cpp22
-rw-r--r--src/webenginewidgets/api/qwebenginefullscreenrequest.h15
-rw-r--r--src/webenginewidgets/api/qwebenginehistory.h4
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp48
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h3
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h3
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp8
-rw-r--r--src/webenginewidgets/api/qwebenginescript.cpp3
-rw-r--r--src/webenginewidgets/api/qwebenginescript.h2
-rw-r--r--src/webenginewidgets/api/qwebenginescriptcollection.cpp5
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp18
-rw-r--r--src/webenginewidgets/api/qwebengineview.h2
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc5
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp9
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h1
-rw-r--r--tests/auto/core/core.pro2
-rw-r--r--tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.cpp2
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp1
-rw-r--r--tests/auto/core/tests.pri4
-rw-r--r--tests/auto/widgets/positionplugin/plugin.cpp112
-rw-r--r--tests/auto/widgets/positionplugin/plugin.json9
-rw-r--r--tests/auto/widgets/positionplugin/positionplugin.pro12
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp34
-rw-r--r--tests/auto/widgets/qwebengineprofile/qwebengineprofile.pro3
-rw-r--r--tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp76
-rw-r--r--tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp29
-rw-r--r--tests/auto/widgets/qwebenginesettings/qwebenginesettings.pro2
-rw-r--r--tests/auto/widgets/qwebenginesettings/tst_qwebenginesettings.cpp63
-rw-r--r--tests/auto/widgets/widgets.pro13
-rw-r--r--tests/quicktestbrowser/BrowserWindow.qml10
-rw-r--r--tests/quicktestbrowser/FullScreenNotification.qml99
-rw-r--r--tests/quicktestbrowser/quicktestbrowser.pro3
-rw-r--r--tests/quicktestbrowser/resources.qrc1
-rw-r--r--tools/qmake/mkspecs/features/configure.prf14
-rw-r--r--tools/qmake/mkspecs/features/functions.prf10
130 files changed, 3285 insertions, 429 deletions
diff --git a/dist/changes-5.5.2 b/dist/changes-5.5.2
new file mode 100644
index 000000000..fe4b88cb0
--- /dev/null
+++ b/dist/changes-5.5.2
@@ -0,0 +1,46 @@
+Qt 5.5.2 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.5.0.
+
+Qt 5.5 introduces many new features and improvements as well as bugfixes
+over the 5.4.x series. For more details, refer to the online documentation
+included in this distribution. The documentation is also available online:
+
+ http://doc.qt.io/qt-5/index.html
+
+The Qt version 5.5 series is binary compatible with the 5.4.x series.
+Applications compiled for 5.4 will continue to run with 5.5.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+ https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* General *
+****************************************************************************
+
+QtWebEngineCore
+--------
+ - [QTBUG-48309] Fixed old-style QObject connections to
+ QWebEngineDownloadItem::stateChanged.
+ - [QTBUG-47976] Fixed httpUserAgent setting after the view's
+ initialization.
+ - [QTBUG-48206] Parse suggested filename from content-disposition response
+ header field.
+ - Fixed crash on malformed URL (Chromium issue 533361).
+
+****************************************************************************
+* Platform Specific Changes *
+****************************************************************************
+
+OS X
+----
+ - [QTBUG-48228] Enabled 32 bit build.
+
+Windows
+-------
+ - [QTBUG-48285] Fixed installation of PDB files.
+
diff --git a/examples/examples.pro b/examples/examples.pro
index d6960e017..c93886989 100644
--- a/examples/examples.pro
+++ b/examples/examples.pro
@@ -7,5 +7,6 @@ qtHaveModule(webengine) {
qtHaveModule(webenginewidgets) {
SUBDIRS += \
webenginewidgets/demobrowser \
- webenginewidgets/contentmanipulation
+ webenginewidgets/contentmanipulation \
+ webenginewidgets/markdowneditor
}
diff --git a/examples/webengine/quicknanobrowser/BrowserWindow.qml b/examples/webengine/quicknanobrowser/BrowserWindow.qml
index 123a7cc8d..e8a9cb9ce 100644
--- a/examples/webengine/quicknanobrowser/BrowserWindow.qml
+++ b/examples/webengine/quicknanobrowser/BrowserWindow.qml
@@ -59,8 +59,10 @@ ApplicationWindow {
// This is for the case where the system forces us to leave fullscreen.
if (currentWebView && !isFullScreen) {
currentWebView.state = ""
- if (currentWebView.isFullScreen)
+ if (currentWebView.isFullScreen) {
currentWebView.fullScreenCancelled()
+ fullScreenNotification.hide()
+ }
}
}
@@ -83,6 +85,7 @@ ApplicationWindow {
property alias javaScriptEnabled: javaScriptEnabled.checked;
property alias errorPageEnabled: errorPageEnabled.checked;
property alias pluginsEnabled: pluginsEnabled.checked;
+ property alias fullScreenSupportEnabled: fullScreenSupportEnabled.checked;
}
Action {
@@ -268,7 +271,13 @@ ApplicationWindow {
id: pluginsEnabled
text: "Plugins On"
checkable: true
- checked: true
+ checked: WebEngine.settings.pluginsEnabled
+ }
+ MenuItem {
+ id: fullScreenSupportEnabled
+ text: "FullScreen On"
+ checkable: true
+ checked: WebEngine.settings.fullScreenSupportEnabled
}
MenuItem {
id: offTheRecordEnabled
@@ -354,6 +363,7 @@ ApplicationWindow {
settings.javascriptEnabled: appSettings.javaScriptEnabled
settings.errorPageEnabled: appSettings.errorPageEnabled
settings.pluginsEnabled: appSettings.pluginsEnabled
+ settings.fullScreenSupportEnabled: appSettings.fullScreenSupportEnabled
onCertificateError: {
error.defer()
@@ -384,9 +394,11 @@ ApplicationWindow {
webEngineView.state = "FullScreen"
browserWindow.previousVisibility = browserWindow.visibility
browserWindow.showFullScreen()
+ fullScreenNotification.show()
} else {
webEngineView.state = ""
browserWindow.visibility = browserWindow.previousVisibility
+ fullScreenNotification.hide()
}
request.accept()
}
@@ -460,6 +472,11 @@ ApplicationWindow {
visible = certErrors.length > 0
}
}
+
+ FullScreenNotification {
+ id: fullScreenNotification
+ }
+
DownloadView {
id: downloadView
visible: false
diff --git a/examples/webengine/quicknanobrowser/FullScreenNotification.qml b/examples/webengine/quicknanobrowser/FullScreenNotification.qml
new file mode 100644
index 000000000..80a63d479
--- /dev/null
+++ b/examples/webengine/quicknanobrowser/FullScreenNotification.qml
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 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: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.5
+
+Rectangle {
+ id: fullScreenNotification
+ width: 500
+ height: 40
+ color: "white"
+ radius: 7
+
+ visible: false
+ opacity: 0
+
+ function show() {
+ visible = true
+ opacity = 1
+ reset.start()
+ }
+
+ function hide() {
+ reset.stop()
+ opacity = 0
+ }
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: 750
+ onStopped: {
+ if (opacity == 0)
+ visible = false
+ }
+ }
+ }
+
+ Timer {
+ id: reset
+ interval: 5000
+ onTriggered: hide()
+ }
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ y: 125
+
+ Text {
+ id: message
+ width: parent.width
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+
+ wrapMode: Text.WordWrap
+ elide: Text.ElideNone
+ clip: true
+
+ text: qsTr("You are now in fullscreen mode. Press ESC to quit!")
+ }
+}
diff --git a/examples/webengine/quicknanobrowser/quicknanobrowser.pro b/examples/webengine/quicknanobrowser/quicknanobrowser.pro
index 1447af927..6cf556984 100644
--- a/examples/webengine/quicknanobrowser/quicknanobrowser.pro
+++ b/examples/webengine/quicknanobrowser/quicknanobrowser.pro
@@ -9,7 +9,8 @@ SOURCES = main.cpp
OTHER_FILES += ApplicationRoot.qml \
BrowserDialog.qml \
BrowserWindow.qml \
- DownloadView.qml
+ DownloadView.qml \
+ FullScreenNotification.qml
RESOURCES += resources.qrc
diff --git a/examples/webengine/quicknanobrowser/resources.qrc b/examples/webengine/quicknanobrowser/resources.qrc
index 28fd7b7dc..694f8d19b 100644
--- a/examples/webengine/quicknanobrowser/resources.qrc
+++ b/examples/webengine/quicknanobrowser/resources.qrc
@@ -4,6 +4,7 @@
<file>BrowserDialog.qml</file>
<file>BrowserWindow.qml</file>
<file>DownloadView.qml</file>
+ <file>FullScreenNotification.qml</file>
</qresource>
<qresource prefix="icons">
<file alias="go-next.png">icons/go-next.png</file>
diff --git a/examples/webenginewidgets/demobrowser/demobrowser.pro b/examples/webenginewidgets/demobrowser/demobrowser.pro
index 14347de71..113eeb40e 100644
--- a/examples/webenginewidgets/demobrowser/demobrowser.pro
+++ b/examples/webenginewidgets/demobrowser/demobrowser.pro
@@ -28,6 +28,7 @@ HEADERS += \
edittableview.h \
edittreeview.h \
featurepermissionbar.h\
+ fullscreennotification.h \
history.h \
modelmenu.h \
searchlineedit.h \
@@ -49,6 +50,7 @@ SOURCES += \
edittableview.cpp \
edittreeview.cpp \
featurepermissionbar.cpp\
+ fullscreennotification.cpp \
history.cpp \
modelmenu.cpp \
searchlineedit.cpp \
diff --git a/examples/webenginewidgets/demobrowser/doc/images/browser-demo.png b/examples/webenginewidgets/demobrowser/doc/images/browser-demo.png
index 09d065095..e8695dbca 100644
--- a/examples/webenginewidgets/demobrowser/doc/images/browser-demo.png
+++ b/examples/webenginewidgets/demobrowser/doc/images/browser-demo.png
Binary files differ
diff --git a/examples/webenginewidgets/demobrowser/downloadmanager.h b/examples/webenginewidgets/demobrowser/downloadmanager.h
index 877682d77..cd96f35a5 100644
--- a/examples/webenginewidgets/demobrowser/downloadmanager.h
+++ b/examples/webenginewidgets/demobrowser/downloadmanager.h
@@ -98,7 +98,6 @@ class DownloadManager : public QDialog, public Ui_DownloadDialog
{
Q_OBJECT
Q_PROPERTY(RemovePolicy removePolicy READ removePolicy WRITE setRemovePolicy)
- Q_ENUMS(RemovePolicy)
public:
enum RemovePolicy {
@@ -106,6 +105,7 @@ public:
Exit,
SuccessFullDownload
};
+ Q_ENUM(RemovePolicy)
DownloadManager(QWidget *parent = 0);
~DownloadManager();
diff --git a/examples/webenginewidgets/demobrowser/fullscreennotification.cpp b/examples/webenginewidgets/demobrowser/fullscreennotification.cpp
new file mode 100644
index 000000000..8ee968bec
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/fullscreennotification.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and 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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "fullscreennotification.h"
+
+#include <QApplication>
+#include <QDesktopWidget>
+#include <QGridLayout>
+#include <QLabel>
+#include <QPropertyAnimation>
+#include <QTimer>
+
+FullScreenNotification::FullScreenNotification(QWidget *parent)
+ : QWidget(parent)
+ , width(400)
+ , height(80)
+ , x((parent->geometry().width() - width) / 2)
+ , y(80)
+{
+ setVisible(false);
+ setWindowFlags(Qt::ToolTip | Qt::WindowDoesNotAcceptFocus);
+
+ QGridLayout *layout = new QGridLayout(this);
+
+ m_label = new QLabel(tr("You are now in fullscreen mode. Press ESC to quit!"), this);
+ layout->addWidget(m_label, 0, 0, 0, 0, Qt::AlignHCenter | Qt::AlignVCenter);
+
+ setGeometry(x, y, width, height);
+
+ setStyleSheet("background-color: white;\
+ color: black;");
+
+ m_animation = new QPropertyAnimation(this, "windowOpacity");
+ connect(m_animation, SIGNAL(finished()), this, SLOT(fadeOutFinished()));
+}
+
+FullScreenNotification::~FullScreenNotification()
+{
+}
+
+void FullScreenNotification::show()
+{
+ setWindowOpacity(1.0);
+ QTimer::singleShot(300, [&] {
+ QWidget *parent = parentWidget();
+ x = (parent->geometry().width() - width) / 2;
+ QPoint topLeft = parent->mapToGlobal(QPoint(x, y));
+ QWidget::move(topLeft.x(), topLeft.y());
+ QWidget::show();
+ QWidget::raise();
+ });
+ QTimer::singleShot(5000, this, SLOT(fadeOut()));
+}
+
+void FullScreenNotification::hide()
+{
+ QWidget::hide();
+ m_animation->stop();
+}
+
+void FullScreenNotification::fadeOut()
+{
+ m_animation->setDuration(800);
+ m_animation->setStartValue(1.0);
+ m_animation->setEndValue(0.0);
+ m_animation->setEasingCurve(QEasingCurve::OutQuad);
+ m_animation->start();
+}
+
+void FullScreenNotification::fadeOutFinished()
+{
+ hide();
+ setWindowOpacity(1.0);
+}
diff --git a/examples/webenginewidgets/demobrowser/fullscreennotification.h b/examples/webenginewidgets/demobrowser/fullscreennotification.h
new file mode 100644
index 000000000..051075ab3
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/fullscreennotification.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and 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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FULLSCREENNOTIFICATION_H
+#define FULLSCREENNOTIFICATION_H
+
+#include <QWidget>
+
+class QLabel;
+class QGridLayout;
+class QPropertyAnimation;
+
+class FullScreenNotification : public QWidget
+{
+ Q_OBJECT
+public:
+ FullScreenNotification(QWidget *parent = 0);
+ ~FullScreenNotification();
+
+ void show();
+ void hide();
+
+public slots:
+ void fadeOut();
+ void fadeOutFinished();
+
+private:
+ QLabel *m_label;
+ QGridLayout *m_layout;
+ QPropertyAnimation *m_animation;
+ int width;
+ int height;
+ int x;
+ int y;
+};
+
+
+#endif // FULLSCREENNOTIFICATION_H
diff --git a/examples/webenginewidgets/demobrowser/tabwidget.cpp b/examples/webenginewidgets/demobrowser/tabwidget.cpp
index 4e2073b11..95b79aaac 100644
--- a/examples/webenginewidgets/demobrowser/tabwidget.cpp
+++ b/examples/webenginewidgets/demobrowser/tabwidget.cpp
@@ -44,6 +44,7 @@
#include "browserapplication.h"
#include "browsermainwindow.h"
#include "downloadmanager.h"
+#include "fullscreennotification.h"
#include "history.h"
#include "urllineedit.h"
#include "webview.h"
@@ -88,6 +89,7 @@ TabBar::TabBar(QWidget *parent)
TabWidget::~TabWidget()
{
+ delete m_fullScreenNotification;
delete m_fullScreenView;
}
@@ -220,6 +222,7 @@ TabWidget::TabWidget(QWidget *parent)
, m_tabBar(new TabBar(this))
, m_profile(QWebEngineProfile::defaultProfile())
, m_fullScreenView(0)
+ , m_fullScreenNotification(0)
{
setElideMode(Qt::ElideRight);
@@ -322,8 +325,8 @@ void TabWidget::currentChanged(int index)
this, SIGNAL(loadProgress(int)));
disconnect(oldWebView->page()->profile(), SIGNAL(downloadRequested(QWebEngineDownloadItem*)),
this, SLOT(downloadRequested(QWebEngineDownloadItem*)));
- disconnect(oldWebView->page(), SIGNAL(fullScreenRequested(const QWebEngineFullScreenRequest&)),
- this, SLOT(fullScreenRequested(const QWebEngineFullScreenRequest&)));
+ disconnect(oldWebView->page(), SIGNAL(fullScreenRequested(QWebEngineFullScreenRequest)),
+ this, SLOT(fullScreenRequested(QWebEngineFullScreenRequest)));
}
#if defined(QWEBENGINEVIEW_STATUSBARMESSAGE)
@@ -336,8 +339,8 @@ void TabWidget::currentChanged(int index)
this, SIGNAL(loadProgress(int)));
connect(webView->page()->profile(), SIGNAL(downloadRequested(QWebEngineDownloadItem*)),
this, SLOT(downloadRequested(QWebEngineDownloadItem*)));
- connect(webView->page(), SIGNAL(fullScreenRequested(const QWebEngineFullScreenRequest&)),
- this, SLOT(fullScreenRequested(const QWebEngineFullScreenRequest&)));
+ connect(webView->page(), SIGNAL(fullScreenRequested(QWebEngineFullScreenRequest)),
+ this, SLOT(fullScreenRequested(QWebEngineFullScreenRequest)));
for (int i = 0; i < m_actions.count(); ++i) {
WebActionMapper *mapper = m_actions[i];
@@ -353,25 +356,35 @@ void TabWidget::currentChanged(int index)
webView->setFocus();
}
-void TabWidget::fullScreenRequested(const QWebEngineFullScreenRequest &request)
+void TabWidget::fullScreenRequested(QWebEngineFullScreenRequest request)
{
+ WebPage *webPage = qobject_cast<WebPage*>(sender());
if (request.toggleOn()) {
- if (!m_fullScreenView)
+ if (!m_fullScreenView) {
m_fullScreenView = new QWebEngineView();
- WebPage *webPage = qobject_cast<WebPage*>(sender());
+ m_fullScreenNotification = new FullScreenNotification(m_fullScreenView);
+
+ QAction *exitFullScreenAction = new QAction(m_fullScreenView);
+ exitFullScreenAction->setShortcut(Qt::Key_Escape);
+ connect(exitFullScreenAction, &QAction::triggered, [webPage] {
+ webPage->triggerAction(QWebEnginePage::ExitFullScreen);
+ });
+ m_fullScreenView->addAction(exitFullScreenAction);
+ }
webPage->setView(m_fullScreenView);
request.accept();
m_fullScreenView->showFullScreen();
m_fullScreenView->raise();
+ m_fullScreenNotification->show();
} else {
if (!m_fullScreenView)
return;
- WebPage *webPage = qobject_cast<WebPage*>(sender());
WebView *oldWebView = this->webView(m_lineEdits->currentIndex());
webPage->setView(oldWebView);
request.accept();
raise();
m_fullScreenView->hide();
+ m_fullScreenNotification->hide();
}
}
diff --git a/examples/webenginewidgets/demobrowser/tabwidget.h b/examples/webenginewidgets/demobrowser/tabwidget.h
index 3a1fe7171..b00131130 100644
--- a/examples/webenginewidgets/demobrowser/tabwidget.h
+++ b/examples/webenginewidgets/demobrowser/tabwidget.h
@@ -42,8 +42,8 @@
#ifndef TABWIDGET_H
#define TABWIDGET_H
+#include <QtWebEngineWidgets/QWebEngineFullScreenRequest>
#include <QtWidgets/QTabBar>
-
#include <QtWidgets/QShortcut>
QT_BEGIN_NAMESPACE
@@ -129,6 +129,7 @@ private:
#include <QtCore/QUrl>
#include <QtWidgets/QTabWidget>
QT_BEGIN_NAMESPACE
+class FullScreenNotification;
class QCompleter;
class QLineEdit;
class QMenu;
@@ -216,7 +217,7 @@ private slots:
void lineEditReturnPressed();
void windowCloseRequested();
void moveTab(int fromIndex, int toIndex);
- void fullScreenRequested(const QWebEngineFullScreenRequest& request);
+ void fullScreenRequested(QWebEngineFullScreenRequest request);
private:
QAction *m_recentlyClosedTabsAction;
@@ -235,6 +236,7 @@ private:
TabBar *m_tabBar;
QWebEngineProfile *m_profile;
QWebEngineView *m_fullScreenView;
+ FullScreenNotification *m_fullScreenNotification;
};
#endif // TABWIDGET_H
diff --git a/examples/webenginewidgets/demobrowser/webview.cpp b/examples/webenginewidgets/demobrowser/webview.cpp
index c12f3db36..79a6cf344 100644
--- a/examples/webenginewidgets/demobrowser/webview.cpp
+++ b/examples/webenginewidgets/demobrowser/webview.cpp
@@ -315,23 +315,6 @@ void WebPage::proxyAuthenticationRequired(const QUrl &requestUrl, QAuthenticator
}
}
-void WebPage::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int /*lineNumber*/, const QString& sourceID)
-{
- QUrl url;
- url.setUrl(sourceID);
- switch (level) {
- case InfoMessageLevel:
- // Ignore these, they can still be found in the inspector.
- break;
- case WarningMessageLevel:
- qInfo() << "JavaScript WARNING:" << url.host() << message;
- break;
- case ErrorMessageLevel:
- qInfo() << "JavaScript ERROR:" << url.host() << message;
- break;
- }
-}
-
WebView::WebView(QWidget* parent)
: QWebEngineView(parent)
, m_progress(0)
diff --git a/examples/webenginewidgets/demobrowser/webview.h b/examples/webenginewidgets/demobrowser/webview.h
index cb78fdd8a..34188a259 100644
--- a/examples/webenginewidgets/demobrowser/webview.h
+++ b/examples/webenginewidgets/demobrowser/webview.h
@@ -65,13 +65,12 @@ public:
BrowserMainWindow *mainWindow();
protected:
- bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame);
- QWebEnginePage *createWindow(QWebEnginePage::WebWindowType type);
+ bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame) Q_DECL_OVERRIDE;
+ QWebEnginePage *createWindow(QWebEnginePage::WebWindowType type) Q_DECL_OVERRIDE;
#if !defined(QT_NO_UITOOLS)
QObject *createPlugin(const QString &classId, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues);
#endif
virtual bool certificateError(const QWebEngineCertificateError &error) Q_DECL_OVERRIDE;
- virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE;
private slots:
#if defined(QWEBENGINEPAGE_UNSUPPORTEDCONTENT)
diff --git a/examples/webenginewidgets/markdowneditor/3RDPARTY.md b/examples/webenginewidgets/markdowneditor/3RDPARTY.md
new file mode 100644
index 000000000..9e91ab302
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/3RDPARTY.md
@@ -0,0 +1,23 @@
+## markd license
+
+```
+Copyright (c) 2011-2014, Christopher Jeffrey (https://github.com/chjj/)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+```
diff --git a/examples/webenginewidgets/markdowneditor/doc/images/markdowneditor-example.png b/examples/webenginewidgets/markdowneditor/doc/images/markdowneditor-example.png
new file mode 100644
index 000000000..9f456c4db
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/doc/images/markdowneditor-example.png
Binary files differ
diff --git a/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc b/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
new file mode 100644
index 000000000..44b1246b3
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 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/markdowneditor
+ \title Markdown Editor Example
+ \ingroup webengine-widgetexamples
+ \brief Demonstrates how to integrate a web engine in a hybrid desktop
+ application.
+
+ \image markdowneditor-example.png
+
+ \e {Markdown Editor} demonstrates how to use QWebChannel and JavaScript
+ libraries to provide a rich text preview tool for a custom markup language.
+
+ \l{http://daringfireball.net/projects/markdown/}{Markdown} is a lightweight
+ markup language with a plain text formatting syntax.
+ Some services, such as \l{http://github.com}{github}, acknowledge the
+ format, and render the content as rich text when viewed in a browser.
+
+ The Markdown Editor main window is split into an editor and a preview area.
+ The editor supports the Markdown syntax and is implemented by using
+ QPlainTextEdit. The document is rendered as rich text in the preview area,
+ which is implemented by using QWebEngineView. To render the text, the
+ Markdown text is converted to HTML format with the help of a JavaScript
+ library inside the web engine. The preview is updated from the editor
+ through QWebChannel.
+
+ \include examples-run.qdocinc
+
+ \section1 Exposing Document Text
+
+ Because we expose the current Markdown text to be rendered to the web engine
+ through QWebChannel, we need to somehow make the current text available
+ through the Qt metatype system. This is done by using a dedicated
+ \c Document class that exposes the document text as a \c{Q_PROPERTY}:
+
+ \quotefromfile webenginewidgets/markdowneditor/document.h
+ \skipto class Document
+ \printto #endif
+
+ The \c Document class wraps a QString to be set on the C++ side with
+ the \c setText() method and exposes it at runtime as a \c text property
+ with a \c textChanged signal.
+
+ We define the \c setText method as follows:
+
+ \quotefromfile webenginewidgets/markdowneditor/document.cpp
+ \skipto Document::setText
+ \printuntil
+
+ \section1 Previewing Text
+
+ We implement our own \c PreviewPage class that publicly inherits from
+ \c QWebEnginePage:
+
+ \quotefromfile webenginewidgets/markdowneditor/previewpage.h
+ \skipto class PreviewPage
+ \printto #endif
+
+ We reimplement the virtual \c acceptNavigationRequest method to
+ stop the page from navigating away from the current document. Instead,
+ we redirect external links to the system browser:
+
+ \quotefromfile webenginewidgets/markdowneditor/previewpage.cpp
+ \skipto acceptNavigationRequest
+ \printuntil
+
+ \section1 Creating the Main Window
+
+ The \c MainWindow class inherits the QMainWindow class:
+
+ \quotefromfile webenginewidgets/markdowneditor/mainwindow.h
+ \skipto class MainWindow :
+ \printto endif
+
+ The class declares private slots that match the actions in the menu,
+ as well as the \c isModified() helper method.
+
+ The actual layout of the main window is specified in a \c .ui file.
+ The widgets and actions are available at runtime in the \c ui member
+ variable.
+
+ \c m_filePath holds the file path to the currently loaded document.
+ \c m_content is an instance of the \c Document class.
+
+ The actual setup of the different objects is done in the \c MainWindow
+ constructor:
+
+ \quotefromfile webenginewidgets/markdowneditor/mainwindow.cpp
+ \skipto MainWindow::MainWindow
+ \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
+ \c PreviewPage is used by the QWebEngineView instance in \c{ui->preview}.
+
+ \printto ui->preview
+
+ Here the \c textChanged signal of the editor is connected to a lambda that
+ updates the text in \c m_content. This object is then exposed to the JS side
+ by \c QWebChannel under the name \c{content}.
+
+ \printto connect
+
+ Now we can actually load the \e index.html file from the
+ resources. For more information about the file, see
+ \l{Creating an Index File}.
+
+ \printto defaultTextFile
+
+ The menu items are connected to the mapping member slots. The
+ \uicontrol Save item is activated or deactivated depending on whether
+ the user has edited the content.
+
+ \printuntil }
+
+ Finally, we load a default document \e default.md from the resources.
+
+ \section1 Creating an Index File
+
+ \quotefile webenginewidgets/markdowneditor/resources/index.html
+
+ In the \e index.html, we load a custom stylesheet and two JavaScript
+ libraries. \l{http://kevinburke.bitbucket.org/markdowncss/}{markdown.css} is
+ a markdown-friendly stylesheet created by Kevin Burke.
+ \l{https://github.com/chjj/marked}{marked.min.js} is a markdown parser and
+ compiler designed for speed written by Christopher Jeffrey and
+ \e qwebchannel.js is part of the \l{QWebChannel} module.
+
+ In the \c <body> element we first define a \c placeholder element, and
+ make it available as a JavaScript variable. We then define the \c updateText
+ helper method that updates the content of \c placeholder with the HTML
+ that the JavaScript method \c marked() returns.
+
+ Finally, we set up the web channel to access the \c content proxy object
+ and make sure that \c updateText() is called whenever \c content.text
+ changes.
+*/
+
diff --git a/examples/webenginewidgets/markdowneditor/document.cpp b/examples/webenginewidgets/markdowneditor/document.cpp
new file mode 100644
index 000000000..98665680c
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/document.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and 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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "document.h"
+
+void Document::setText(const QString &text)
+{
+ if (text == m_text)
+ return;
+ m_text = text;
+ emit textChanged(m_text);
+}
diff --git a/examples/webenginewidgets/markdowneditor/document.h b/examples/webenginewidgets/markdowneditor/document.h
new file mode 100644
index 000000000..d2f33ec81
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/document.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and 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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DOCUMENT_H
+#define DOCUMENT_H
+
+#include <QObject>
+#include <QString>
+
+class Document : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged)
+public:
+ explicit Document(QObject *parent = nullptr) : QObject(parent) {}
+
+ void setText(const QString &text);
+
+signals:
+ void textChanged(const QString &text);
+
+private:
+ QString m_text;
+};
+
+#endif // DOCUMENT_H
diff --git a/examples/webenginewidgets/markdowneditor/main.cpp b/examples/webenginewidgets/markdowneditor/main.cpp
new file mode 100644
index 000000000..2cf4e1f60
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/main.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and 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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "document.h"
+#include "mainwindow.h"
+
+#include <QApplication>
+#include <QFile>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+
+ MainWindow window;
+ window.show();
+
+ return a.exec();
+}
diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.cpp b/examples/webenginewidgets/markdowneditor/mainwindow.cpp
new file mode 100644
index 000000000..fec7c661e
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/mainwindow.cpp
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and 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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+#include "previewpage.h"
+#include "ui_mainwindow.h"
+
+#include <QFile>
+#include <QFileDialog>
+#include <QMessageBox>
+#include <QTextStream>
+#include <QWebChannel>
+
+MainWindow::MainWindow(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::MainWindow)
+{
+ ui->setupUi(this);
+
+ PreviewPage *page = new PreviewPage(this);
+ ui->preview->setPage(page);
+
+ connect(ui->editor, &QPlainTextEdit::textChanged,
+ [this]() { m_content.setText(ui->editor->toPlainText()); });
+
+ QWebChannel *channel = new QWebChannel(this);
+ channel->registerObject(QStringLiteral("content"), &m_content);
+ page->setWebChannel(channel);
+
+ ui->preview->setUrl(QUrl("qrc:/index.html"));
+
+ connect(ui->actionNew, &QAction::triggered, this, &MainWindow::onFileNew);
+ connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::onFileOpen);
+ connect(ui->actionSave, &QAction::triggered, this, &MainWindow::onFileSave);
+ connect(ui->actionSaveAs, &QAction::triggered, this, &MainWindow::onFileSaveAs);
+ connect(ui->actionExit, &QAction::triggered, this, &MainWindow::onExit);
+
+ connect(ui->editor->document(), &QTextDocument::modificationChanged,
+ ui->actionSave, &QAction::setEnabled);
+
+ QFile defaultTextFile(":/default.md");
+ defaultTextFile.open(QIODevice::ReadOnly);
+ ui->editor->setPlainText(defaultTextFile.readAll());
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+bool MainWindow::isModified() const
+{
+ return ui->editor->document()->isModified();
+}
+
+void MainWindow::onFileNew()
+{
+ if (isModified()) {
+ QMessageBox::StandardButton button = QMessageBox::question(this, windowTitle(),
+ tr("You have unsaved changes. Do you want to create a new document anyway?"));
+ if (button != QMessageBox::Yes)
+ return;
+ }
+
+ m_filePath.clear();
+ ui->editor->setPlainText(tr("## New document"));
+ ui->editor->document()->setModified(false);
+}
+
+void MainWindow::onFileOpen()
+{
+ if (isModified()) {
+ QMessageBox::StandardButton button = QMessageBox::question(this, windowTitle(),
+ tr("You have unsaved changes. Do you want to open a new document anyway?"));
+ if (button != QMessageBox::Yes)
+ return;
+ }
+
+ QString path = QFileDialog::getOpenFileName(this,
+ tr("Open MarkDown File"), "", tr("MarkDown File (*.md)"));
+ 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());
+}
+
+void MainWindow::onFileSave()
+{
+ if (m_filePath.isEmpty()) {
+ onFileSaveAs();
+ return;
+ }
+
+ QFile f(m_filePath);
+ if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ QMessageBox::warning(this, windowTitle(),
+ tr("Could not write to file %1: %2").arg(
+ QDir::toNativeSeparators(m_filePath), f.errorString()));
+ return;
+ }
+ QTextStream str(&f);
+ str << ui->editor->toPlainText();
+
+ ui->editor->document()->setModified(false);
+}
+
+void MainWindow::onFileSaveAs()
+{
+ QString path = QFileDialog::getSaveFileName(this,
+ tr("Save MarkDown File"), "", tr("MarkDown File (*.md, *.markdown)"));
+ if (path.isEmpty())
+ return;
+ m_filePath = path;
+ onFileSave();
+}
+
+void MainWindow::onExit()
+{
+ if (isModified()) {
+ QMessageBox::StandardButton button = QMessageBox::question(this, windowTitle(),
+ tr("You have unsaved changes. Do you want to exit anyway?"));
+ if (button != QMessageBox::Yes)
+ return;
+ }
+ close();
+}
diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.h b/examples/webenginewidgets/markdowneditor/mainwindow.h
new file mode 100644
index 000000000..6099f1f79
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/mainwindow.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and 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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include "document.h"
+
+#include <QMainWindow>
+#include <QString>
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+
+private slots:
+ void onFileNew();
+ void onFileOpen();
+ void onFileSave();
+ void onFileSaveAs();
+ void onExit();
+
+private:
+ bool isModified() const;
+
+ Ui::MainWindow *ui;
+ QString m_filePath;
+ Document m_content;
+};
+
+#endif // MAINWINDOW_H
diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.ui b/examples/webenginewidgets/markdowneditor/mainwindow.ui
new file mode 100644
index 000000000..36ab352b7
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/mainwindow.ui
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>600</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MarkDown Editor</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QSplitter" name="splitter">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <widget class="QPlainTextEdit" name="editor"/>
+ <widget class="QWebEngineView" name="preview" native="true"/>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menu_File">
+ <property name="title">
+ <string>&amp;File</string>
+ </property>
+ <addaction name="actionNew"/>
+ <addaction name="actionOpen"/>
+ <addaction name="actionSave"/>
+ <addaction name="actionSaveAs"/>
+ <addaction name="separator"/>
+ <addaction name="actionExit"/>
+ </widget>
+ <addaction name="menu_File"/>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ <action name="actionOpen">
+ <property name="text">
+ <string>&amp;Open...</string>
+ </property>
+ <property name="toolTip">
+ <string>Open document</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+O</string>
+ </property>
+ </action>
+ <action name="actionSave">
+ <property name="text">
+ <string>&amp;Save</string>
+ </property>
+ <property name="toolTip">
+ <string>Save current document</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+S</string>
+ </property>
+ </action>
+ <action name="actionExit">
+ <property name="text">
+ <string>E&amp;xit</string>
+ </property>
+ <property name="toolTip">
+ <string>Exit editor</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Q</string>
+ </property>
+ </action>
+ <action name="actionSaveAs">
+ <property name="text">
+ <string>Save &amp;As...</string>
+ </property>
+ <property name="toolTip">
+ <string>Save document under different name</string>
+ </property>
+ </action>
+ <action name="actionNew">
+ <property name="text">
+ <string>&amp;New</string>
+ </property>
+ <property name="toolTip">
+ <string>Create new document</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+N</string>
+ </property>
+ </action>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QWebEngineView</class>
+ <extends>QWidget</extends>
+ <header>qwebengineview.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/webenginewidgets/markdowneditor/markdowneditor.pro b/examples/webenginewidgets/markdowneditor/markdowneditor.pro
new file mode 100644
index 000000000..bfd16698a
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/markdowneditor.pro
@@ -0,0 +1,28 @@
+TEMPLATE = app
+
+QT += webenginewidgets webchannel
+CONFIG += c++11
+
+HEADERS += \
+ mainwindow.h \
+ previewpage.h \
+ document.h
+
+SOURCES = \
+ main.cpp \
+ mainwindow.cpp \
+ previewpage.cpp \
+ document.cpp
+
+RESOURCES = \
+ resources/markdowneditor.qrc
+
+FORMS += \
+ mainwindow.ui
+
+DISTFILES += \
+ 3RDPARTY.md
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/markdowneditor
+INSTALLS += target
diff --git a/examples/webenginewidgets/markdowneditor/previewpage.cpp b/examples/webenginewidgets/markdowneditor/previewpage.cpp
new file mode 100644
index 000000000..2d4322664
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/previewpage.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and 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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "previewpage.h"
+
+#include <QDesktopServices>
+
+bool PreviewPage::acceptNavigationRequest(const QUrl &url,
+ QWebEnginePage::NavigationType /*type*/,
+ bool /*isMainFrame*/)
+{
+ // Only allow qrc:/index.html.
+ if (url.scheme() == QString("qrc"))
+ return true;
+ QDesktopServices::openUrl(url);
+ return false;
+}
diff --git a/examples/webenginewidgets/markdowneditor/previewpage.h b/examples/webenginewidgets/markdowneditor/previewpage.h
new file mode 100644
index 000000000..53b0e23e6
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/previewpage.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and 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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PREVIEWPAGE_H
+#define PREVIEWPAGE_H
+
+#include <QWebEnginePage>
+
+class PreviewPage : public QWebEnginePage
+{
+ Q_OBJECT
+public:
+ explicit PreviewPage(QObject *parent = nullptr) : QWebEnginePage(parent) {}
+
+protected:
+ bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame);
+};
+
+#endif // PREVIEWPAGE_H
diff --git a/examples/webenginewidgets/markdowneditor/resources/default.md b/examples/webenginewidgets/markdowneditor/resources/default.md
new file mode 100644
index 000000000..e5905b101
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/resources/default.md
@@ -0,0 +1,12 @@
+## Markdown Editor Example
+
+This example uses [QWebEngineView](http://doc.qt.io/qt-5/qwebengineview.html)
+to preview text written using the [Markdown](https://en.wikipedia.org/wiki/Markdown)
+syntax.
+
+### Acknowledgments
+
+The conversion from Markdown to HTML is done with the help of the
+[marked JavaScript library](https://github.com/chjj/marked) by _Christopher Jeffrey_.
+The [style sheet](http://kevinburke.bitbucket.org/markdowncss/markdown.css)
+was created by _Kevin Burke_.
diff --git a/examples/webenginewidgets/markdowneditor/resources/index.html b/examples/webenginewidgets/markdowneditor/resources/index.html
new file mode 100644
index 000000000..2f45479ed
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/resources/index.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<html lang="en">
+<meta charset="utf-8">
+<head>
+ <link rel="stylesheet" type="text/css" href="markdown.css">
+ <script src="marked.min.js"></script>
+ <script src="qwebchannel.js"></script>
+</head>
+<body>
+ <div id="placeholder"></div>
+ <script>
+ 'use strict';
+
+ var placeholder = document.getElementById('placeholder');
+
+ var updateText = function(text) {
+ placeholder.innerHTML = marked(text);
+ }
+
+ new QWebChannel(qt.webChannelTransport,
+ function(channel) {
+ var content = channel.objects.content;
+ updateText(content.text);
+ content.textChanged.connect(updateText);
+ }
+ );
+ </script>
+</body>
+</html>
+
+
+
diff --git a/examples/webenginewidgets/markdowneditor/resources/markdown.css b/examples/webenginewidgets/markdowneditor/resources/markdown.css
new file mode 100644
index 000000000..24fc2ffe2
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/resources/markdown.css
@@ -0,0 +1,260 @@
+body{
+ margin: 0 auto;
+ font-family: Georgia, Palatino, serif;
+ color: #444444;
+ line-height: 1;
+ max-width: 960px;
+ padding: 30px;
+}
+h1, h2, h3, h4 {
+ color: #111111;
+ font-weight: 400;
+}
+h1, h2, h3, h4, h5, p {
+ margin-bottom: 24px;
+ padding: 0;
+}
+h1 {
+ font-size: 48px;
+}
+h2 {
+ font-size: 36px;
+ /* The bottom margin is small. It's designed to be used with gray meta text
+ * below a post title. */
+ margin: 24px 0 6px;
+}
+h3 {
+ font-size: 24px;
+}
+h4 {
+ font-size: 21px;
+}
+h5 {
+ font-size: 18px;
+}
+a {
+ color: #0099ff;
+ margin: 0;
+ padding: 0;
+ vertical-align: baseline;
+}
+a:hover {
+ text-decoration: none;
+ color: #ff6600;
+}
+a:visited {
+ color: purple;
+}
+ul, ol {
+ padding: 0;
+ margin: 0;
+}
+li {
+ line-height: 24px;
+}
+li ul, li ul {
+ margin-left: 24px;
+}
+p, ul, ol {
+ font-size: 16px;
+ line-height: 24px;
+ max-width: 540px;
+}
+pre {
+ padding: 0px 24px;
+ max-width: 800px;
+ white-space: pre-wrap;
+}
+code {
+ font-family: Consolas, Monaco, Andale Mono, monospace;
+ line-height: 1.5;
+ font-size: 13px;
+}
+aside {
+ display: block;
+ float: right;
+ width: 390px;
+}
+blockquote {
+ border-left:.5em solid #eee;
+ padding: 0 2em;
+ margin-left:0;
+ max-width: 476px;
+}
+blockquote cite {
+ font-size:14px;
+ line-height:20px;
+ color:#bfbfbf;
+}
+blockquote cite:before {
+ content: '\2014 \00A0';
+}
+
+blockquote p {
+ color: #666;
+ max-width: 460px;
+}
+hr {
+ width: 540px;
+ text-align: left;
+ margin: 0 auto 0 0;
+ color: #999;
+}
+
+/* Code below this line is copyright Twitter Inc. */
+
+button,
+input,
+select,
+textarea {
+ font-size: 100%;
+ margin: 0;
+ vertical-align: baseline;
+ *vertical-align: middle;
+}
+button, input {
+ line-height: normal;
+ *overflow: visible;
+}
+button::-moz-focus-inner, input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+button,
+input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ cursor: pointer;
+ -webkit-appearance: button;
+}
+input[type=checkbox], input[type=radio] {
+ cursor: pointer;
+}
+/* override default chrome & firefox settings */
+input:not([type="image"]), textarea {
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+}
+
+input[type="search"] {
+ -webkit-appearance: textfield;
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+}
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+label,
+input,
+select,
+textarea {
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 13px;
+ font-weight: normal;
+ line-height: normal;
+ margin-bottom: 18px;
+}
+input[type=checkbox], input[type=radio] {
+ cursor: pointer;
+ margin-bottom: 0;
+}
+input[type=text],
+input[type=password],
+textarea,
+select {
+ display: inline-block;
+ width: 210px;
+ padding: 4px;
+ font-size: 13px;
+ font-weight: normal;
+ line-height: 18px;
+ height: 18px;
+ color: #808080;
+ border: 1px solid #ccc;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+select, input[type=file] {
+ height: 27px;
+ line-height: 27px;
+}
+textarea {
+ height: auto;
+}
+
+/* grey out placeholders */
+:-moz-placeholder {
+ color: #bfbfbf;
+}
+::-webkit-input-placeholder {
+ color: #bfbfbf;
+}
+
+input[type=text],
+input[type=password],
+select,
+textarea {
+ -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
+ -moz-transition: border linear 0.2s, box-shadow linear 0.2s;
+ transition: border linear 0.2s, box-shadow linear 0.2s;
+ -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
+ -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
+}
+input[type=text]:focus, input[type=password]:focus, textarea:focus {
+ outline: none;
+ border-color: rgba(82, 168, 236, 0.8);
+ -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
+ -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
+}
+
+/* buttons */
+button {
+ display: inline-block;
+ padding: 4px 14px;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 13px;
+ line-height: 18px;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ background-color: #0064cd;
+ background-repeat: repeat-x;
+ background-image: -khtml-gradient(linear, left top, left bottom, from(#049cdb), to(#0064cd));
+ background-image: -moz-linear-gradient(top, #049cdb, #0064cd);
+ background-image: -ms-linear-gradient(top, #049cdb, #0064cd);
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #049cdb), color-stop(100%, #0064cd));
+ background-image: -webkit-linear-gradient(top, #049cdb, #0064cd);
+ background-image: -o-linear-gradient(top, #049cdb, #0064cd);
+ background-image: linear-gradient(top, #049cdb, #0064cd);
+ color: #fff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ border: 1px solid #004b9a;
+ border-bottom-color: #003f81;
+ -webkit-transition: 0.1s linear all;
+ -moz-transition: 0.1s linear all;
+ transition: 0.1s linear all;
+ border-color: #0064cd #0064cd #003f81;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+}
+button:hover {
+ color: #fff;
+ background-position: 0 -15px;
+ text-decoration: none;
+}
+button:active {
+ -webkit-box-shadow: inset 0 3px 7px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 0 3px 7px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 3px 7px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+}
+button::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+}
diff --git a/examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc b/examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc
new file mode 100644
index 000000000..8b7471a9c
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc
@@ -0,0 +1,9 @@
+<RCC>
+ <qresource prefix="/">
+ <file>index.html</file>
+ <file>qwebchannel.js</file>
+ <file>marked.min.js</file>
+ <file>default.md</file>
+ <file>markdown.css</file>
+ </qresource>
+</RCC>
diff --git a/examples/webenginewidgets/markdowneditor/resources/marked.min.js b/examples/webenginewidgets/markdowneditor/resources/marked.min.js
new file mode 100644
index 000000000..f3542fff0
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/resources/marked.min.js
@@ -0,0 +1,6 @@
+/**
+ * marked - a markdown parser
+ * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
+ * https://github.com/chjj/marked
+ */
+(function(){var block={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:noop,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:noop,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,blockquote:/^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:noop,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,text:/^[^\n]+/};block.bullet=/(?:[*+-]|\d+\.)/;block.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;block.item=replace(block.item,"gm")(/bull/g,block.bullet)();block.list=replace(block.list)(/bull/g,block.bullet)("hr","\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))")("def","\\n+(?="+block.def.source+")")();block.blockquote=replace(block.blockquote)("def",block.def)();block._tag="(?!(?:"+"a|em|strong|small|s|cite|q|dfn|abbr|data|time|code"+"|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo"+"|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b";block.html=replace(block.html)("comment",/<!--[\s\S]*?-->/)("closed",/<(tag)[\s\S]+?<\/\1>/)("closing",/<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)(/tag/g,block._tag)();block.paragraph=replace(block.paragraph)("hr",block.hr)("heading",block.heading)("lheading",block.lheading)("blockquote",block.blockquote)("tag","<"+block._tag)("def",block.def)();block.normal=merge({},block);block.gfm=merge({},block.normal,{fences:/^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,paragraph:/^/,heading:/^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/});block.gfm.paragraph=replace(block.paragraph)("(?!","(?!"+block.gfm.fences.source.replace("\\1","\\2")+"|"+block.list.source.replace("\\1","\\3")+"|")();block.tables=merge({},block.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/});function Lexer(options){this.tokens=[];this.tokens.links={};this.options=options||marked.defaults;this.rules=block.normal;if(this.options.gfm){if(this.options.tables){this.rules=block.tables}else{this.rules=block.gfm}}}Lexer.rules=block;Lexer.lex=function(src,options){var lexer=new Lexer(options);return lexer.lex(src)};Lexer.prototype.lex=function(src){src=src.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n");return this.token(src,true)};Lexer.prototype.token=function(src,top,bq){var src=src.replace(/^ +$/gm,""),next,loose,cap,bull,b,item,space,i,l;while(src){if(cap=this.rules.newline.exec(src)){src=src.substring(cap[0].length);if(cap[0].length>1){this.tokens.push({type:"space"})}}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);cap=cap[0].replace(/^ {4}/gm,"");this.tokens.push({type:"code",text:!this.options.pedantic?cap.replace(/\n+$/,""):cap});continue}if(cap=this.rules.fences.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"code",lang:cap[2],text:cap[3]||""});continue}if(cap=this.rules.heading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[1].length,text:cap[2]});continue}if(top&&(cap=this.rules.nptable.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/\n$/,"").split("\n")};for(i=0;i<item.align.length;i++){if(/^ *-+: *$/.test(item.align[i])){item.align[i]="right"}else if(/^ *:-+: *$/.test(item.align[i])){item.align[i]="center"}else if(/^ *:-+ *$/.test(item.align[i])){item.align[i]="left"}else{item.align[i]=null}}for(i=0;i<item.cells.length;i++){item.cells[i]=item.cells[i].split(/ *\| */)}this.tokens.push(item);continue}if(cap=this.rules.lheading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[2]==="="?1:2,text:cap[1]});continue}if(cap=this.rules.hr.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"hr"});continue}if(cap=this.rules.blockquote.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"blockquote_start"});cap=cap[0].replace(/^ *> ?/gm,"");this.token(cap,top,true);this.tokens.push({type:"blockquote_end"});continue}if(cap=this.rules.list.exec(src)){src=src.substring(cap[0].length);bull=cap[2];this.tokens.push({type:"list_start",ordered:bull.length>1});cap=cap[0].match(this.rules.item);next=false;l=cap.length;i=0;for(;i<l;i++){item=cap[i];space=item.length;item=item.replace(/^ *([*+-]|\d+\.) +/,"");if(~item.indexOf("\n ")){space-=item.length;item=!this.options.pedantic?item.replace(new RegExp("^ {1,"+space+"}","gm"),""):item.replace(/^ {1,4}/gm,"")}if(this.options.smartLists&&i!==l-1){b=block.bullet.exec(cap[i+1])[0];if(bull!==b&&!(bull.length>1&&b.length>1)){src=cap.slice(i+1).join("\n")+src;i=l-1}}loose=next||/\n\n(?!\s*$)/.test(item);if(i!==l-1){next=item.charAt(item.length-1)==="\n";if(!loose)loose=next}this.tokens.push({type:loose?"loose_item_start":"list_item_start"});this.token(item,false,bq);this.tokens.push({type:"list_item_end"})}this.tokens.push({type:"list_end"});continue}if(cap=this.rules.html.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:!this.options.sanitizer&&(cap[1]==="pre"||cap[1]==="script"||cap[1]==="style"),text:cap[0]});continue}if(!bq&&top&&(cap=this.rules.def.exec(src))){src=src.substring(cap[0].length);this.tokens.links[cap[1].toLowerCase()]={href:cap[2],title:cap[3]};continue}if(top&&(cap=this.rules.table.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/(?: *\| *)?\n$/,"").split("\n")};for(i=0;i<item.align.length;i++){if(/^ *-+: *$/.test(item.align[i])){item.align[i]="right"}else if(/^ *:-+: *$/.test(item.align[i])){item.align[i]="center"}else if(/^ *:-+ *$/.test(item.align[i])){item.align[i]="left"}else{item.align[i]=null}}for(i=0;i<item.cells.length;i++){item.cells[i]=item.cells[i].replace(/^ *\| *| *\| *$/g,"").split(/ *\| */)}this.tokens.push(item);continue}if(top&&(cap=this.rules.paragraph.exec(src))){src=src.substring(cap[0].length);this.tokens.push({type:"paragraph",text:cap[1].charAt(cap[1].length-1)==="\n"?cap[1].slice(0,-1):cap[1]});continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"text",text:cap[0]});continue}if(src){throw new Error("Infinite loop on byte: "+src.charCodeAt(0))}}return this.tokens};var inline={escape:/^\\([\\`*{}\[\]()#+\-.!_>])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:noop,tag:/^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:noop,text:/^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/};inline._inside=/(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;inline._href=/\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;inline.link=replace(inline.link)("inside",inline._inside)("href",inline._href)();inline.reflink=replace(inline.reflink)("inside",inline._inside)();inline.normal=merge({},inline);inline.pedantic=merge({},inline.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/});inline.gfm=merge({},inline.normal,{escape:replace(inline.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:replace(inline.text)("]|","~]|")("|","|https?://|")()});inline.breaks=merge({},inline.gfm,{br:replace(inline.br)("{2,}","*")(),text:replace(inline.gfm.text)("{2,}","*")()});function InlineLexer(links,options){this.options=options||marked.defaults;this.links=links;this.rules=inline.normal;this.renderer=this.options.renderer||new Renderer;this.renderer.options=this.options;if(!this.links){throw new Error("Tokens array requires a `links` property.")}if(this.options.gfm){if(this.options.breaks){this.rules=inline.breaks}else{this.rules=inline.gfm}}else if(this.options.pedantic){this.rules=inline.pedantic}}InlineLexer.rules=inline;InlineLexer.output=function(src,links,options){var inline=new InlineLexer(links,options);return inline.output(src)};InlineLexer.prototype.output=function(src){var out="",link,text,href,cap;while(src){if(cap=this.rules.escape.exec(src)){src=src.substring(cap[0].length);out+=cap[1];continue}if(cap=this.rules.autolink.exec(src)){src=src.substring(cap[0].length);if(cap[2]==="@"){text=cap[1].charAt(6)===":"?this.mangle(cap[1].substring(7)):this.mangle(cap[1]);href=this.mangle("mailto:")+text}else{text=escape(cap[1]);href=text}out+=this.renderer.link(href,null,text);continue}if(!this.inLink&&(cap=this.rules.url.exec(src))){src=src.substring(cap[0].length);text=escape(cap[1]);href=text;out+=this.renderer.link(href,null,text);continue}if(cap=this.rules.tag.exec(src)){if(!this.inLink&&/^<a /i.test(cap[0])){this.inLink=true}else if(this.inLink&&/^<\/a>/i.test(cap[0])){this.inLink=false}src=src.substring(cap[0].length);out+=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(cap[0]):escape(cap[0]):cap[0];continue}if(cap=this.rules.link.exec(src)){src=src.substring(cap[0].length);this.inLink=true;out+=this.outputLink(cap,{href:cap[2],title:cap[3]});this.inLink=false;continue}if((cap=this.rules.reflink.exec(src))||(cap=this.rules.nolink.exec(src))){src=src.substring(cap[0].length);link=(cap[2]||cap[1]).replace(/\s+/g," ");link=this.links[link.toLowerCase()];if(!link||!link.href){out+=cap[0].charAt(0);src=cap[0].substring(1)+src;continue}this.inLink=true;out+=this.outputLink(cap,link);this.inLink=false;continue}if(cap=this.rules.strong.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.strong(this.output(cap[2]||cap[1]));continue}if(cap=this.rules.em.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.em(this.output(cap[2]||cap[1]));continue}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.codespan(escape(cap[2],true));continue}if(cap=this.rules.br.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.br();continue}if(cap=this.rules.del.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.del(this.output(cap[1]));continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.text(escape(this.smartypants(cap[0])));continue}if(src){throw new Error("Infinite loop on byte: "+src.charCodeAt(0))}}return out};InlineLexer.prototype.outputLink=function(cap,link){var href=escape(link.href),title=link.title?escape(link.title):null;return cap[0].charAt(0)!=="!"?this.renderer.link(href,title,this.output(cap[1])):this.renderer.image(href,title,escape(cap[1]))};InlineLexer.prototype.smartypants=function(text){if(!this.options.smartypants)return text;return text.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…")};InlineLexer.prototype.mangle=function(text){if(!this.options.mangle)return text;var out="",l=text.length,i=0,ch;for(;i<l;i++){ch=text.charCodeAt(i);if(Math.random()>.5){ch="x"+ch.toString(16)}out+="&#"+ch+";"}return out};function Renderer(options){this.options=options||{}}Renderer.prototype.code=function(code,lang,escaped){if(this.options.highlight){var out=this.options.highlight(code,lang);if(out!=null&&out!==code){escaped=true;code=out}}if(!lang){return"<pre><code>"+(escaped?code:escape(code,true))+"\n</code></pre>"}return'<pre><code class="'+this.options.langPrefix+escape(lang,true)+'">'+(escaped?code:escape(code,true))+"\n</code></pre>\n"};Renderer.prototype.blockquote=function(quote){return"<blockquote>\n"+quote+"</blockquote>\n"};Renderer.prototype.html=function(html){return html};Renderer.prototype.heading=function(text,level,raw){return"<h"+level+' id="'+this.options.headerPrefix+raw.toLowerCase().replace(/[^\w]+/g,"-")+'">'+text+"</h"+level+">\n"};Renderer.prototype.hr=function(){return this.options.xhtml?"<hr/>\n":"<hr>\n"};Renderer.prototype.list=function(body,ordered){var type=ordered?"ol":"ul";return"<"+type+">\n"+body+"</"+type+">\n"};Renderer.prototype.listitem=function(text){return"<li>"+text+"</li>\n"};Renderer.prototype.paragraph=function(text){return"<p>"+text+"</p>\n"};Renderer.prototype.table=function(header,body){return"<table>\n"+"<thead>\n"+header+"</thead>\n"+"<tbody>\n"+body+"</tbody>\n"+"</table>\n"};Renderer.prototype.tablerow=function(content){return"<tr>\n"+content+"</tr>\n"};Renderer.prototype.tablecell=function(content,flags){var type=flags.header?"th":"td";var tag=flags.align?"<"+type+' style="text-align:'+flags.align+'">':"<"+type+">";return tag+content+"</"+type+">\n"};Renderer.prototype.strong=function(text){return"<strong>"+text+"</strong>"};Renderer.prototype.em=function(text){return"<em>"+text+"</em>"};Renderer.prototype.codespan=function(text){return"<code>"+text+"</code>"};Renderer.prototype.br=function(){return this.options.xhtml?"<br/>":"<br>"};Renderer.prototype.del=function(text){return"<del>"+text+"</del>"};Renderer.prototype.link=function(href,title,text){if(this.options.sanitize){try{var prot=decodeURIComponent(unescape(href)).replace(/[^\w:]/g,"").toLowerCase()}catch(e){return""}if(prot.indexOf("javascript:")===0||prot.indexOf("vbscript:")===0){return""}}var out='<a href="'+href+'"';if(title){out+=' title="'+title+'"'}out+=">"+text+"</a>";return out};Renderer.prototype.image=function(href,title,text){var out='<img src="'+href+'" alt="'+text+'"';if(title){out+=' title="'+title+'"'}out+=this.options.xhtml?"/>":">";return out};Renderer.prototype.text=function(text){return text};function Parser(options){this.tokens=[];this.token=null;this.options=options||marked.defaults;this.options.renderer=this.options.renderer||new Renderer;this.renderer=this.options.renderer;this.renderer.options=this.options}Parser.parse=function(src,options,renderer){var parser=new Parser(options,renderer);return parser.parse(src)};Parser.prototype.parse=function(src){this.inline=new InlineLexer(src.links,this.options,this.renderer);this.tokens=src.reverse();var out="";while(this.next()){out+=this.tok()}return out};Parser.prototype.next=function(){return this.token=this.tokens.pop()};Parser.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0};Parser.prototype.parseText=function(){var body=this.token.text;while(this.peek().type==="text"){body+="\n"+this.next().text}return this.inline.output(body)};Parser.prototype.tok=function(){switch(this.token.type){case"space":{return""}case"hr":{return this.renderer.hr()}case"heading":{return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,this.token.text)}case"code":{return this.renderer.code(this.token.text,this.token.lang,this.token.escaped)}case"table":{var header="",body="",i,row,cell,flags,j;cell="";for(i=0;i<this.token.header.length;i++){flags={header:true,align:this.token.align[i]};cell+=this.renderer.tablecell(this.inline.output(this.token.header[i]),{header:true,align:this.token.align[i]})}header+=this.renderer.tablerow(cell);for(i=0;i<this.token.cells.length;i++){row=this.token.cells[i];cell="";for(j=0;j<row.length;j++){cell+=this.renderer.tablecell(this.inline.output(row[j]),{header:false,align:this.token.align[j]})}body+=this.renderer.tablerow(cell)}return this.renderer.table(header,body)}case"blockquote_start":{var body="";while(this.next().type!=="blockquote_end"){body+=this.tok()}return this.renderer.blockquote(body)}case"list_start":{var body="",ordered=this.token.ordered;while(this.next().type!=="list_end"){body+=this.tok()}return this.renderer.list(body,ordered)}case"list_item_start":{var body="";while(this.next().type!=="list_item_end"){body+=this.token.type==="text"?this.parseText():this.tok()}return this.renderer.listitem(body)}case"loose_item_start":{var body="";while(this.next().type!=="list_item_end"){body+=this.tok()}return this.renderer.listitem(body)}case"html":{var html=!this.token.pre&&!this.options.pedantic?this.inline.output(this.token.text):this.token.text;return this.renderer.html(html)}case"paragraph":{return this.renderer.paragraph(this.inline.output(this.token.text))}case"text":{return this.renderer.paragraph(this.parseText())}}};function escape(html,encode){return html.replace(!encode?/&(?!#?\w+;)/g:/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function unescape(html){return html.replace(/&([#\w]+);/g,function(_,n){n=n.toLowerCase();if(n==="colon")return":";if(n.charAt(0)==="#"){return n.charAt(1)==="x"?String.fromCharCode(parseInt(n.substring(2),16)):String.fromCharCode(+n.substring(1))}return""})}function replace(regex,opt){regex=regex.source;opt=opt||"";return function self(name,val){if(!name)return new RegExp(regex,opt);val=val.source||val;val=val.replace(/(^|[^\[])\^/g,"$1");regex=regex.replace(name,val);return self}}function noop(){}noop.exec=noop;function merge(obj){var i=1,target,key;for(;i<arguments.length;i++){target=arguments[i];for(key in target){if(Object.prototype.hasOwnProperty.call(target,key)){obj[key]=target[key]}}}return obj}function marked(src,opt,callback){if(callback||typeof opt==="function"){if(!callback){callback=opt;opt=null}opt=merge({},marked.defaults,opt||{});var highlight=opt.highlight,tokens,pending,i=0;try{tokens=Lexer.lex(src,opt)}catch(e){return callback(e)}pending=tokens.length;var done=function(err){if(err){opt.highlight=highlight;return callback(err)}var out;try{out=Parser.parse(tokens,opt)}catch(e){err=e}opt.highlight=highlight;return err?callback(err):callback(null,out)};if(!highlight||highlight.length<3){return done()}delete opt.highlight;if(!pending)return done();for(;i<tokens.length;i++){(function(token){if(token.type!=="code"){return--pending||done()}return highlight(token.text,token.lang,function(err,code){if(err)return done(err);if(code==null||code===token.text){return--pending||done()}token.text=code;token.escaped=true;--pending||done()})})(tokens[i])}return}try{if(opt)opt=merge({},marked.defaults,opt);return Parser.parse(Lexer.lex(src,opt),opt)}catch(e){e.message+="\nPlease report this to https://github.com/chjj/marked.";if((opt||marked.defaults).silent){return"<p>An error occurred:</p><pre>"+escape(e.message+"",true)+"</pre>"}throw e}}marked.options=marked.setOptions=function(opt){merge(marked.defaults,opt);return marked};marked.defaults={gfm:true,tables:true,breaks:false,pedantic:false,sanitize:false,sanitizer:null,mangle:true,smartLists:false,silent:false,highlight:null,langPrefix:"lang-",smartypants:false,headerPrefix:"",renderer:new Renderer,xhtml:false};marked.Parser=Parser;marked.parser=Parser.parse;marked.Renderer=Renderer;marked.Lexer=Lexer;marked.lexer=Lexer.lex;marked.InlineLexer=InlineLexer;marked.inlineLexer=InlineLexer.output;marked.parse=marked;if(typeof module!=="undefined"&&typeof exports==="object"){module.exports=marked}else if(typeof define==="function"&&define.amd){define(function(){return marked})}else{this.marked=marked}}).call(function(){return this||(typeof window!=="undefined"?window:global)}()); \ No newline at end of file
diff --git a/examples/webenginewidgets/markdowneditor/resources/qwebchannel.js b/examples/webenginewidgets/markdowneditor/resources/qwebchannel.js
new file mode 100644
index 000000000..d8c28bc66
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/resources/qwebchannel.js
@@ -0,0 +1,413 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebChannel module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+"use strict";
+
+var QWebChannelMessageTypes = {
+ signal: 1,
+ propertyUpdate: 2,
+ init: 3,
+ idle: 4,
+ debug: 5,
+ invokeMethod: 6,
+ connectToSignal: 7,
+ disconnectFromSignal: 8,
+ setProperty: 9,
+ response: 10,
+};
+
+var QWebChannel = function(transport, initCallback)
+{
+ if (typeof transport !== "object" || typeof transport.send !== "function") {
+ console.error("The QWebChannel expects a transport object with a send function and onmessage callback property." +
+ " Given is: transport: " + typeof(transport) + ", transport.send: " + typeof(transport.send));
+ return;
+ }
+
+ var channel = this;
+ this.transport = transport;
+
+ this.send = function(data)
+ {
+ if (typeof(data) !== "string") {
+ data = JSON.stringify(data);
+ }
+ channel.transport.send(data);
+ }
+
+ this.transport.onmessage = function(message)
+ {
+ var data = message.data;
+ if (typeof data === "string") {
+ data = JSON.parse(data);
+ }
+ switch (data.type) {
+ case QWebChannelMessageTypes.signal:
+ channel.handleSignal(data);
+ break;
+ case QWebChannelMessageTypes.response:
+ channel.handleResponse(data);
+ break;
+ case QWebChannelMessageTypes.propertyUpdate:
+ channel.handlePropertyUpdate(data);
+ break;
+ default:
+ console.error("invalid message received:", message.data);
+ break;
+ }
+ }
+
+ this.execCallbacks = {};
+ this.execId = 0;
+ this.exec = function(data, callback)
+ {
+ if (!callback) {
+ // if no callback is given, send directly
+ channel.send(data);
+ return;
+ }
+ if (channel.execId === Number.MAX_VALUE) {
+ // wrap
+ channel.execId = Number.MIN_VALUE;
+ }
+ if (data.hasOwnProperty("id")) {
+ console.error("Cannot exec message with property id: " + JSON.stringify(data));
+ return;
+ }
+ data.id = channel.execId++;
+ channel.execCallbacks[data.id] = callback;
+ channel.send(data);
+ };
+
+ this.objects = {};
+
+ this.handleSignal = function(message)
+ {
+ var object = channel.objects[message.object];
+ if (object) {
+ object.signalEmitted(message.signal, message.args);
+ } else {
+ console.warn("Unhandled signal: " + message.object + "::" + message.signal);
+ }
+ }
+
+ this.handleResponse = function(message)
+ {
+ if (!message.hasOwnProperty("id")) {
+ console.error("Invalid response message received: ", JSON.stringify(message));
+ return;
+ }
+ channel.execCallbacks[message.id](message.data);
+ delete channel.execCallbacks[message.id];
+ }
+
+ this.handlePropertyUpdate = function(message)
+ {
+ for (var i in message.data) {
+ var data = message.data[i];
+ var object = channel.objects[data.object];
+ if (object) {
+ object.propertyUpdate(data.signals, data.properties);
+ } else {
+ console.warn("Unhandled property update: " + data.object + "::" + data.signal);
+ }
+ }
+ channel.exec({type: QWebChannelMessageTypes.idle});
+ }
+
+ this.debug = function(message)
+ {
+ channel.send({type: QWebChannelMessageTypes.debug, data: message});
+ };
+
+ channel.exec({type: QWebChannelMessageTypes.init}, function(data) {
+ for (var objectName in data) {
+ var object = new QObject(objectName, data[objectName], channel);
+ }
+ // now unwrap properties, which might reference other registered objects
+ for (var objectName in channel.objects) {
+ channel.objects[objectName].unwrapProperties();
+ }
+ if (initCallback) {
+ initCallback(channel);
+ }
+ channel.exec({type: QWebChannelMessageTypes.idle});
+ });
+};
+
+function QObject(name, data, webChannel)
+{
+ this.__id__ = name;
+ webChannel.objects[name] = this;
+
+ // List of callbacks that get invoked upon signal emission
+ this.__objectSignals__ = {};
+
+ // Cache of all properties, updated when a notify signal is emitted
+ this.__propertyCache__ = {};
+
+ var object = this;
+
+ // ----------------------------------------------------------------------
+
+ this.unwrapQObject = function(response)
+ {
+ if (response instanceof Array) {
+ // support list of objects
+ var ret = new Array(response.length);
+ for (var i = 0; i < response.length; ++i) {
+ ret[i] = object.unwrapQObject(response[i]);
+ }
+ return ret;
+ }
+ if (!response
+ || !response["__QObject*__"]
+ || response.id === undefined) {
+ return response;
+ }
+
+ var objectId = response.id;
+ if (webChannel.objects[objectId])
+ return webChannel.objects[objectId];
+
+ if (!response.data) {
+ console.error("Cannot unwrap unknown QObject " + objectId + " without data.");
+ return;
+ }
+
+ var qObject = new QObject( objectId, response.data, webChannel );
+ qObject.destroyed.connect(function() {
+ if (webChannel.objects[objectId] === qObject) {
+ delete webChannel.objects[objectId];
+ // reset the now deleted QObject to an empty {} object
+ // just assigning {} though would not have the desired effect, but the
+ // below also ensures all external references will see the empty map
+ // NOTE: this detour is necessary to workaround QTBUG-40021
+ var propertyNames = [];
+ for (var propertyName in qObject) {
+ propertyNames.push(propertyName);
+ }
+ for (var idx in propertyNames) {
+ delete qObject[propertyNames[idx]];
+ }
+ }
+ });
+ // here we are already initialized, and thus must directly unwrap the properties
+ qObject.unwrapProperties();
+ return qObject;
+ }
+
+ this.unwrapProperties = function()
+ {
+ for (var propertyIdx in object.__propertyCache__) {
+ object.__propertyCache__[propertyIdx] = object.unwrapQObject(object.__propertyCache__[propertyIdx]);
+ }
+ }
+
+ function addSignal(signalData, isPropertyNotifySignal)
+ {
+ var signalName = signalData[0];
+ var signalIndex = signalData[1];
+ object[signalName] = {
+ connect: function(callback) {
+ if (typeof(callback) !== "function") {
+ console.error("Bad callback given to connect to signal " + signalName);
+ return;
+ }
+
+ object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || [];
+ object.__objectSignals__[signalIndex].push(callback);
+
+ if (!isPropertyNotifySignal && signalName !== "destroyed") {
+ // only required for "pure" signals, handled separately for properties in propertyUpdate
+ // also note that we always get notified about the destroyed signal
+ webChannel.exec({
+ type: QWebChannelMessageTypes.connectToSignal,
+ object: object.__id__,
+ signal: signalIndex
+ });
+ }
+ },
+ disconnect: function(callback) {
+ if (typeof(callback) !== "function") {
+ console.error("Bad callback given to disconnect from signal " + signalName);
+ return;
+ }
+ object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || [];
+ var idx = object.__objectSignals__[signalIndex].indexOf(callback);
+ if (idx === -1) {
+ console.error("Cannot find connection of signal " + signalName + " to " + callback.name);
+ return;
+ }
+ object.__objectSignals__[signalIndex].splice(idx, 1);
+ if (!isPropertyNotifySignal && object.__objectSignals__[signalIndex].length === 0) {
+ // only required for "pure" signals, handled separately for properties in propertyUpdate
+ webChannel.exec({
+ type: QWebChannelMessageTypes.disconnectFromSignal,
+ object: object.__id__,
+ signal: signalIndex
+ });
+ }
+ }
+ };
+ }
+
+ /**
+ * Invokes all callbacks for the given signalname. Also works for property notify callbacks.
+ */
+ function invokeSignalCallbacks(signalName, signalArgs)
+ {
+ var connections = object.__objectSignals__[signalName];
+ if (connections) {
+ connections.forEach(function(callback) {
+ callback.apply(callback, signalArgs);
+ });
+ }
+ }
+
+ this.propertyUpdate = function(signals, propertyMap)
+ {
+ // update property cache
+ for (var propertyIndex in propertyMap) {
+ var propertyValue = propertyMap[propertyIndex];
+ object.__propertyCache__[propertyIndex] = propertyValue;
+ }
+
+ for (var signalName in signals) {
+ // Invoke all callbacks, as signalEmitted() does not. This ensures the
+ // property cache is updated before the callbacks are invoked.
+ invokeSignalCallbacks(signalName, signals[signalName]);
+ }
+ }
+
+ this.signalEmitted = function(signalName, signalArgs)
+ {
+ invokeSignalCallbacks(signalName, signalArgs);
+ }
+
+ function addMethod(methodData)
+ {
+ var methodName = methodData[0];
+ var methodIdx = methodData[1];
+ object[methodName] = function() {
+ var args = [];
+ var callback;
+ for (var i = 0; i < arguments.length; ++i) {
+ if (typeof arguments[i] === "function")
+ callback = arguments[i];
+ else
+ args.push(arguments[i]);
+ }
+
+ webChannel.exec({
+ "type": QWebChannelMessageTypes.invokeMethod,
+ "object": object.__id__,
+ "method": methodIdx,
+ "args": args
+ }, function(response) {
+ if (response !== undefined) {
+ var result = object.unwrapQObject(response);
+ if (callback) {
+ (callback)(result);
+ }
+ }
+ });
+ };
+ }
+
+ function bindGetterSetter(propertyInfo)
+ {
+ var propertyIndex = propertyInfo[0];
+ var propertyName = propertyInfo[1];
+ var notifySignalData = propertyInfo[2];
+ // initialize property cache with current value
+ // NOTE: if this is an object, it is not directly unwrapped as it might
+ // reference other QObject that we do not know yet
+ object.__propertyCache__[propertyIndex] = propertyInfo[3];
+
+ if (notifySignalData) {
+ if (notifySignalData[0] === 1) {
+ // signal name is optimized away, reconstruct the actual name
+ notifySignalData[0] = propertyName + "Changed";
+ }
+ addSignal(notifySignalData, true);
+ }
+
+ Object.defineProperty(object, propertyName, {
+ configurable: true,
+ get: function () {
+ var propertyValue = object.__propertyCache__[propertyIndex];
+ if (propertyValue === undefined) {
+ // This shouldn't happen
+ console.warn("Undefined value in property cache for property \"" + propertyName + "\" in object " + object.__id__);
+ }
+
+ return propertyValue;
+ },
+ set: function(value) {
+ if (value === undefined) {
+ console.warn("Property setter for " + propertyName + " called with undefined value!");
+ return;
+ }
+ object.__propertyCache__[propertyIndex] = value;
+ webChannel.exec({
+ "type": QWebChannelMessageTypes.setProperty,
+ "object": object.__id__,
+ "property": propertyIndex,
+ "value": value
+ });
+ }
+ });
+
+ }
+
+ // ----------------------------------------------------------------------
+
+ data.methods.forEach(addMethod);
+
+ data.properties.forEach(bindGetterSetter);
+
+ data.signals.forEach(function(signal) { addSignal(signal, false); });
+
+ for (var name in data.enums) {
+ object[name] = data.enums[name];
+ }
+}
+
+//required for use with nodejs
+if (typeof module === 'object') {
+ module.exports = {
+ QWebChannel: QWebChannel
+ };
+}
diff --git a/src/core/api/qwebenginecallback.h b/src/core/api/qwebenginecallback.h
index ddee20d06..b675438f5 100644
--- a/src/core/api/qwebenginecallback.h
+++ b/src/core/api/qwebenginecallback.h
@@ -81,12 +81,19 @@ public:
: d(new QtWebEnginePrivate::QWebEngineCallbackPrivate<T, F>(f))
{ }
QWebEngineCallback() { }
+ void swap(QWebEngineCallback &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
operator bool() const { return d; }
private:
friend class QtWebEngineCore::CallbackDirectory;
QExplicitlySharedDataPointer<QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> > d;
};
+Q_DECLARE_SHARED(QWebEngineCallback<int>)
+Q_DECLARE_SHARED(QWebEngineCallback<const QByteArray &>)
+Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineCallback<bool>)
+Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineCallback<const QString &>)
+Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineCallback<const QVariant &>)
+
QT_END_NAMESPACE
#endif // QWEBENGINECALLBACK_H
diff --git a/src/core/api/qwebenginecallback_p.h b/src/core/api/qwebenginecallback_p.h
index f0c25fe9e..9bc9b9727 100644
--- a/src/core/api/qwebenginecallback_p.h
+++ b/src/core/api/qwebenginecallback_p.h
@@ -47,6 +47,7 @@
#include <QVariant>
#include <type_traits>
+// keep in sync with Q_DECLARE_SHARED... in qwebenginecallback.h
#define FOR_EACH_TYPE(F) \
F(bool) \
F(int) \
@@ -227,6 +228,11 @@ void CallbackDirectory::CallbackSharedDataPointer<T>::invokeEmpty()
parent->invokeEmptyInternal(callback);
}
+#define CHECK_RELOCATABLE(x) \
+ Q_STATIC_ASSERT((QTypeInfoQuery<QWebEngineCallback< x > >::isRelocatable));
+FOR_EACH_TYPE(CHECK_RELOCATABLE)
+#undef CHECK_RELOCATABLE
+
} // namespace QtWebEngineCore
#endif // QWEBENGINECALLBACK_P_H
diff --git a/src/core/api/qwebenginecookiestoreclient.cpp b/src/core/api/qwebenginecookiestoreclient.cpp
index 167b3f68c..bd43b871d 100644
--- a/src/core/api/qwebenginecookiestoreclient.cpp
+++ b/src/core/api/qwebenginecookiestoreclient.cpp
@@ -181,7 +181,7 @@ bool QWebEngineCookieStoreClientPrivate::canSetCookie(const QUrl &firstPartyUrl,
request.firstPartyUrl = firstPartyUrl;
request.cookieLine = cookieLine;
request.cookieSource = url;
- callbackDirectory.invokeDirectly<const QWebEngineCookieStoreClient::FilterRequest&>(filterCallback, request);
+ callbackDirectory.invokeDirectly<QWebEngineCookieStoreClient::FilterRequest&>(filterCallback, request);
return request.accepted;
}
return true;
@@ -394,7 +394,7 @@ void QWebEngineCookieStoreClient::deleteAllCookies()
\sa deleteAllCookiesWithCallback(), getAllCookies()
*/
-void QWebEngineCookieStoreClient::setCookieFilter(const QWebEngineCallback<const QWebEngineCookieStoreClient::FilterRequest&> &filter)
+void QWebEngineCookieStoreClient::setCookieFilter(const QWebEngineCallback<QWebEngineCookieStoreClient::FilterRequest&> &filter)
{
Q_D(QWebEngineCookieStoreClient);
d->filterCallback = filter;
diff --git a/src/core/api/qwebenginecookiestoreclient.h b/src/core/api/qwebenginecookiestoreclient.h
index 8bdb988e2..4664a8459 100644
--- a/src/core/api/qwebenginecookiestoreclient.h
+++ b/src/core/api/qwebenginecookiestoreclient.h
@@ -77,7 +77,7 @@ public:
void deleteSessionCookiesWithCallback(const QWebEngineCallback<int> &resultCallback);
void deleteAllCookiesWithCallback(const QWebEngineCallback<int> &resultCallback);
void getAllCookies(const QWebEngineCallback<const QByteArray&> &resultCallback);
- void setCookieFilter(const QWebEngineCallback<const FilterRequest&> &filterCallback);
+ void setCookieFilter(const QWebEngineCallback<FilterRequest&> &filterCallback);
#endif
void setCookie(const QNetworkCookie &cookie, const QUrl &origin = QUrl());
void deleteCookie(const QNetworkCookie &cookie, const QUrl &origin = QUrl());
diff --git a/src/core/api/qwebenginecookiestoreclient_p.h b/src/core/api/qwebenginecookiestoreclient_p.h
index 43652fba6..54f3b9eb7 100644
--- a/src/core/api/qwebenginecookiestoreclient_p.h
+++ b/src/core/api/qwebenginecookiestoreclient_p.h
@@ -53,8 +53,7 @@
#include "qwebenginecallback_p.h"
#include "qwebenginecookiestoreclient.h"
-#include <QList>
-#include <QMap>
+#include <QVector>
#include <QNetworkCookie>
#include <QUrl>
@@ -70,12 +69,12 @@ class QWEBENGINE_PRIVATE_EXPORT QWebEngineCookieStoreClientPrivate {
QNetworkCookie cookie;
QUrl origin;
};
-
+ friend class QTypeInfo<CookieData>;
public:
Q_DECLARE_PUBLIC(QWebEngineCookieStoreClient)
QtWebEngineCore::CallbackDirectory callbackDirectory;
- QWebEngineCallback<const QWebEngineCookieStoreClient::FilterRequest&> filterCallback;
- QList<CookieData> m_pendingUserCookies;
+ QWebEngineCallback<QWebEngineCookieStoreClient::FilterRequest&> filterCallback;
+ QVector<CookieData> m_pendingUserCookies;
quint64 m_nextCallbackId;
bool m_deleteSessionCookiesPending;
bool m_deleteAllCookiesPending;
@@ -102,6 +101,8 @@ public:
void onCookieChanged(const QNetworkCookie &cookie, bool removed);
};
+Q_DECLARE_TYPEINFO(QWebEngineCookieStoreClientPrivate::CookieData, Q_MOVABLE_TYPE);
+
QT_END_NAMESPACE
#endif // QWEBENGINECOOKIESTORECLIENT_P_H
diff --git a/src/core/api/qwebengineurlschemehandler.cpp b/src/core/api/qwebengineurlschemehandler.cpp
index f887e4e98..7f9ebaf48 100644
--- a/src/core/api/qwebengineurlschemehandler.cpp
+++ b/src/core/api/qwebengineurlschemehandler.cpp
@@ -75,7 +75,6 @@ QWebEngineUrlSchemeHandler::QWebEngineUrlSchemeHandler(QObject *parent)
QWebEngineUrlSchemeHandler::~QWebEngineUrlSchemeHandler()
{
Q_EMIT destroyed(this);
- delete d_ptr;
}
/*!
diff --git a/src/core/api/qwebengineurlschemehandler.h b/src/core/api/qwebengineurlschemehandler.h
index 8c1e52646..66aebe00d 100644
--- a/src/core/api/qwebengineurlschemehandler.h
+++ b/src/core/api/qwebengineurlschemehandler.h
@@ -48,7 +48,6 @@ class URLRequestContextGetterQt;
QT_BEGIN_NAMESPACE
class QWebEngineUrlRequestJob;
-class QWebEngineUrlSchemeHandlerPrivate;
class QWEBENGINE_EXPORT QWebEngineUrlSchemeHandler : public QObject {
Q_OBJECT
@@ -63,8 +62,6 @@ Q_SIGNALS:
private:
Q_DISABLE_COPY(QWebEngineUrlSchemeHandler)
- Q_DECLARE_PRIVATE(QWebEngineUrlSchemeHandler)
- QWebEngineUrlSchemeHandlerPrivate *d_ptr;
};
QT_END_NAMESPACE
diff --git a/src/core/chrome_qt.gyp b/src/core/chrome_qt.gyp
index 2d2abe802..6c8e0d4d6 100644
--- a/src/core/chrome_qt.gyp
+++ b/src/core/chrome_qt.gyp
@@ -20,13 +20,13 @@
'<(SHARED_INTERMEDIATE_DIR)/components/strings',
],
'sources': [
- '<(chromium_src_dir)/chrome/browser/media/desktop_streams_registry.cc',
- '<(chromium_src_dir)/chrome/browser/media/desktop_streams_registry.h',
- '<(chromium_src_dir)/chrome/browser/media/desktop_media_list.h',
- '<(chromium_src_dir)/chrome/common/chrome_switches.cc',
- '<(chromium_src_dir)/chrome/common/chrome_switches.h',
- '<(chromium_src_dir)/chrome/common/localized_error.cc',
- '<(chromium_src_dir)/chrome/common/localized_error.h',
+ '<(DEPTH)/chrome/browser/media/desktop_streams_registry.cc',
+ '<(DEPTH)/chrome/browser/media/desktop_streams_registry.h',
+ '<(DEPTH)/chrome/browser/media/desktop_media_list.h',
+ '<(DEPTH)/chrome/common/chrome_switches.cc',
+ '<(DEPTH)/chrome/common/chrome_switches.h',
+ '<(DEPTH)/chrome/common/localized_error.cc',
+ '<(DEPTH)/chrome/common/localized_error.h',
],
},
{
diff --git a/src/core/common/qt_messages.h b/src/core/common/qt_messages.h
index 25a995b27..ae36a0d7f 100644
--- a/src/core/common/qt_messages.h
+++ b/src/core/common/qt_messages.h
@@ -25,13 +25,13 @@ IPC_STRUCT_TRAITS_END()
// RenderView messages
// These are messages sent from the browser to the renderer process.
-IPC_MESSAGE_ROUTED1(QtRenderViewObserver_FetchDocumentMarkup,
+IPC_MESSAGE_ROUTED1(RenderViewObserverQt_FetchDocumentMarkup,
uint64 /* requestId */)
-IPC_MESSAGE_ROUTED1(QtRenderViewObserver_FetchDocumentInnerText,
+IPC_MESSAGE_ROUTED1(RenderViewObserverQt_FetchDocumentInnerText,
uint64 /* requestId */)
-IPC_MESSAGE_ROUTED1(QtRenderViewObserver_SetBackgroundColor,
+IPC_MESSAGE_ROUTED1(RenderViewObserverQt_SetBackgroundColor,
uint32 /* color */)
IPC_MESSAGE_ROUTED1(WebChannelIPCTransport_Message, std::vector<char> /*binaryJSON*/)
@@ -51,14 +51,14 @@ IPC_MESSAGE_CONTROL0(UserScriptController_ClearScripts)
// WebContents messages
// These are messages sent from the renderer back to the browser process.
-IPC_MESSAGE_ROUTED2(QtRenderViewObserverHost_DidFetchDocumentMarkup,
+IPC_MESSAGE_ROUTED2(RenderViewObserverHostQt_DidFetchDocumentMarkup,
uint64 /* requestId */,
base::string16 /* markup */)
-IPC_MESSAGE_ROUTED2(QtRenderViewObserverHost_DidFetchDocumentInnerText,
+IPC_MESSAGE_ROUTED2(RenderViewObserverHostQt_DidFetchDocumentInnerText,
uint64 /* requestId */,
base::string16 /* innerText */)
-IPC_MESSAGE_ROUTED0(QtRenderViewObserverHost_DidFirstVisuallyNonEmptyLayout)
+IPC_MESSAGE_ROUTED0(RenderViewObserverHostQt_DidFirstVisuallyNonEmptyLayout)
IPC_MESSAGE_ROUTED1(WebChannelIPCTransportHost_SendMessage, std::vector<char> /*binaryJSON*/)
diff --git a/src/core/common/user_script_data.h b/src/core/common/user_script_data.h
index 3dfec0ec3..d0856e02a 100644
--- a/src/core/common/user_script_data.h
+++ b/src/core/common/user_script_data.h
@@ -60,4 +60,10 @@ struct UserScriptData {
uint64 scriptId;
};
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_TYPEINFO(UserScriptData, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
#endif // USER_SCRIPT_DATA_H
diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri
index 85dfe69ae..c3398757e 100644
--- a/src/core/config/linux.pri
+++ b/src/core/config/linux.pri
@@ -27,9 +27,9 @@ GYP_CONFIG += \
contains(QT_CONFIG, system-zlib): use?(system_minizip): GYP_CONFIG += use_system_zlib=1
contains(QT_CONFIG, system-png): GYP_CONFIG += use_system_libpng=1
contains(QT_CONFIG, system-jpeg): GYP_CONFIG += use_system_libjpeg=1
+contains(QT_CONFIG, system-harfbuzz): GYP_CONFIG += use_system_harfbuzz=1
!contains(QT_CONFIG, pulseaudio): GYP_CONFIG += use_pulseaudio=0
-
-use?(system_harfbuzz): GYP_CONFIG += use_system_harfbuzz=1
+!contains(QT_CONFIG, glib): GYP_CONFIG += use_glib=0
use?(system_libevent): GYP_CONFIG += use_system_libevent=1
use?(system_libwebp): GYP_CONFIG += use_system_libwebp=1
use?(system_libsrtp): GYP_CONFIG += use_system_libsrtp=1
diff --git a/src/core/cookie_monster_delegate_qt.h b/src/core/cookie_monster_delegate_qt.h
index 7592d57fa..db80bf0a1 100644
--- a/src/core/cookie_monster_delegate_qt.h
+++ b/src/core/cookie_monster_delegate_qt.h
@@ -47,7 +47,6 @@ QT_WARNING_DISABLE_CLANG("-Wunused-parameter")
#include "net/cookies/cookie_monster.h"
QT_WARNING_POP
-#include <QList>
#include <QNetworkCookie>
#include <QPointer>
diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro
index 813626dc3..14b8d78e2 100644
--- a/src/core/core_gyp_generator.pro
+++ b/src/core/core_gyp_generator.pro
@@ -62,15 +62,15 @@ SOURCES = \
process_main.cpp \
proxy_config_service_qt.cpp \
qrc_protocol_handler_qt.cpp \
- qt_render_view_observer_host.cpp \
+ render_view_observer_host_qt.cpp \
render_widget_host_view_qt.cpp \
renderer/content_renderer_client_qt.cpp \
renderer/pepper/pepper_flash_browser_host_qt.cpp \
renderer/pepper/pepper_flash_renderer_host_qt.cpp \
renderer/pepper/pepper_host_factory_qt.cpp \
renderer/pepper/pepper_renderer_host_factory_qt.cpp \
- renderer/qt_render_frame_observer.cpp \
- renderer/qt_render_view_observer.cpp \
+ renderer/render_frame_observer_qt.cpp \
+ renderer/render_view_observer_qt.cpp \
renderer/user_script_controller.cpp \
renderer/web_channel_ipc_transport.cpp \
resource_bundle_qt.cpp \
@@ -134,7 +134,7 @@ HEADERS = \
process_main.h \
proxy_config_service_qt.h \
qrc_protocol_handler_qt.h \
- qt_render_view_observer_host.h \
+ render_view_observer_host_qt.h \
render_widget_host_view_qt.h \
render_widget_host_view_qt_delegate.h \
renderer/content_renderer_client_qt.h \
@@ -142,8 +142,8 @@ HEADERS = \
renderer/pepper/pepper_flash_renderer_host_qt.h \
renderer/pepper/pepper_host_factory_qt.h \
renderer/pepper/pepper_renderer_host_factory_qt.h \
- renderer/qt_render_frame_observer.h \
- renderer/qt_render_view_observer.h \
+ renderer/render_frame_observer_qt.h \
+ renderer/render_view_observer_qt.h \
renderer/user_script_controller.h \
renderer/web_channel_ipc_transport.h \
resource_context_qt.h \
diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp
index 724c2c9bc..a2836d5e6 100644
--- a/src/core/delegated_frame_node.cpp
+++ b/src/core/delegated_frame_node.cpp
@@ -56,6 +56,7 @@
#include "cc/output/delegated_frame_data.h"
#include "cc/quads/debug_border_draw_quad.h"
#include "cc/quads/draw_quad.h"
+#include "cc/quads/io_surface_draw_quad.h"
#include "cc/quads/render_pass_draw_quad.h"
#include "cc/quads/solid_color_draw_quad.h"
#include "cc/quads/stream_video_draw_quad.h"
@@ -79,6 +80,10 @@
#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
#endif
+#ifndef GL_TEXTURE_RECTANGLE
+#define GL_TEXTURE_RECTANGLE 0x84F5
+#endif
+
namespace QtWebEngineCore {
class MailboxTexture : public QSGTexture, protected QOpenGLFunctions {
@@ -130,7 +135,7 @@ private:
QSGGeometry m_geometry;
};
-static inline QSharedPointer<QSGLayer> findRenderPassLayer(const cc::RenderPassId &id, const QList<QPair<cc::RenderPassId, QSharedPointer<QSGLayer> > > &list)
+static inline QSharedPointer<QSGLayer> findRenderPassLayer(const cc::RenderPassId &id, const QVector<QPair<cc::RenderPassId, QSharedPointer<QSGLayer> > > &list)
{
typedef QPair<cc::RenderPassId, QSharedPointer<QSGLayer> > Pair;
Q_FOREACH (const Pair &pair, list)
@@ -646,13 +651,29 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData,
MailboxTexture *texture = static_cast<MailboxTexture *>(initAndHoldTexture(resource, quad->ShouldDrawWithBlending()));
texture->setTarget(GL_TEXTURE_EXTERNAL_OES); // since this is not default TEXTURE_2D type
- StreamVideoNode *svideoNode = new StreamVideoNode(texture);
+ StreamVideoNode *svideoNode = new StreamVideoNode(texture, false, ExternalTarget);
svideoNode->setRect(toQt(squad->rect));
svideoNode->setTextureMatrix(toQt(squad->matrix.matrix()));
currentLayerChain->appendChildNode(svideoNode);
break;
#endif
- } default:
+ }
+ case cc::DrawQuad::IO_SURFACE_CONTENT: {
+ const cc::IOSurfaceDrawQuad *ioquad = cc::IOSurfaceDrawQuad::MaterialCast(quad);
+ ResourceHolder *resource = findAndHoldResource(ioquad->io_surface_resource_id(), resourceCandidates);
+ MailboxTexture *texture = static_cast<MailboxTexture *>(initAndHoldTexture(resource, quad->ShouldDrawWithBlending()));
+ texture->setTarget(GL_TEXTURE_RECTANGLE);
+
+ bool flip = ioquad->orientation != cc::IOSurfaceDrawQuad::FLIPPED;
+ StreamVideoNode *svideoNode = new StreamVideoNode(texture, flip, RectangleTarget);
+ QMatrix4x4 matrix;
+ matrix.scale(ioquad->io_surface_size.width(), ioquad->io_surface_size.height());
+ svideoNode->setRect(toQt(ioquad->rect));
+ svideoNode->setTextureMatrix(matrix);
+ currentLayerChain->appendChildNode(svideoNode);
+ break;
+ }
+ default:
qWarning("Unimplemented quad material: %d", quad->material);
}
}
diff --git a/src/core/delegated_frame_node.h b/src/core/delegated_frame_node.h
index 60a1535d2..eed03fadd 100644
--- a/src/core/delegated_frame_node.h
+++ b/src/core/delegated_frame_node.h
@@ -90,9 +90,9 @@ private:
QExplicitlySharedDataPointer<ChromiumCompositorData> m_chromiumCompositorData;
struct SGObjects {
- QList<QPair<cc::RenderPassId, QSharedPointer<QSGLayer> > > renderPassLayers;
- QList<QSharedPointer<QSGRootNode> > renderPassRootNodes;
- QList<QSharedPointer<QSGTexture> > textureStrongRefs;
+ QVector<QPair<cc::RenderPassId, QSharedPointer<QSGLayer> > > renderPassLayers;
+ QVector<QSharedPointer<QSGRootNode> > renderPassRootNodes;
+ QVector<QSharedPointer<QSGTexture> > textureStrongRefs;
} m_sgObjects;
int m_numPendingSyncPoints;
QMap<uint32, gfx::TransferableFence> m_mailboxGLFences;
diff --git a/src/core/gl_context_qt.cpp b/src/core/gl_context_qt.cpp
index b350c3c5b..3c3b8225d 100644
--- a/src/core/gl_context_qt.cpp
+++ b/src/core/gl_context_qt.cpp
@@ -146,10 +146,14 @@ scoped_refptr<GLContext> GLContext::CreateGLContext(GLShareGroup* share_group, G
{
#if defined(OS_WIN)
scoped_refptr<GLContext> context;
- if (GetGLImplementation() == kGLImplementationDesktopGL)
+ if (GetGLImplementation() == kGLImplementationDesktopGL) {
context = new GLContextWGL(share_group);
- else
+ if (!context->Initialize(compatible_surface, gpu_preference))
+ return nullptr;
+ return context;
+ } else {
context = new GLContextEGL(share_group);
+ }
#else
scoped_refptr<GLContext> context = new GLContextEGL(share_group);
#endif
diff --git a/src/core/location_provider_qt.cpp b/src/core/location_provider_qt.cpp
index e3be01b36..222d15354 100644
--- a/src/core/location_provider_qt.cpp
+++ b/src/core/location_provider_qt.cpp
@@ -88,12 +88,15 @@ QtPositioningHelper::~QtPositioningHelper()
m_locationProvider->m_positioningHelper = 0;
}
+static bool isHighAccuracySource(const QGeoPositionInfoSource *source)
+{
+ return source->supportedPositioningMethods().testFlag(
+ QGeoPositionInfoSource::SatellitePositioningMethods);
+}
+
void QtPositioningHelper::start(bool highAccuracy)
{
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- Q_UNUSED(highAccuracy);
- // FIXME: go through availableSources until one supports QGeoPositionInfoSource::SatellitePositioningMethods
- // for the highAccuracy case.
m_positionInfoSource = QGeoPositionInfoSource::createDefaultSource(this);
if (!m_positionInfoSource) {
qWarning("Failed to initialize location provider: The system either has no default "
@@ -103,6 +106,23 @@ void QtPositioningHelper::start(bool highAccuracy)
return;
}
+ // Find high accuracy source if the default source is not already one.
+ if (highAccuracy && !isHighAccuracySource(m_positionInfoSource)) {
+ Q_FOREACH (const QString &name, QGeoPositionInfoSource::availableSources()) {
+ if (name == m_positionInfoSource->sourceName())
+ continue;
+ QGeoPositionInfoSource *source = QGeoPositionInfoSource::createSource(name, this);
+ if (source && isHighAccuracySource(source)) {
+ delete m_positionInfoSource;
+ m_positionInfoSource = source;
+ break;
+ }
+ delete source;
+ }
+ m_positionInfoSource->setPreferredPositioningMethods(
+ QGeoPositionInfoSource::SatellitePositioningMethods);
+ }
+
connect(m_positionInfoSource, &QGeoPositionInfoSource::positionUpdated, this, &QtPositioningHelper::updatePosition);
// disambiguate the error getter and the signal in QGeoPositionInfoSource.
connect(m_positionInfoSource, static_cast<void (QGeoPositionInfoSource::*)(QGeoPositionInfoSource::Error)>(&QGeoPositionInfoSource::error)
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index d93f9c331..19204b270 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -83,8 +83,7 @@ void PermissionManagerQt::permissionRequestReply(const QUrl &origin, BrowserCont
m_permissions[key] = reply;
content::PermissionStatus status = reply ? content::PERMISSION_STATUS_GRANTED : content::PERMISSION_STATUS_DENIED;
auto it = m_requests.begin();
- const auto end = m_requests.end();
- while (it != end) {
+ while (it != m_requests.end()) {
if (it->origin == origin && it->type == type) {
it->callback.Run(status);
it = m_requests.erase(it);
diff --git a/src/core/qtwebengine.gypi b/src/core/qtwebengine.gypi
index a420918a0..96b48e2ca 100644
--- a/src/core/qtwebengine.gypi
+++ b/src/core/qtwebengine.gypi
@@ -13,6 +13,8 @@
'<(chromium_src_dir)/components/components.gyp:error_page_renderer',
'<(chromium_src_dir)/components/components.gyp:visitedlink_browser',
'<(chromium_src_dir)/components/components.gyp:visitedlink_renderer',
+ '<(chromium_src_dir)/components/components.gyp:web_cache_browser',
+ '<(chromium_src_dir)/components/components.gyp:web_cache_renderer',
'<(chromium_src_dir)/content/content.gyp:content',
'<(chromium_src_dir)/content/content.gyp:content_app_browser',
'<(chromium_src_dir)/content/content.gyp:content_browser',
diff --git a/src/core/qt_render_view_observer_host.cpp b/src/core/render_view_observer_host_qt.cpp
index 97d001ed6..03c9d241f 100644
--- a/src/core/qt_render_view_observer_host.cpp
+++ b/src/core/render_view_observer_host_qt.cpp
@@ -34,7 +34,7 @@
**
****************************************************************************/
-#include "qt_render_view_observer_host.h"
+#include "render_view_observer_host_qt.h"
#include "common/qt_messages.h"
#include "content/public/browser/web_contents.h"
@@ -44,31 +44,31 @@
namespace QtWebEngineCore {
-QtRenderViewObserverHost::QtRenderViewObserverHost(content::WebContents *webContents, WebContentsAdapterClient *adapterClient)
+RenderViewObserverHostQt::RenderViewObserverHostQt(content::WebContents *webContents, WebContentsAdapterClient *adapterClient)
: content::WebContentsObserver(webContents)
, m_adapterClient(adapterClient)
{
}
-void QtRenderViewObserverHost::fetchDocumentMarkup(quint64 requestId)
+void RenderViewObserverHostQt::fetchDocumentMarkup(quint64 requestId)
{
- Send(new QtRenderViewObserver_FetchDocumentMarkup(routing_id(), requestId));
+ Send(new RenderViewObserverQt_FetchDocumentMarkup(routing_id(), requestId));
}
-void QtRenderViewObserverHost::fetchDocumentInnerText(quint64 requestId)
+void RenderViewObserverHostQt::fetchDocumentInnerText(quint64 requestId)
{
- Send(new QtRenderViewObserver_FetchDocumentInnerText(routing_id(), requestId));
+ Send(new RenderViewObserverQt_FetchDocumentInnerText(routing_id(), requestId));
}
-bool QtRenderViewObserverHost::OnMessageReceived(const IPC::Message& message)
+bool RenderViewObserverHostQt::OnMessageReceived(const IPC::Message& message)
{
bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(QtRenderViewObserverHost, message)
- IPC_MESSAGE_HANDLER(QtRenderViewObserverHost_DidFetchDocumentMarkup,
+ IPC_BEGIN_MESSAGE_MAP(RenderViewObserverHostQt, message)
+ IPC_MESSAGE_HANDLER(RenderViewObserverHostQt_DidFetchDocumentMarkup,
onDidFetchDocumentMarkup)
- IPC_MESSAGE_HANDLER(QtRenderViewObserverHost_DidFetchDocumentInnerText,
+ IPC_MESSAGE_HANDLER(RenderViewObserverHostQt_DidFetchDocumentInnerText,
onDidFetchDocumentInnerText)
- IPC_MESSAGE_HANDLER(QtRenderViewObserverHost_DidFirstVisuallyNonEmptyLayout,
+ IPC_MESSAGE_HANDLER(RenderViewObserverHostQt_DidFirstVisuallyNonEmptyLayout,
onDidFirstVisuallyNonEmptyLayout)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -76,17 +76,17 @@ bool QtRenderViewObserverHost::OnMessageReceived(const IPC::Message& message)
}
-void QtRenderViewObserverHost::onDidFetchDocumentMarkup(quint64 requestId, const base::string16& markup)
+void RenderViewObserverHostQt::onDidFetchDocumentMarkup(quint64 requestId, const base::string16& markup)
{
m_adapterClient->didFetchDocumentMarkup(requestId, toQt(markup));
}
-void QtRenderViewObserverHost::onDidFetchDocumentInnerText(quint64 requestId, const base::string16& innerText)
+void RenderViewObserverHostQt::onDidFetchDocumentInnerText(quint64 requestId, const base::string16& innerText)
{
m_adapterClient->didFetchDocumentInnerText(requestId, toQt(innerText));
}
-void QtRenderViewObserverHost::onDidFirstVisuallyNonEmptyLayout()
+void RenderViewObserverHostQt::onDidFirstVisuallyNonEmptyLayout()
{
RenderWidgetHostViewQt *rwhv = static_cast<RenderWidgetHostViewQt*>(web_contents()->GetRenderWidgetHostView());
if (rwhv)
diff --git a/src/core/qt_render_view_observer_host.h b/src/core/render_view_observer_host_qt.h
index 148fcb9da..2683e5807 100644
--- a/src/core/qt_render_view_observer_host.h
+++ b/src/core/render_view_observer_host_qt.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QT_RENDER_VIEW_OBSERVER_HOST_H
-#define QT_RENDER_VIEW_OBSERVER_HOST_H
+#ifndef RENDER_VIEW_OBSERVER_HOST_QT_H
+#define RENDER_VIEW_OBSERVER_HOST_QT_H
#include "content/public/browser/web_contents_observer.h"
@@ -49,10 +49,10 @@ namespace QtWebEngineCore {
class WebContentsAdapterClient;
-class QtRenderViewObserverHost : public content::WebContentsObserver
+class RenderViewObserverHostQt : public content::WebContentsObserver
{
public:
- QtRenderViewObserverHost(content::WebContents*, WebContentsAdapterClient *adapterClient);
+ RenderViewObserverHostQt(content::WebContents*, WebContentsAdapterClient *adapterClient);
void fetchDocumentMarkup(quint64 requestId);
void fetchDocumentInnerText(quint64 requestId);
@@ -67,4 +67,4 @@ private:
} // namespace QtWebEngineCore
-#endif // QT_RENDER_VIEW_OBSERVER_HOST_H
+#endif // RENDER_VIEW_OBSERVER_HOST_QT_H
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 94b459e74..d2d292ee9 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -186,13 +186,14 @@ static inline int flagsFromModifiers(Qt::KeyboardModifiers modifiers)
static uint32 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, int index = -1)
+ MotionEventQt(const QList<QTouchEvent::TouchPoint> &touchPoints, const base::TimeTicks &eventTime, Action action, const Qt::KeyboardModifiers modifiers, float dpiScale, int index = -1)
: touchPoints(touchPoints)
, eventTime(eventTime)
, action(action)
, eventId(++s_eventId)
, flags(flagsFromModifiers(modifiers))
, index(index)
+ , dpiScale(dpiScale)
{
// ACTION_DOWN and ACTION_UP must be accesssed through pointer_index 0
Q_ASSERT((action != ACTION_DOWN && action != ACTION_UP) || index == 0);
@@ -203,8 +204,8 @@ public:
virtual int GetActionIndex() const Q_DECL_OVERRIDE { return index; }
virtual size_t GetPointerCount() const Q_DECL_OVERRIDE { return touchPoints.size(); }
virtual int GetPointerId(size_t pointer_index) const Q_DECL_OVERRIDE { return touchPoints.at(pointer_index).id(); }
- virtual float GetX(size_t pointer_index) const Q_DECL_OVERRIDE { return touchPoints.at(pointer_index).pos().x(); }
- virtual float GetY(size_t pointer_index) const Q_DECL_OVERRIDE { return touchPoints.at(pointer_index).pos().y(); }
+ virtual float GetX(size_t pointer_index) const Q_DECL_OVERRIDE { return touchPoints.at(pointer_index).pos().x() / dpiScale; }
+ virtual float GetY(size_t pointer_index) const Q_DECL_OVERRIDE { return touchPoints.at(pointer_index).pos().y() / dpiScale; }
virtual float GetRawX(size_t pointer_index) const Q_DECL_OVERRIDE { return touchPoints.at(pointer_index).screenPos().x(); }
virtual float GetRawY(size_t pointer_index) const Q_DECL_OVERRIDE { return touchPoints.at(pointer_index).screenPos().y(); }
virtual float GetTouchMajor(size_t pointer_index) const Q_DECL_OVERRIDE
@@ -240,6 +241,7 @@ private:
const uint32 eventId;
int flags;
int index;
+ float dpiScale;
};
RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget)
@@ -413,12 +415,13 @@ gfx::Rect RenderWidgetHostViewQt::GetViewBounds() const
return gfx::BoundingRect(p1, p2);
}
-void RenderWidgetHostViewQt::SetBackgroundColor(SkColor color) {
+void RenderWidgetHostViewQt::SetBackgroundColor(SkColor color)
+{
RenderWidgetHostViewBase::SetBackgroundColor(color);
// Set the background of the compositor if necessary
m_delegate->setClearColor(toQt(color));
// Set the background of the blink::FrameView
- m_host->Send(new QtRenderViewObserver_SetBackgroundColor(m_host->GetRoutingID(), color));
+ m_host->Send(new RenderViewObserverQt_SetBackgroundColor(m_host->GetRoutingID(), color));
}
// Return value indicates whether the mouse is locked successfully or not.
@@ -997,7 +1000,7 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
QList<QTouchEvent::TouchPoint> touchPoints = mapTouchPointIds(ev->touchPoints());
if (ev->type() == QEvent::TouchCancel) {
- MotionEventQt cancelEvent(touchPoints, eventTimestamp, ui::MotionEvent::ACTION_CANCEL, ev->modifiers());
+ MotionEventQt cancelEvent(touchPoints, eventTimestamp, ui::MotionEvent::ACTION_CANCEL, ev->modifiers(), dpiScale());
processMotionEvent(cancelEvent);
return;
}
@@ -1030,7 +1033,7 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
continue;
}
- MotionEventQt motionEvent(touchPoints, eventTimestamp, action, ev->modifiers(), i);
+ MotionEventQt motionEvent(touchPoints, eventTimestamp, action, ev->modifiers(), dpiScale(), i);
processMotionEvent(motionEvent);
}
}
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
index 0b8262c76..db50caad8 100644
--- a/src/core/renderer/content_renderer_client_qt.cpp
+++ b/src/core/renderer/content_renderer_client_qt.cpp
@@ -40,6 +40,7 @@
#include "chrome/common/localized_error.h"
#include "components/error_page/common/error_page_params.h"
#include "components/visitedlink/renderer/visitedlink_slave.h"
+#include "components/web_cache/renderer/web_cache_render_process_observer.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
@@ -53,8 +54,8 @@
#include "content/public/common/web_preferences.h"
#include "renderer/web_channel_ipc_transport.h"
-#include "renderer/qt_render_frame_observer.h"
-#include "renderer/qt_render_view_observer.h"
+#include "renderer/render_frame_observer_qt.h"
+#include "renderer/render_view_observer_qt.h"
#include "renderer/user_script_controller.h"
#include "grit/renderer_resources.h"
@@ -77,7 +78,9 @@ void ContentRendererClientQt::RenderThreadStarted()
content::RenderThread *renderThread = content::RenderThread::Get();
renderThread->RegisterExtension(WebChannelIPCTransport::getV8Extension());
m_visitedLinkSlave.reset(new visitedlink::VisitedLinkSlave);
+ m_webCacheObserver.reset(new web_cache::WebCacheRenderProcessObserver());
renderThread->AddObserver(m_visitedLinkSlave.data());
+ renderThread->AddObserver(m_webCacheObserver.data());
renderThread->AddObserver(UserScriptController::instance());
// mark qrc as a secure scheme (avoids deprecation warnings)
@@ -87,14 +90,14 @@ void ContentRendererClientQt::RenderThreadStarted()
void ContentRendererClientQt::RenderViewCreated(content::RenderView* render_view)
{
// RenderViewObservers destroy themselves with their RenderView.
- new QtRenderViewObserver(render_view);
+ new RenderViewObserverQt(render_view, m_webCacheObserver.data());
new WebChannelIPCTransport(render_view);
UserScriptController::instance()->renderViewCreated(render_view);
}
void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame* render_frame)
{
- new QtWebEngineCore::QtRenderFrameObserver(render_frame);
+ new QtWebEngineCore::RenderFrameObserverQt(render_frame);
}
bool ContentRendererClientQt::HasErrorPage(int httpStatusCode, std::string *errorDomain)
diff --git a/src/core/renderer/content_renderer_client_qt.h b/src/core/renderer/content_renderer_client_qt.h
index fab88441f..eb55156ad 100644
--- a/src/core/renderer/content_renderer_client_qt.h
+++ b/src/core/renderer/content_renderer_client_qt.h
@@ -45,6 +45,10 @@ namespace visitedlink {
class VisitedLinkSlave;
}
+namespace web_cache {
+class WebCacheRenderProcessObserver;
+}
+
namespace QtWebEngineCore {
class ContentRendererClientQt : public content::ContentRendererClient {
@@ -64,6 +68,7 @@ public:
private:
QScopedPointer<visitedlink::VisitedLinkSlave> m_visitedLinkSlave;
+ QScopedPointer<web_cache::WebCacheRenderProcessObserver> m_webCacheObserver;
};
} // namespace
diff --git a/src/core/renderer/qt_render_frame_observer.cpp b/src/core/renderer/render_frame_observer_qt.cpp
index 5f06d1e4e..8130cc53a 100644
--- a/src/core/renderer/qt_render_frame_observer.cpp
+++ b/src/core/renderer/render_frame_observer_qt.cpp
@@ -34,7 +34,7 @@
**
****************************************************************************/
-#include "qt_render_frame_observer.h"
+#include "render_frame_observer_qt.h"
#include "content/public/renderer/renderer_ppapi_host.h"
#include "ppapi/host/ppapi_host.h"
@@ -44,17 +44,17 @@
namespace QtWebEngineCore {
-QtRenderFrameObserver::QtRenderFrameObserver(content::RenderFrame* render_frame)
+RenderFrameObserverQt::RenderFrameObserverQt(content::RenderFrame* render_frame)
: RenderFrameObserver(render_frame)
{
}
-QtRenderFrameObserver::~QtRenderFrameObserver()
+RenderFrameObserverQt::~RenderFrameObserverQt()
{
}
#if defined(ENABLE_PLUGINS)
-void QtRenderFrameObserver::DidCreatePepperPlugin(content::RendererPpapiHost* host)
+void RenderFrameObserverQt::DidCreatePepperPlugin(content::RendererPpapiHost* host)
{
host->GetPpapiHost()->AddHostFactoryFilter(
scoped_ptr<ppapi::host::HostFactory>(
diff --git a/src/core/renderer/qt_render_frame_observer.h b/src/core/renderer/render_frame_observer_qt.h
index 42f2b7464..4835e442e 100644
--- a/src/core/renderer/qt_render_frame_observer.h
+++ b/src/core/renderer/render_frame_observer_qt.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QT_RENDER_FRAME_OBSERVER_H
-#define QT_RENDER_FRAME_OBSERVER_H
+#ifndef RENDER_FRAME_OBSERVER_QT_H
+#define RENDER_FRAME_OBSERVER_QT_H
#include "base/basictypes.h"
#include "base/compiler_specific.h"
@@ -48,19 +48,19 @@ class RenderFrame;
namespace QtWebEngineCore {
-class QtRenderFrameObserver : public content::RenderFrameObserver {
+class RenderFrameObserverQt : public content::RenderFrameObserver {
public:
- explicit QtRenderFrameObserver(content::RenderFrame* render_frame);
- ~QtRenderFrameObserver();
+ explicit RenderFrameObserverQt(content::RenderFrame* render_frame);
+ ~RenderFrameObserverQt();
#if defined(ENABLE_PLUGINS)
void DidCreatePepperPlugin(content::RendererPpapiHost* host) override;
#endif
private:
- DISALLOW_COPY_AND_ASSIGN(QtRenderFrameObserver);
+ DISALLOW_COPY_AND_ASSIGN(RenderFrameObserverQt);
};
} // namespace QtWebEngineCore
-#endif // QT_RENDER_FRAME_OBSERVER_H
+#endif // RENDER_FRAME_OBSERVER_QT_H
diff --git a/src/core/renderer/qt_render_view_observer.cpp b/src/core/renderer/render_view_observer_qt.cpp
index ba91e54ae..47efd07e4 100644
--- a/src/core/renderer/qt_render_view_observer.cpp
+++ b/src/core/renderer/render_view_observer_qt.cpp
@@ -34,55 +34,65 @@
**
****************************************************************************/
-#include "renderer/qt_render_view_observer.h"
+#include "renderer/render_view_observer_qt.h"
#include "common/qt_messages.h"
+#include "components/web_cache/renderer/web_cache_render_process_observer.h"
#include "content/public/renderer/render_view.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebElement.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebView.h"
-QtRenderViewObserver::QtRenderViewObserver(content::RenderView* render_view)
+RenderViewObserverQt::RenderViewObserverQt(
+ content::RenderView* render_view,
+ web_cache::WebCacheRenderProcessObserver* web_cache_render_process_observer)
: content::RenderViewObserver(render_view)
+ , m_web_cache_render_process_observer(web_cache_render_process_observer)
{
}
-void QtRenderViewObserver::onFetchDocumentMarkup(quint64 requestId)
+void RenderViewObserverQt::onFetchDocumentMarkup(quint64 requestId)
{
- Send(new QtRenderViewObserverHost_DidFetchDocumentMarkup(
+ Send(new RenderViewObserverHostQt_DidFetchDocumentMarkup(
routing_id(),
requestId,
render_view()->GetWebView()->mainFrame()->contentAsMarkup()));
}
-void QtRenderViewObserver::onFetchDocumentInnerText(quint64 requestId)
+void RenderViewObserverQt::onFetchDocumentInnerText(quint64 requestId)
{
- Send(new QtRenderViewObserverHost_DidFetchDocumentInnerText(
+ Send(new RenderViewObserverHostQt_DidFetchDocumentInnerText(
routing_id(),
requestId,
render_view()->GetWebView()->mainFrame()->contentAsText(std::numeric_limits<std::size_t>::max())));
}
-void QtRenderViewObserver::onSetBackgroundColor(quint32 color)
+void RenderViewObserverQt::onSetBackgroundColor(quint32 color)
{
render_view()->GetWebView()->setBaseBackgroundColor(color);
}
-void QtRenderViewObserver::OnFirstVisuallyNonEmptyLayout()
+void RenderViewObserverQt::OnFirstVisuallyNonEmptyLayout()
{
- Send(new QtRenderViewObserverHost_DidFirstVisuallyNonEmptyLayout(routing_id()));
+ Send(new RenderViewObserverHostQt_DidFirstVisuallyNonEmptyLayout(routing_id()));
}
-bool QtRenderViewObserver::OnMessageReceived(const IPC::Message& message)
+bool RenderViewObserverQt::OnMessageReceived(const IPC::Message& message)
{
bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(QtRenderViewObserver, message)
- IPC_MESSAGE_HANDLER(QtRenderViewObserver_FetchDocumentMarkup, onFetchDocumentMarkup)
- IPC_MESSAGE_HANDLER(QtRenderViewObserver_FetchDocumentInnerText, onFetchDocumentInnerText)
- IPC_MESSAGE_HANDLER(QtRenderViewObserver_SetBackgroundColor, onSetBackgroundColor)
+ IPC_BEGIN_MESSAGE_MAP(RenderViewObserverQt, message)
+ IPC_MESSAGE_HANDLER(RenderViewObserverQt_FetchDocumentMarkup, onFetchDocumentMarkup)
+ IPC_MESSAGE_HANDLER(RenderViewObserverQt_FetchDocumentInnerText, onFetchDocumentInnerText)
+ IPC_MESSAGE_HANDLER(RenderViewObserverQt_SetBackgroundColor, onSetBackgroundColor)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
+
+void RenderViewObserverQt::Navigate(const GURL &)
+{
+ if (m_web_cache_render_process_observer)
+ m_web_cache_render_process_observer->ExecutePendingClearCache();
+}
diff --git a/src/core/renderer/qt_render_view_observer.h b/src/core/renderer/render_view_observer_qt.h
index 3f7829a92..166dcc9ea 100644
--- a/src/core/renderer/qt_render_view_observer.h
+++ b/src/core/renderer/render_view_observer_qt.h
@@ -33,16 +33,21 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#ifndef QT_RENDER_VIEW_OBSERVER_H
-#define QT_RENDER_VIEW_OBSERVER_H
+#ifndef RENDER_VIEW_OBSERVER_QT_H
+#define RENDER_VIEW_OBSERVER_QT_H
#include "content/public/renderer/render_view_observer.h"
#include <QtGlobal>
-class QtRenderViewObserver : public content::RenderViewObserver {
+namespace web_cache {
+class WebCacheRenderProcessObserver;
+}
+
+class RenderViewObserverQt : public content::RenderViewObserver {
public:
- QtRenderViewObserver(content::RenderView* render_view);
+ RenderViewObserverQt(content::RenderView* render_view,
+ web_cache::WebCacheRenderProcessObserver* web_cache_render_process_observer);
private:
void onFetchDocumentMarkup(quint64 requestId);
@@ -52,8 +57,11 @@ private:
void OnFirstVisuallyNonEmptyLayout() Q_DECL_OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message) Q_DECL_OVERRIDE;
+ virtual void Navigate(const GURL& url) Q_DECL_OVERRIDE;
+
+ web_cache::WebCacheRenderProcessObserver* m_web_cache_render_process_observer;
- DISALLOW_COPY_AND_ASSIGN(QtRenderViewObserver);
+ DISALLOW_COPY_AND_ASSIGN(RenderViewObserverQt);
};
-#endif // QT_RENDER_VIEW_OBSERVER_H
+#endif // RENDER_VIEW_OBSERVER_QT_H
diff --git a/src/core/resources/devtools_discovery_page.html b/src/core/resources/devtools_discovery_page.html
index 7aac74932..d37dbfcf4 100644
--- a/src/core/resources/devtools_discovery_page.html
+++ b/src/core/resources/devtools_discovery_page.html
@@ -3,44 +3,68 @@
<title>QtWebEngine Remote Debugging</title>
<style>
body {
- background-color: rgb(245, 245, 245);
+ color: #222;
font-family: Helvetica, Arial, sans-serif;
+ margin: 0;
text-shadow: rgba(255, 255, 255, 0.496094) 0px 1px 0px;
}
#caption {
- color: black;
font-size: 16px;
- margin-top: 30px;
- margin-bottom: 0px;
- margin-left: 70px;
+ margin-top: 15px;
+ margin-bottom: 10px;
+ margin-left: 20px;
height: 20px;
text-align: left;
}
#items {
- margin-left: 60px;
- margin-right: 60px;
- -webkit-box-orient: horizontal;
- -webkit-box-lines: multiple;
+ display: flex;
+ flex-direction: column;
+ margin: 10px;
+}
+
+.item {
+ color: #222;
+ display: flex;
+ flex-direction: row;
+ text-decoration: none;
+ padding: 10px;
+ -webkit-transition-property: background-color, border-color;
+ -webkit-transition: background-color 0.15s, 0.15s;
+ -webkit-transition-delay: 0ms, 0ms;
}
-.frontend_ref {
+.item:not(.connected):hover {
+ background-color: rgba(242, 242, 242, 1);
+ border-color: rgba(110, 116, 128, 1);
color: black;
- text-decoration: initial;
}
-.text {
- background: no-repeat 0;
- background-size: 16px;
- font-size: 12px;
- margin: 4px 0px 0px 4px;
+.item.connected:hover {
+ border-color: rgba(184, 184, 184, 1);
+ color: rgb(110, 116, 128);
+}
+
+.description {
+ display: flex;
+ flex-direction: column;
+}
+
+.title, .subtitle {
+ font-size: 13px;
+ margin: 4px 0px 0px 6px;
overflow: hidden;
- padding: 2px 0px 0px 20px;
- text-align: left;
- text-overflow: ellipsis;
- white-space: nowrap;
+ padding-left: 20px;
}
+
+.title {
+ background-repeat: no-repeat;
+ background-size: 16px;
+ font-size: 15px;
+}
+
+
</style>
<script>
@@ -74,35 +98,43 @@ function overrideFrontendUrl(item) {
}
function appendItem(item_object) {
- var frontend_ref;
+ var item_element;
if (item_object.devtoolsFrontendUrl) {
- frontend_ref = document.createElement('a');
- frontend_ref.href = overrideFrontendUrl(item_object);
- frontend_ref.title = item_object.title;
+ item_element = document.createElement('a');
+ item_element.href = overrideFrontendUrl(item_object);
+ item_element.title = item_object.title;
} else {
- frontend_ref = document.createElement('div');
- frontend_ref.title = 'The tab already has an active debug session';
+ item_element = document.createElement('div');
+ item_element.className = 'connected';
+ item_element.title = 'The tab already has an active debug session';
}
- frontend_ref.className = 'frontend_ref';
+ item_element.classList.add('item');
- var text = document.createElement('div');
- text.className = 'text';
- text.innerText = item_object.description || item_object.title;
- text.style.cssText = 'background-image:url(' +
- item_object.faviconUrl + ')';
- frontend_ref.appendChild(text);
+ var description = document.createElement('div');
+ description.className = 'description';
- var item = document.createElement('p');
- item.appendChild(frontend_ref);
+ var title = document.createElement('div');
+ title.className = 'title';
+ title.textContent = item_object.description || item_object.title;
+ title.style.cssText = 'background-image:url(' +
+ item_object.faviconUrl + ')';
+ description.appendChild(title);
- document.getElementById('items').appendChild(item);
+ var subtitle = document.createElement('div');
+ subtitle.className = 'subtitle';
+ subtitle.textContent = (item_object.url || '').substring(0, 300);
+ description.appendChild(subtitle);
+
+ item_element.appendChild(description);
+
+ document.getElementById('items').appendChild(item_element);
}
</script>
</head>
<body onload='onLoad()'>
<div id='caption'>Inspectable pages</div>
+ <hr>
<div id='items'>
</div>
- <hr>
</body>
</html>
diff --git a/src/core/stream_video_node.cpp b/src/core/stream_video_node.cpp
index a5a6041f3..fdae5fee2 100644
--- a/src/core/stream_video_node.cpp
+++ b/src/core/stream_video_node.cpp
@@ -38,9 +38,12 @@
#include <QtQuick/qsgtexture.h>
+namespace QtWebEngineCore {
+
class StreamVideoMaterialShader : public QSGMaterialShader
{
public:
+ StreamVideoMaterialShader(TextureTarget target) : m_target(target) { }
virtual void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial);
virtual char const *const *attributeNames() const Q_DECL_OVERRIDE {
@@ -55,7 +58,7 @@ public:
protected:
virtual const char *vertexShader() const Q_DECL_OVERRIDE {
// Keep in sync with cc::VertexShaderVideoTransform
- const char *shader =
+ static const char *shader =
"attribute highp vec4 a_position;\n"
"attribute mediump vec2 a_texCoord;\n"
"uniform highp mat4 matrix;\n"
@@ -70,7 +73,7 @@ protected:
virtual const char *fragmentShader() const Q_DECL_OVERRIDE {
// Keep in sync with cc::FragmentShaderRGBATexAlpha
- static const char *shader =
+ static const char *shaderExternal =
"#extension GL_OES_EGL_image_external : require\n"
"varying mediump vec2 v_texCoord;\n"
"uniform samplerExternalOES s_texture;\n"
@@ -79,7 +82,19 @@ protected:
" lowp vec4 texColor = texture2D(s_texture, v_texCoord);\n"
" gl_FragColor = texColor * alpha;\n"
"}";
- return shader;
+ static const char *shader2DRect =
+ "#extension GL_ARB_texture_rectangle : require\n"
+ "varying mediump vec2 v_texCoord;\n"
+ "uniform sampler2DRect s_texture;\n"
+ "uniform lowp float alpha;\n"
+ "void main() {\n"
+ " lowp vec4 texColor = texture2DRect(s_texture, v_texCoord);\n"
+ " gl_FragColor = texColor * alpha;\n"
+ "}";
+ if (m_target == ExternalTarget)
+ return shaderExternal;
+ else
+ return shader2DRect;
}
virtual void initialize() {
@@ -93,6 +108,7 @@ protected:
int m_id_texMatrix;
int m_id_sTexture;
int m_id_opacity;
+ TextureTarget m_target;
};
void StreamVideoMaterialShader::updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
@@ -113,31 +129,38 @@ void StreamVideoMaterialShader::updateState(const RenderState &state, QSGMateria
program()->setUniformValue(m_id_texMatrix, mat->m_texMatrix);
}
-StreamVideoMaterial::StreamVideoMaterial(QSGTexture *texture)
+StreamVideoMaterial::StreamVideoMaterial(QSGTexture *texture, TextureTarget target)
: m_texture(texture)
+ , m_target(target)
{
}
QSGMaterialShader *StreamVideoMaterial::createShader() const
{
- return new StreamVideoMaterialShader;
+ return new StreamVideoMaterialShader(m_target);
}
-StreamVideoNode::StreamVideoNode(QSGTexture *texture)
+StreamVideoNode::StreamVideoNode(QSGTexture *texture, bool flip, TextureTarget target)
: m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
+ , m_flip(flip)
{
setGeometry(&m_geometry);
setFlag(QSGNode::OwnsMaterial);
- m_material = new StreamVideoMaterial(texture);
+ m_material = new StreamVideoMaterial(texture, target);
setMaterial(m_material);
}
void StreamVideoNode::setRect(const QRectF &rect)
{
- QSGGeometry::updateTexturedRectGeometry(geometry(), rect, QRectF(0, 0, 1, 1));
+ if (m_flip)
+ QSGGeometry::updateTexturedRectGeometry(geometry(), rect, QRectF(0, 1, 1, -1));
+ else
+ QSGGeometry::updateTexturedRectGeometry(geometry(), rect, QRectF(0, 0, 1, 1));
}
void StreamVideoNode::setTextureMatrix(const QMatrix4x4 &matrix)
{
m_material->m_texMatrix = matrix;
}
+
+} // namespace
diff --git a/src/core/stream_video_node.h b/src/core/stream_video_node.h
index f808bb609..92c640811 100644
--- a/src/core/stream_video_node.h
+++ b/src/core/stream_video_node.h
@@ -40,19 +40,22 @@
#include <QtQuick/qsgmaterial.h>
#include <QtQuick/qsgnode.h>
-QT_BEGIN_NAMESPACE
-class QSGTexture;
-QT_END_NAMESPACE
+QT_FORWARD_DECLARE_CLASS(QSGTexture)
+
+namespace QtWebEngineCore {
// These classes duplicate, QtQuick style, the logic of GLRenderer::DrawStreamVideoQuad.
// Their behavior should stay as close as possible to GLRenderer.
+enum TextureTarget { ExternalTarget, RectangleTarget };
+
class StreamVideoMaterial : public QSGMaterial
{
public:
- StreamVideoMaterial(QSGTexture *texture);
+ StreamVideoMaterial(QSGTexture *texture, TextureTarget target);
- virtual QSGMaterialType *type() const Q_DECL_OVERRIDE{
+ virtual QSGMaterialType *type() const Q_DECL_OVERRIDE
+ {
static QSGMaterialType theType;
return &theType;
}
@@ -61,18 +64,22 @@ public:
QSGTexture *m_texture;
QMatrix4x4 m_texMatrix;
+ TextureTarget m_target;
};
class StreamVideoNode : public QSGGeometryNode
{
public:
- StreamVideoNode(QSGTexture *texture);
+ StreamVideoNode(QSGTexture *texture, bool flip, TextureTarget target);
void setRect(const QRectF &rect);
void setTextureMatrix(const QMatrix4x4 &matrix);
private:
QSGGeometry m_geometry;
+ bool m_flip;
StreamVideoMaterial *m_material;
};
+} // namespace
+
#endif // STREAM_VIDEO_NODE_H
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 8d3345d1c..84c4e50f3 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -45,8 +45,8 @@
#include "browser_context_adapter.h"
#include "browser_context_qt.h"
#include "media_capture_devices_dispatcher.h"
-#include "qt_render_view_observer_host.h"
#include "qwebenginecallback_p.h"
+#include "render_view_observer_host_qt.h"
#include "type_conversion.h"
#include "web_channel_ipc_transport_host.h"
#include "web_contents_adapter_client.h"
@@ -385,7 +385,7 @@ void WebContentsAdapter::initialize(WebContentsAdapterClient *adapterClient)
// Create and attach observers to the WebContents.
d->webContentsDelegate.reset(new WebContentsDelegateQt(d->webContents.get(), adapterClient));
- d->renderViewObserverHost.reset(new QtRenderViewObserverHost(d->webContents.get(), adapterClient));
+ d->renderViewObserverHost.reset(new RenderViewObserverHostQt(d->webContents.get(), adapterClient));
// Let the WebContent's view know about the WebContentsAdapterClient.
WebContentsViewQt* contentsView = static_cast<WebContentsViewQt*>(static_cast<content::WebContentsImpl*>(d->webContents.get())->GetView());
diff --git a/src/core/web_contents_adapter_p.h b/src/core/web_contents_adapter_p.h
index 9b4128749..093b9059d 100644
--- a/src/core/web_contents_adapter_p.h
+++ b/src/core/web_contents_adapter_p.h
@@ -60,7 +60,7 @@ QT_FORWARD_DECLARE_CLASS(QWebChannel)
namespace QtWebEngineCore {
class BrowserContextAdapter;
-class QtRenderViewObserverHost;
+class RenderViewObserverHostQt;
class UserScriptControllerHost;
class WebChannelIPCTransportHost;
class WebContentsAdapterClient;
@@ -75,7 +75,7 @@ public:
QExplicitlySharedDataPointer<BrowserContextAdapter> browserContextAdapter;
scoped_ptr<content::WebContents> webContents;
scoped_ptr<WebContentsDelegateQt> webContentsDelegate;
- scoped_ptr<QtRenderViewObserverHost> renderViewObserverHost;
+ scoped_ptr<RenderViewObserverHostQt> renderViewObserverHost;
scoped_ptr<WebChannelIPCTransportHost> webChannelTransport;
QWebChannel *webChannel;
WebContentsAdapterClient *adapterClient;
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 1f789161a..1897664e3 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -51,12 +51,14 @@
#include "web_engine_settings.h"
#include "web_engine_visited_links_manager.h"
+#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"
#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/favicon_url.h"
#include "content/public/common/file_chooser_params.h"
@@ -315,6 +317,11 @@ void WebContentsDelegateQt::DidNavigateAnyFrame(content::RenderFrameHost* render
m_viewClient->browserContextAdapter()->visitedLinksManager()->addUrl(params.url);
}
+void WebContentsDelegateQt::WasShown()
+{
+ web_cache::WebCacheManager::GetInstance()->ObserveActivity(web_contents()->GetRenderProcessHost()->GetID());
+}
+
void WebContentsDelegateQt::RequestToLockMouse(content::WebContents *web_contents, bool user_gesture, bool last_unlocked_by_target)
{
Q_UNUSED(user_gesture);
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index abdf75fe5..d3075cfbf 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -44,6 +44,7 @@
#include "base/callback.h"
#include "javascript_dialog_manager_qt.h"
+#include <QtCore/qvector.h>
#include <QtCore/qcompilerdetection.h>
QT_FORWARD_DECLARE_CLASS(CertificateErrorController)
@@ -104,6 +105,7 @@ public:
virtual void DidFinishLoad(content::RenderFrameHost *render_frame_host, const GURL &validated_url) Q_DECL_OVERRIDE;
virtual void DidUpdateFaviconURL(const std::vector<content::FaviconURL> &candidates) Q_DECL_OVERRIDE;
virtual void DidNavigateAnyFrame(content::RenderFrameHost *render_frame_host, const content::LoadCommittedDetails &details, const content::FrameNavigateParams &params) Q_DECL_OVERRIDE;
+ virtual void WasShown() Q_DECL_OVERRIDE;
void overrideWebPreferences(content::WebContents *, content::WebPreferences*);
void allowCertificateError(const QSharedPointer<CertificateErrorController> &) ;
@@ -116,7 +118,7 @@ private:
WebContentsAdapterClient *m_viewClient;
QString m_lastSearchedString;
int m_lastReceivedFindReply;
- QList<int64> m_loadingErrorFrameList;
+ QVector<int64> m_loadingErrorFrameList;
};
} // namespace QtWebEngineCore
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 5be35b348..4d1cbf3d4 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -200,7 +200,7 @@ WebEngineContext::WebEngineContext()
, m_browserRunner(content::BrowserMainRunner::Create())
, m_globalQObject(new QObject())
{
- QList<QByteArray> args;
+ QVector<QByteArray> args;
Q_FOREACH (const QString& arg, QCoreApplication::arguments())
args << arg.toUtf8();
diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp
index c8d1cc27f..88d8a0c5c 100644
--- a/src/core/web_engine_settings.cpp
+++ b/src/core/web_engine_settings.cpp
@@ -46,6 +46,10 @@
namespace QtWebEngineCore {
+QHash<WebEngineSettings::Attribute, bool> WebEngineSettings::m_defaultAttributes;
+QHash<WebEngineSettings::FontFamily, QString> WebEngineSettings::m_defaultFontFamilies;
+QHash<WebEngineSettings::FontSize, int> WebEngineSettings::m_defaultFontSizes;
+
static const int batchTimerTimeout = 0;
class BatchTimer : public QTimer {
@@ -132,9 +136,12 @@ bool WebEngineSettings::testAttribute(WebEngineSettings::Attribute attr) const
void WebEngineSettings::resetAttribute(WebEngineSettings::Attribute attr)
{
- if (!parentSettings) // FIXME: Set initial defaults.
- return;
- m_attributes.remove(attr);
+ if (!parentSettings) {
+ Q_ASSERT(m_defaultAttributes.contains(attr));
+ m_attributes.insert(attr, m_defaultAttributes.value(attr));
+ } else {
+ m_attributes.remove(attr);
+ }
scheduleApplyRecursively();
}
@@ -155,9 +162,12 @@ QString WebEngineSettings::fontFamily(WebEngineSettings::FontFamily which)
void WebEngineSettings::resetFontFamily(WebEngineSettings::FontFamily which)
{
- if (!parentSettings) // FIXME: Set initial defaults.
- return;
- m_fontFamilies.remove(which);
+ if (!parentSettings) {
+ Q_ASSERT(m_defaultFontFamilies.contains(which));
+ m_fontFamilies.insert(which, m_defaultFontFamilies.value(which));
+ } else {
+ m_fontFamilies.remove(which);
+ }
scheduleApplyRecursively();
}
@@ -178,9 +188,12 @@ int WebEngineSettings::fontSize(WebEngineSettings::FontSize type) const
void WebEngineSettings::resetFontSize(WebEngineSettings::FontSize type)
{
- if (!parentSettings) // FIXME: Set initial defaults.
- return;
- m_fontSizes.remove(type);
+ if (!parentSettings) {
+ Q_ASSERT(m_defaultFontSizes.contains(type));
+ m_fontSizes.insert(type, m_defaultFontSizes.value(type));
+ } else {
+ m_fontSizes.remove(type);
+ }
scheduleApplyRecursively();
}
@@ -199,46 +212,55 @@ QString WebEngineSettings::defaultTextEncoding() const
void WebEngineSettings::initDefaults(bool offTheRecord)
{
- // Initialize the default settings.
- m_attributes.insert(AutoLoadImages, true);
- m_attributes.insert(JavascriptEnabled, true);
- m_attributes.insert(JavascriptCanOpenWindows, true);
- m_attributes.insert(JavascriptCanAccessClipboard, false);
- m_attributes.insert(LinksIncludedInFocusChain, true);
- m_attributes.insert(LocalStorageEnabled, !offTheRecord);
- m_attributes.insert(LocalContentCanAccessRemoteUrls, false);
- m_attributes.insert(XSSAuditingEnabled, false);
- m_attributes.insert(SpatialNavigationEnabled, false);
- m_attributes.insert(LocalContentCanAccessFileUrls, true);
- m_attributes.insert(HyperlinkAuditingEnabled, false);
- m_attributes.insert(ScrollAnimatorEnabled, false);
- m_attributes.insert(ErrorPageEnabled, true);
- m_attributes.insert(PluginsEnabled, false);
- m_attributes.insert(FullScreenSupportEnabled, false);
- m_attributes.insert(ScreenCaptureEnabled, false);
-
- // Default fonts
- QFont defaultFont;
- defaultFont.setStyleHint(QFont::Serif);
- m_fontFamilies.insert(StandardFont, defaultFont.defaultFamily());
- m_fontFamilies.insert(SerifFont, defaultFont.defaultFamily());
-
- defaultFont.setStyleHint(QFont::Fantasy);
- m_fontFamilies.insert(FantasyFont, defaultFont.defaultFamily());
-
- defaultFont.setStyleHint(QFont::Cursive);
- m_fontFamilies.insert(CursiveFont, defaultFont.defaultFamily());
-
- defaultFont.setStyleHint(QFont::SansSerif);
- m_fontFamilies.insert(SansSerifFont, defaultFont.defaultFamily());
-
- defaultFont.setStyleHint(QFont::Monospace);
- m_fontFamilies.insert(FixedFont, defaultFont.defaultFamily());
-
- m_fontSizes.insert(MinimumFontSize, 0);
- m_fontSizes.insert(MinimumLogicalFontSize, 6);
- m_fontSizes.insert(DefaultFixedFontSize, 13);
- m_fontSizes.insert(DefaultFontSize, 16);
+ if (m_defaultAttributes.isEmpty()) {
+ // Initialize the default settings.
+ m_defaultAttributes.insert(AutoLoadImages, true);
+ m_defaultAttributes.insert(JavascriptEnabled, true);
+ m_defaultAttributes.insert(JavascriptCanOpenWindows, true);
+ m_defaultAttributes.insert(JavascriptCanAccessClipboard, false);
+ m_defaultAttributes.insert(LinksIncludedInFocusChain, true);
+ m_defaultAttributes.insert(LocalStorageEnabled, !offTheRecord);
+ m_defaultAttributes.insert(LocalContentCanAccessRemoteUrls, false);
+ m_defaultAttributes.insert(XSSAuditingEnabled, false);
+ m_defaultAttributes.insert(SpatialNavigationEnabled, false);
+ m_defaultAttributes.insert(LocalContentCanAccessFileUrls, true);
+ m_defaultAttributes.insert(HyperlinkAuditingEnabled, false);
+ m_defaultAttributes.insert(ScrollAnimatorEnabled, false);
+ m_defaultAttributes.insert(ErrorPageEnabled, true);
+ m_defaultAttributes.insert(PluginsEnabled, false);
+ m_defaultAttributes.insert(FullScreenSupportEnabled, false);
+ m_defaultAttributes.insert(ScreenCaptureEnabled, false);
+ }
+ m_attributes = m_defaultAttributes;
+
+ if (m_defaultFontFamilies.isEmpty()) {
+ // Default fonts
+ QFont defaultFont;
+ defaultFont.setStyleHint(QFont::Serif);
+ m_defaultFontFamilies.insert(StandardFont, defaultFont.defaultFamily());
+ m_defaultFontFamilies.insert(SerifFont, defaultFont.defaultFamily());
+
+ defaultFont.setStyleHint(QFont::Fantasy);
+ m_defaultFontFamilies.insert(FantasyFont, defaultFont.defaultFamily());
+
+ defaultFont.setStyleHint(QFont::Cursive);
+ m_defaultFontFamilies.insert(CursiveFont, defaultFont.defaultFamily());
+
+ defaultFont.setStyleHint(QFont::SansSerif);
+ m_defaultFontFamilies.insert(SansSerifFont, defaultFont.defaultFamily());
+
+ defaultFont.setStyleHint(QFont::Monospace);
+ m_defaultFontFamilies.insert(FixedFont, defaultFont.defaultFamily());
+ }
+ m_fontFamilies = m_defaultFontFamilies;
+
+ if (m_defaultFontSizes.isEmpty()) {
+ m_defaultFontSizes.insert(MinimumFontSize, 0);
+ m_defaultFontSizes.insert(MinimumLogicalFontSize, 6);
+ m_defaultFontSizes.insert(DefaultFixedFontSize, 13);
+ m_defaultFontSizes.insert(DefaultFontSize, 16);
+ }
+ m_fontSizes = m_defaultFontSizes;
m_defaultEncoding = QStringLiteral("ISO-8859-1");
}
diff --git a/src/core/web_engine_settings.h b/src/core/web_engine_settings.h
index d850bd1ef..4104ec67c 100644
--- a/src/core/web_engine_settings.h
+++ b/src/core/web_engine_settings.h
@@ -137,6 +137,10 @@ private:
WebEngineSettings *parentSettings;
QSet<WebEngineSettings *> childSettings;
+ static QHash<Attribute, bool> m_defaultAttributes;
+ static QHash<FontFamily, QString> m_defaultFontFamilies;
+ static QHash<FontSize, int> m_defaultFontSizes;
+
friend class BatchTimer;
friend class WebContentsAdapter;
};
diff --git a/src/core/yuv_video_node.cpp b/src/core/yuv_video_node.cpp
index 815ea7d51..7deeb5802 100644
--- a/src/core/yuv_video_node.cpp
+++ b/src/core/yuv_video_node.cpp
@@ -40,6 +40,8 @@
#include <QtGui/qopenglfunctions.h>
#include <QtQuick/qsgtexture.h>
+namespace QtWebEngineCore {
+
class YUVVideoMaterialShader : public QSGMaterialShader
{
public:
@@ -369,3 +371,5 @@ void YUVVideoNode::setRect(const QRectF &rect)
{
QSGGeometry::updateTexturedRectGeometry(geometry(), rect, QRectF(0, 0, 1, 1));
}
+
+} // namespace
diff --git a/src/core/yuv_video_node.h b/src/core/yuv_video_node.h
index 457c2c7fe..5b13879d3 100644
--- a/src/core/yuv_video_node.h
+++ b/src/core/yuv_video_node.h
@@ -40,9 +40,9 @@
#include <QtQuick/qsgmaterial.h>
#include <QtQuick/qsgnode.h>
-QT_BEGIN_NAMESPACE
-class QSGTexture;
-QT_END_NAMESPACE
+QT_FORWARD_DECLARE_CLASS(QSGTexture)
+
+namespace QtWebEngineCore {
// These classes duplicate, QtQuick style, the logic of GLRenderer::DrawYUVVideoQuad.
// Their behavior should stay as close as possible to GLRenderer.
@@ -59,7 +59,8 @@ public:
const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
ColorSpace colorspace);
- virtual QSGMaterialType *type() const Q_DECL_OVERRIDE {
+ virtual QSGMaterialType *type() const Q_DECL_OVERRIDE
+ {
static QSGMaterialType theType;
return &theType;
}
@@ -85,7 +86,8 @@ public:
const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
ColorSpace colorspace);
- virtual QSGMaterialType *type() const Q_DECL_OVERRIDE{
+ virtual QSGMaterialType *type() const Q_DECL_OVERRIDE
+ {
static QSGMaterialType theType;
return &theType;
}
@@ -109,4 +111,6 @@ private:
YUVVideoMaterial *m_material;
};
+} // namespace
+
#endif // YUV_VIDEO_NODE_H
diff --git a/src/process/main.cpp b/src/process/main.cpp
index 446465ef7..8328c0022 100644
--- a/src/process/main.cpp
+++ b/src/process/main.cpp
@@ -146,8 +146,16 @@ int stat64_proxy(const char *path, struct stat64 *buf)
#endif
#endif // defined(OS_LINUX)
+#ifdef Q_OS_WIN
+void initDpiAwareness();
+#endif // defined(Q_OS_WIN)
+
int main(int argc, const char **argv)
{
+#ifdef Q_OS_WIN
+ initDpiAwareness();
+#endif
+
// QCoreApplication needs a non-const pointer, while the
// ContentMain in Chromium needs the pointer to be const.
QCoreApplication qtApplication(argc, const_cast<char**>(argv));
diff --git a/src/process/process.pro b/src/process/process.pro
index 7bf06a376..6174e53bf 100644
--- a/src/process/process.pro
+++ b/src/process/process.pro
@@ -8,8 +8,23 @@ 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);"
+ }
} else {
CONFIG -= app_bundle
win32: DESTDIR = $$MODULE_BASE_OUTDIR/bin
@@ -24,6 +39,11 @@ INCLUDEPATH += ../core
SOURCES = main.cpp
+win32 {
+ SOURCES += \
+ support_win.cpp
+}
+
contains(QT_CONFIG, qt_framework) {
target.path = $$[QT_INSTALL_LIBS]/QtWebEngineCore.framework/Versions/5/Helpers
} else {
diff --git a/src/process/support_win.cpp b/src/process/support_win.cpp
new file mode 100644
index 000000000..4ccd51627
--- /dev/null
+++ b/src/process/support_win.cpp
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 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 <qlibrary.h>
+#include <qsysinfo.h>
+#include <qt_windows.h>
+#include <Tlhelp32.h>
+
+class User32DLL {
+public:
+ User32DLL()
+ : setProcessDPIAware(0)
+ {
+ library.setFileName(QStringLiteral("User32"));
+ if (!library.load())
+ return;
+ setProcessDPIAware = (SetProcessDPIAware)library.resolve("SetProcessDPIAware");
+ }
+
+ bool isValid() const
+ {
+ return setProcessDPIAware;
+ }
+
+ typedef BOOL (WINAPI *SetProcessDPIAware)();
+
+ // Windows Vista onwards
+ SetProcessDPIAware setProcessDPIAware;
+
+private:
+ QLibrary library;
+};
+
+// This must match PROCESS_DPI_AWARENESS in ShellScalingApi.h
+enum DpiAwareness {
+ PROCESS_PER_UNAWARE = 0,
+ PROCESS_PER_SYSTEM_DPI_AWARE = 1,
+ PROCESS_PER_MONITOR_DPI_AWARE = 2
+};
+
+// Shell scaling library (Windows 8.1 onwards)
+class ShcoreDLL {
+public:
+ ShcoreDLL()
+ : getProcessDpiAwareness(0), setProcessDpiAwareness(0)
+ {
+ if (QSysInfo::windowsVersion() < QSysInfo::WV_WINDOWS8_1)
+ return;
+ library.setFileName(QStringLiteral("SHCore"));
+ if (!library.load())
+ return;
+ getProcessDpiAwareness = (GetProcessDpiAwareness)library.resolve("GetProcessDpiAwareness");
+ setProcessDpiAwareness = (SetProcessDpiAwareness)library.resolve("SetProcessDpiAwareness");
+ }
+
+ bool isValid() const
+ {
+ return getProcessDpiAwareness && setProcessDpiAwareness;
+ }
+
+ typedef HRESULT (WINAPI *GetProcessDpiAwareness)(HANDLE, DpiAwareness *);
+ typedef HRESULT (WINAPI *SetProcessDpiAwareness)(DpiAwareness);
+
+ GetProcessDpiAwareness getProcessDpiAwareness;
+ SetProcessDpiAwareness setProcessDpiAwareness;
+
+private:
+ QLibrary library;
+};
+
+
+static DWORD getParentProcessId()
+{
+ HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if (hSnapshot == INVALID_HANDLE_VALUE) {
+ qErrnoWarning(GetLastError(), "CreateToolhelp32Snapshot failed.");
+ return NULL;
+ }
+
+ PROCESSENTRY32 pe = {0};
+ pe.dwSize = sizeof(PROCESSENTRY32);
+
+ if (!Process32First(hSnapshot, &pe)) {
+ qWarning("Cannot retrieve parent process handle.");
+ return NULL;
+ }
+
+ DWORD parentPid = NULL;
+ const DWORD pid = GetCurrentProcessId();
+ do {
+ if (pe.th32ProcessID == pid) {
+ parentPid = pe.th32ParentProcessID;
+ break;
+ }
+ } while (Process32Next(hSnapshot, &pe));
+ CloseHandle(hSnapshot);
+ return parentPid;
+}
+
+void initDpiAwareness()
+{
+ ShcoreDLL shcore;
+ if (shcore.isValid()) {
+ DpiAwareness dpiAwareness = PROCESS_PER_MONITOR_DPI_AWARE;
+ const DWORD pid = getParentProcessId();
+ if (pid) {
+ HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
+ DpiAwareness parentDpiAwareness;
+ HRESULT hr = shcore.getProcessDpiAwareness(hProcess, &parentDpiAwareness);
+ CloseHandle(hProcess);
+ if (hr == S_OK)
+ dpiAwareness = parentDpiAwareness;
+ }
+ if (shcore.setProcessDpiAwareness(dpiAwareness) != S_OK)
+ qErrnoWarning(GetLastError(), "SetProcessDPIAwareness failed.");
+ } else {
+ // Fallback. Use SetProcessDPIAware unconditionally.
+ User32DLL user32;
+ if (user32.isValid())
+ user32.setProcessDPIAware();
+ }
+}
diff --git a/src/webengine/api/qquickwebenginecertificateerror_p.h b/src/webengine/api/qquickwebenginecertificateerror_p.h
index 6f54528d4..7deeac932 100644
--- a/src/webengine/api/qquickwebenginecertificateerror_p.h
+++ b/src/webengine/api/qquickwebenginecertificateerror_p.h
@@ -62,7 +62,6 @@ class Q_WEBENGINE_EXPORT QQuickWebEngineCertificateError : public QObject {
Q_PROPERTY(Error error READ error)
Q_PROPERTY(QString description READ description)
Q_PROPERTY(bool overridable READ overridable)
- Q_ENUMS(Error)
public:
@@ -82,6 +81,7 @@ public:
CertificateWeakKey = -211,
CertificateNameConstraintViolation = -212,
};
+ Q_ENUM(Error)
QQuickWebEngineCertificateError(const QSharedPointer<CertificateErrorController> &controller, QObject *parent = 0);
~QQuickWebEngineCertificateError();
diff --git a/src/webengine/api/qquickwebenginedownloaditem_p.h b/src/webengine/api/qquickwebenginedownloaditem_p.h
index 9a30eb4ca..d0be2f99a 100644
--- a/src/webengine/api/qquickwebenginedownloaditem_p.h
+++ b/src/webengine/api/qquickwebenginedownloaditem_p.h
@@ -69,7 +69,7 @@ public:
DownloadCancelled,
DownloadInterrupted
};
- Q_ENUMS(DownloadState)
+ Q_ENUM(DownloadState)
Q_PROPERTY(quint32 id READ id CONSTANT FINAL)
Q_PROPERTY(DownloadState state READ state NOTIFY stateChanged)
diff --git a/src/webengine/api/qquickwebenginenewviewrequest.cpp b/src/webengine/api/qquickwebenginenewviewrequest.cpp
index 893df7f46..6e20c0a46 100644
--- a/src/webengine/api/qquickwebenginenewviewrequest.cpp
+++ b/src/webengine/api/qquickwebenginenewviewrequest.cpp
@@ -69,7 +69,7 @@ QQuickWebEngineView::NewViewDestination QQuickWebEngineNewViewRequest::destinati
}
/*!
- \qmlproperty bool WebEngineNewViewRequest::isUserInitiated
+ \qmlproperty bool WebEngineNewViewRequest::userInitiated
Whether this window request was directly triggered as the result of a keyboard or mouse event.
Use this property to block possibly unwanted \e popups.
diff --git a/src/webengine/api/qquickwebengineprofile_p.h b/src/webengine/api/qquickwebengineprofile_p.h
index b4e0d173c..1ed15aec2 100644
--- a/src/webengine/api/qquickwebengineprofile_p.h
+++ b/src/webengine/api/qquickwebengineprofile_p.h
@@ -67,8 +67,6 @@ class QWebEngineCookieStoreClient;
class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineProfile : public QObject {
Q_OBJECT
- Q_ENUMS(HttpCacheType);
- Q_ENUMS(PersistentCookiesPolicy);
Q_PROPERTY(QString storageName READ storageName WRITE setStorageName NOTIFY storageNameChanged FINAL)
Q_PROPERTY(bool offTheRecord READ isOffTheRecord WRITE setOffTheRecord NOTIFY offTheRecordChanged FINAL)
Q_PROPERTY(QString persistentStoragePath READ persistentStoragePath WRITE setPersistentStoragePath NOTIFY persistentStoragePathChanged FINAL)
@@ -86,12 +84,14 @@ public:
MemoryHttpCache,
DiskHttpCache
};
+ Q_ENUM(HttpCacheType)
enum PersistentCookiesPolicy {
NoPersistentCookies,
AllowPersistentCookies,
ForcePersistentCookies
};
+ Q_ENUM(PersistentCookiesPolicy)
QString storageName() const;
void setStorageName(const QString &name);
diff --git a/src/webengine/api/qquickwebenginescript_p.h b/src/webengine/api/qquickwebenginescript_p.h
index de91134ef..c9d6f5d26 100644
--- a/src/webengine/api/qquickwebenginescript_p.h
+++ b/src/webengine/api/qquickwebenginescript_p.h
@@ -59,8 +59,6 @@ class QQuickWebEngineView;
class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineScript : public QObject
{
Q_OBJECT
- Q_ENUMS(InjectionPoint)
- Q_ENUMS(ScriptWorldId)
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QUrl sourceUrl READ sourceUrl WRITE setSourceUrl NOTIFY sourceUrlChanged)
Q_PROPERTY(QString sourceCode READ sourceCode WRITE setSourceCode NOTIFY sourceCodeChanged)
@@ -75,12 +73,14 @@ public:
DocumentReady,
DocumentCreation
};
+ Q_ENUM(InjectionPoint)
enum ScriptWorldId {
MainWorld = 0,
ApplicationWorld,
UserWorld
};
+ Q_ENUM(ScriptWorldId)
QQuickWebEngineScript();
~QQuickWebEngineScript();
diff --git a/src/webengine/api/qquickwebenginesettings_p.h b/src/webengine/api/qquickwebenginesettings_p.h
index e82ec6d48..c08a5d897 100644
--- a/src/webengine/api/qquickwebenginesettings_p.h
+++ b/src/webengine/api/qquickwebenginesettings_p.h
@@ -72,7 +72,8 @@ 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)
- Q_PROPERTY(bool fullScreenSupportEnabled READ fullScreenSupportEnabled WRITE setFullScreenSupportEnabled NOTIFY fullScreenSupportEnabledChanged REVISION 1)
+ // 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(bool screenCaptureEnabled READ screenCaptureEnabled WRITE setScreenCaptureEnabled NOTIFY screenCaptureEnabledChanged /* REVISION 2 */)
Q_PROPERTY(QString defaultTextEncoding READ defaultTextEncoding WRITE setDefaultTextEncoding NOTIFY defaultTextEncodingChanged)
@@ -125,7 +126,8 @@ signals:
void hyperlinkAuditingEnabledChanged();
void errorPageEnabledChanged();
void pluginsEnabledChanged();
- Q_REVISION(1) void fullScreenSupportEnabledChanged();
+ // 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 defaultTextEncodingChanged();
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index aa450003c..f266fdce6 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -67,6 +67,7 @@
#include <QClipboard>
#include <QGuiApplication>
+#include <QLoggingCategory>
#include <QMimeData>
#include <QQmlComponent>
#include <QQmlContext>
@@ -534,7 +535,29 @@ bool QQuickWebEngineViewPrivate::isFullScreenMode() const
void QQuickWebEngineViewPrivate::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID)
{
Q_Q(QQuickWebEngineView);
- Q_EMIT q->javaScriptConsoleMessage(static_cast<QQuickWebEngineView::JavaScriptConsoleMessageLevel>(level), message, lineNumber, sourceID);
+ if (q->receivers(SIGNAL(javaScriptConsoleMessage(JavaScriptConsoleMessageLevel,QString,int,QString))) > 0) {
+ Q_EMIT q->javaScriptConsoleMessage(static_cast<QQuickWebEngineView::JavaScriptConsoleMessageLevel>(level), message, lineNumber, sourceID);
+ return;
+ }
+
+ static QLoggingCategory loggingCategory("js", QtWarningMsg);
+ const QByteArray file = sourceID.toUtf8();
+ QMessageLogger logger(file.constData(), lineNumber, nullptr, loggingCategory.categoryName());
+
+ switch (level) {
+ case JavaScriptConsoleMessageLevel::Info:
+ if (loggingCategory.isInfoEnabled())
+ logger.info().noquote() << message;
+ break;
+ case JavaScriptConsoleMessageLevel::Warning:
+ if (loggingCategory.isWarningEnabled())
+ logger.warning().noquote() << message;
+ break;
+ case JavaScriptConsoleMessageLevel::Error:
+ if (loggingCategory.isCriticalEnabled())
+ logger.critical().noquote() << message;
+ break;
+ }
}
void QQuickWebEngineViewPrivate::authenticationRequired(QSharedPointer<AuthenticationDialogController> controller)
@@ -656,11 +679,25 @@ void QQuickWebEngineViewPrivate::adoptWebContents(WebContentsAdapter *webContent
}
Q_Q(QQuickWebEngineView);
+
+ // memorize what webChannel we had for the previous adapter
+ QQmlWebChannel *qmlWebChannel = NULL;
+ if (adapter)
+ qmlWebChannel = qobject_cast<QQmlWebChannel *>(adapter->webChannel());
+
// This throws away the WebContentsAdapter that has been used until now.
// All its states, particularly the loading URL, are replaced by the adopted WebContentsAdapter.
adapter = webContents;
adapter->initialize(this);
+ // associate the webChannel with the new adapter
+ if (qmlWebChannel)
+ adapter->setWebChannel(qmlWebChannel);
+
+ // re-bind the userscrips to the new adapter
+ Q_FOREACH (QQuickWebEngineScript *script, m_userScripts)
+ script->d_func()->bind(browserContextAdapter()->userScriptController(), adapter.data());
+
// Emit signals for values that might be different from the previous WebContentsAdapter.
emit q->titleChanged();
emit q->urlChanged();
@@ -1454,5 +1491,3 @@ void QQuickWebEngineViewport::setDevicePixelRatio(qreal devicePixelRatio)
QT_END_NAMESPACE
-#include "moc_qquickwebengineview_p.cpp"
-#include "moc_qquickwebengineview_p_p.cpp"
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index a17c7bd43..4c4192b4c 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -115,16 +115,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem {
Q_PROPERTY(QQuickWebEngineTestSupport *testSupport READ testSupport WRITE setTestSupport FINAL)
#endif
- Q_ENUMS(NavigationRequestAction);
- Q_ENUMS(NavigationType);
- Q_ENUMS(LoadStatus);
- Q_ENUMS(ErrorDomain);
- Q_ENUMS(NewViewDestination);
- Q_ENUMS(Feature);
- Q_ENUMS(JavaScriptConsoleMessageLevel);
- Q_ENUMS(RenderProcessTerminationStatus);
Q_FLAGS(FindFlags);
- Q_ENUMS(WebAction);
public:
QQuickWebEngineView(QQuickItem *parent = 0);
@@ -155,6 +146,7 @@ public:
// we can expose extra actions in experimental.
IgnoreRequest = 0xFF
};
+ Q_ENUM(NavigationRequestAction)
// must match WebContentsAdapterClient::NavigationType
enum NavigationType {
@@ -165,6 +157,7 @@ public:
ReloadNavigation,
OtherNavigation
};
+ Q_ENUM(NavigationType)
enum LoadStatus {
LoadStartedStatus,
@@ -172,6 +165,7 @@ public:
LoadSucceededStatus,
LoadFailedStatus
};
+ Q_ENUM(LoadStatus)
enum ErrorDomain {
NoErrorDomain,
@@ -182,6 +176,7 @@ public:
FtpErrorDomain,
DnsErrorDomain
};
+ Q_ENUM(ErrorDomain)
enum NewViewDestination {
NewViewInWindow,
@@ -189,6 +184,7 @@ public:
NewViewInDialog,
NewViewInBackgroundTab
};
+ Q_ENUM(NewViewDestination)
enum Feature {
MediaAudioCapture,
@@ -196,6 +192,7 @@ public:
MediaAudioVideoCapture,
Geolocation
};
+ Q_ENUM(Feature)
enum WebAction {
NoWebAction = - 1,
@@ -239,6 +236,7 @@ public:
WebActionCount
};
+ Q_ENUM(WebAction)
// must match WebContentsAdapterClient::JavaScriptConsoleMessageLevel
enum JavaScriptConsoleMessageLevel {
@@ -246,6 +244,7 @@ public:
WarningMessageLevel,
ErrorMessageLevel
};
+ Q_ENUM(JavaScriptConsoleMessageLevel)
// must match WebContentsAdapterClient::RenderProcessTerminationStatus
enum RenderProcessTerminationStatus {
@@ -254,6 +253,7 @@ public:
CrashedTerminationStatus,
KilledTerminationStatus
};
+ Q_ENUM(RenderProcessTerminationStatus)
enum FindFlag {
FindBackward = 1,
diff --git a/src/webengine/doc/src/external-resources.qdoc b/src/webengine/doc/src/external-resources.qdoc
index 34a66291e..2987f1fca 100644
--- a/src/webengine/doc/src/external-resources.qdoc
+++ b/src/webengine/doc/src/external-resources.qdoc
@@ -35,6 +35,11 @@
\title Chrome DevTools
*/
+/*!
+ \externalpage https://developers.google.com/web/tools/javascript/console/console-write
+ \title Chrome console API
+*/
+
/*
This prevents autolinking of each occurrence of 'WebEngine'
To link to the WebEngine QML type, use explicit linking:
diff --git a/src/webengine/doc/src/qtwebengine-devtools.qdoc b/src/webengine/doc/src/qtwebengine-debugging.qdoc
index ee87214e1..bffcd1669 100644
--- a/src/webengine/doc/src/qtwebengine-devtools.qdoc
+++ b/src/webengine/doc/src/qtwebengine-debugging.qdoc
@@ -26,8 +26,24 @@
****************************************************************************/
/*!
- \page qtwebengine-devtools.html
- \title Qt WebEngine Web Developer Tools
+ \page qtwebengine-debugging.html
+ \title Qt WebEngine Debugging and Profiling
+
+ \section1 Console Logging
+
+ JavaScript executed inside Qt WebEngine can use the
+ \l{Chrome console API} to log information to a console. The logging messages
+ are forwarded to Qt's logging facilities inside a \c js
+ \l{QLoggingCategory}{logging category}. However, only warning and fatal
+ messages are printed by default. To change this, you either have to set custom
+ rules for the \c js category, or provide custom message handlers
+ by reimplementing \l{QWebEnginePage::javaScriptConsoleMessage()}, or
+ connecting to \l{WebEngineView::javaScriptConsoleMessage()}.
+
+ All messages can also be accessed through the Qt WebEngine developer
+ tools.
+
+ \section1 Qt WebEngine Developer Tools
The Qt WebEngine module provides web developer tools that make it easy
to inspect and debug layout and performance issues of any web content.
diff --git a/src/webengine/doc/src/qtwebengine-index.qdoc b/src/webengine/doc/src/qtwebengine-index.qdoc
index e67bd43fd..671425e75 100644
--- a/src/webengine/doc/src/qtwebengine-index.qdoc
+++ b/src/webengine/doc/src/qtwebengine-index.qdoc
@@ -70,7 +70,7 @@
\list
\li \l{Qt WebEngine Overview}
\li \l{Qt WebEngine Platform Notes}
- \li \l{Qt WebEngine Web Developer Tools}
+ \li \l{Qt WebEngine Debugging and Profiling}
\li \l{Porting from Qt WebKit to Qt WebEngine}
\endlist
diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc
index 7ab29e324..cfe731c01 100644
--- a/src/webengine/doc/src/qtwebengine-overview.qdoc
+++ b/src/webengine/doc/src/qtwebengine-overview.qdoc
@@ -67,6 +67,12 @@
specification than Qt WebKit. However, Qt WebEngine is thus heavier than Qt WebKit and does
not provide direct access to the network stack and the HTML document through C++ APIs.
+ Please note that Qt WebEngine is based on Chromium, but does not contain or use any services
+ or add-ons that might be part of the Chrome browser that is built and delivered by Google.
+ You can find more detailed information about the differences between Chromium and Chrome in this
+ \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.
+
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
diff --git a/src/webengine/doc/src/webengineview.qdoc b/src/webengine/doc/src/webengineview.qdoc
index f230ba261..d1b4e722b 100644
--- a/src/webengine/doc/src/webengineview.qdoc
+++ b/src/webengine/doc/src/webengineview.qdoc
@@ -434,7 +434,10 @@
\a level indicates the severity of the event that triggered the message, that is, whether it
was triggered by an error or a less severe event.
- The corresponding handler is \c onJavaScriptConsoleMessage.
+ The corresponding handler is \c onJavaScriptConsoleMessage. If no handler is specified,
+ the view will log the messages into a \c js \l{QLoggingCategory}{logging category}.
+
+ \sa{Console Logging}
*/
/*!
diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp
index 2025ce588..c59dfb450 100644
--- a/src/webengine/plugin/plugin.cpp
+++ b/src/webengine/plugin/plugin.cpp
@@ -79,7 +79,7 @@ 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"));
- qmlRegisterUncreatableType<QQuickWebEngineSettings, 1>(uri, 1, 2, "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"));
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/webengine/plugin/plugins.qmltypes b/src/webengine/plugin/plugins.qmltypes
index 1e577bf51..7a310d268 100644
--- a/src/webengine/plugin/plugins.qmltypes
+++ b/src/webengine/plugin/plugins.qmltypes
@@ -488,8 +488,10 @@ Module {
exports: ["QtWebEngine/FullScreenRequest 1.1"]
isCreatable: false
exportMetaObjectRevisions: [0]
+ Property { name: "origin"; type: "QUrl"; isReadonly: true }
Property { name: "toggleOn"; type: "bool"; isReadonly: true }
Method { name: "accept" }
+ Method { name: "reject" }
}
Component {
name: "QQuickWebEngineHistory"
@@ -609,11 +611,7 @@ Module {
name: "downloadFinished"
Parameter { name: "download"; type: "QQuickWebEngineDownloadItem"; isPointer: true }
}
- Method {
- name: "setCookieStoreClient"
- revision: 1
- Parameter { name: "client"; type: "QWebEngineCookieStoreClient"; isPointer: true }
- }
+ Method { name: "cookieStoreClient"; revision: 1; type: "QWebEngineCookieStoreClient*" }
}
Component {
name: "QQuickWebEngineScript"
@@ -832,7 +830,8 @@ Module {
"DownloadMediaToDisk": 25,
"InspectElement": 26,
"ExitFullScreen": 27,
- "WebActionCount": 28
+ "RequestClose": 28,
+ "WebActionCount": 29
}
}
Enum {
@@ -953,6 +952,7 @@ Module {
Parameter { name: "terminationStatus"; type: "RenderProcessTerminationStatus" }
Parameter { name: "exitCode"; type: "int" }
}
+ Signal { name: "windowCloseRequested"; revision: 2 }
Method {
name: "runJavaScript"
Parameter { type: "string" }
diff --git a/src/webengine/ui/AuthenticationDialog.qml b/src/webengine/ui/AuthenticationDialog.qml
index 46e2e3151..441235980 100644
--- a/src/webengine/ui/AuthenticationDialog.qml
+++ b/src/webengine/ui/AuthenticationDialog.qml
@@ -35,71 +35,88 @@
****************************************************************************/
// FIXME: authentication missing in Qt Quick Dialogs atm. Make our own for now.
+import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.0
-import QtQuick 2.5
+import QtQuick.Window 2.2
-ApplicationWindow {
+Window {
signal accepted(string user, string password);
signal rejected;
- property alias text: message.text;
+ property alias text: message.text
- width: 350
- height: 100
+ title: qsTr("Authentication Required")
flags: Qt.Dialog
+ modality: Qt.WindowModal
- title: "Authentication Required"
+ width: minimumWidth
+ height: minimumHeight
+ minimumWidth: rootLayout.implicitWidth + rootLayout.doubleMargins
+ minimumHeight: rootLayout.implicitHeight + rootLayout.doubleMargins
+
+ SystemPalette { id: palette; colorGroup: SystemPalette.Active }
+ color: palette.window
function open() {
show();
}
+ function acceptDialog() {
+ accepted(userField.text, passwordField.text);
+ close();
+ }
+
ColumnLayout {
- anchors.fill: parent;
- anchors.margins: 4;
+ id: rootLayout
+ anchors.fill: parent
+ anchors.margins: 4
+ property int doubleMargins: anchors.margins * 2
Text {
id: message;
- Layout.fillWidth: true;
+ color: palette.windowText
}
- RowLayout {
+ GridLayout {
+ columns: 2
Label {
- text: "Username:"
+ text: qsTr("Username:")
+ color: palette.windowText
}
TextField {
- id: userField;
- Layout.fillWidth: true;
+ id: userField
+ focus: true
+ Layout.fillWidth: true
+ onAccepted: acceptDialog()
}
- }
- RowLayout {
Label {
- text: "Password:"
+ text: qsTr("Password:")
+ color: palette.windowText
}
TextField {
- id: passwordField;
- Layout.fillWidth: true;
- echoMode: TextInput.Password;
+ id: passwordField
+ Layout.fillWidth: true
+ echoMode: TextInput.Password
+ onAccepted: acceptDialog()
}
}
+ Item {
+ Layout.fillHeight: true
+ }
RowLayout {
Layout.alignment: Qt.AlignRight
- spacing: 8;
+ spacing: 8
Button {
- text: "Log In"
+ id: cancelButton
+ text: qsTr("&Cancel")
onClicked: {
- accepted(userField.text, passwordField.text);
+ rejected();
close();
- destroy();
}
}
Button {
- text: "Cancel"
- onClicked: {
- rejected();
- close();
- destroy();
- }
+ text: qsTr("&Log In")
+ isDefault: true
+ onClicked: acceptDialog()
}
}
}
-
}
diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp
index f60cfb1a7..2e686b1b1 100644
--- a/src/webengine/ui_delegates_manager.cpp
+++ b/src/webengine/ui_delegates_manager.cpp
@@ -245,19 +245,19 @@ void UIDelegatesManager::showDialog(QSharedPointer<JavaScriptDialogController> d
switch (dialogController->type()) {
case WebContentsAdapterClient::AlertDialog:
dialogComponentType = AlertDialog;
- title = QCoreApplication::translate("UIDelegatesManager", "Javascript Alert - %1").arg(m_view->url().toString());
+ title = tr("Javascript Alert - %1").arg(m_view->url().toString());
break;
case WebContentsAdapterClient::ConfirmDialog:
dialogComponentType = ConfirmDialog;
- title = QCoreApplication::translate("UIDelegatesManager", "Javascript Confirm - %1").arg(m_view->url().toString());
+ title = tr("Javascript Confirm - %1").arg(m_view->url().toString());
break;
case WebContentsAdapterClient::PromptDialog:
dialogComponentType = PromptDialog;
- title = QCoreApplication::translate("UIDelegatesManager", "Javascript Prompt - %1").arg(m_view->url().toString());
+ title = tr("Javascript Prompt - %1").arg(m_view->url().toString());
break;
case WebContentsAdapterClient::UnloadDialog:
dialogComponentType = ConfirmDialog;
- title = QCoreApplication::translate("UIDelegatesManager", "Are you sure you want to leave this page?");
+ title = tr("Are you sure you want to leave this page?");
break;
case WebContentsAdapterClient::InternalAuthorizationDialog:
dialogComponentType = ConfirmDialog;
@@ -335,10 +335,10 @@ void UIDelegatesManager::showDialog(QSharedPointer<AuthenticationDialogControlle
QString introMessage;
if (dialogController->isProxy()) {
- introMessage = QObject::tr("Connect to proxy \"%1\" using:");
+ introMessage = tr("Connect to proxy \"%1\" using:");
introMessage = introMessage.arg(dialogController->host().toHtmlEscaped());
} else {
- introMessage = QObject::tr("Enter username and password for \"%1\" at %2");
+ introMessage = tr("Enter username and password for \"%1\" at %2");
introMessage = introMessage.arg(dialogController->realm()).arg(dialogController->url().toString().toHtmlEscaped());
}
QQmlProperty textProp(authenticationDialog, QStringLiteral("text"));
diff --git a/src/webengine/ui_delegates_manager.h b/src/webengine/ui_delegates_manager.h
index fb262aac1..7a87c1eee 100644
--- a/src/webengine/ui_delegates_manager.h
+++ b/src/webengine/ui_delegates_manager.h
@@ -37,7 +37,12 @@
#ifndef UI_DELEGATES_MANAGER_H
#define UI_DELEGATES_MANAGER_H
-#include <QObject>
+#include "qglobal.h"
+#include "web_contents_adapter.h"
+#include "web_contents_adapter_client.h"
+
+#include <QCoreApplication>
+#include <QExplicitlySharedDataPointer>
#include <QPoint>
#include <QSharedPointer>
@@ -82,8 +87,9 @@ Q_SIGNALS:
void triggered();
};
-class UIDelegatesManager {
-
+class UIDelegatesManager
+{
+ Q_DECLARE_TR_FUNCTIONS(UIDelegatesManager)
public:
enum ComponentType {
Invalid = -1,
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem.h b/src/webenginewidgets/api/qwebenginedownloaditem.h
index 05e0f8765..38b9a4ad8 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem.h
+++ b/src/webenginewidgets/api/qwebenginedownloaditem.h
@@ -59,7 +59,7 @@ public:
DownloadCancelled,
DownloadInterrupted
};
- Q_ENUMS(DownloadState)
+ Q_ENUM(DownloadState)
quint32 id() const;
DownloadState state() const;
diff --git a/src/webenginewidgets/api/qwebenginefullscreenrequest.cpp b/src/webenginewidgets/api/qwebenginefullscreenrequest.cpp
index 6223c070d..7db86e6f2 100644
--- a/src/webenginewidgets/api/qwebenginefullscreenrequest.cpp
+++ b/src/webenginewidgets/api/qwebenginefullscreenrequest.cpp
@@ -39,21 +39,31 @@
QT_BEGIN_NAMESPACE
-QWebEngineFullScreenRequest::QWebEngineFullScreenRequest(QWebEnginePagePrivate *pagePrivate, const QUrl &origin, bool fullscreen)
- : m_pagePrivate(pagePrivate)
+QWebEngineFullScreenRequest::QWebEngineFullScreenRequest(QWebEnginePage *page, const QUrl &origin, bool fullscreen)
+ : m_page(page)
, m_origin(origin)
, m_toggleOn(fullscreen)
{
}
-void QWebEngineFullScreenRequest::reject() const
+void QWebEngineFullScreenRequest::reject()
{
- m_pagePrivate->setFullScreenMode(!m_toggleOn);
+ if (!m_page) {
+ qWarning("Cannot reject QWebEngineFullScreenRequest: Originating page is already deleted");
+ return;
+ }
+
+ m_page->d_func()->setFullScreenMode(!m_toggleOn);
}
-void QWebEngineFullScreenRequest::accept() const
+void QWebEngineFullScreenRequest::accept()
{
- m_pagePrivate->setFullScreenMode(m_toggleOn);
+ if (!m_page) {
+ qWarning("Cannot accept QWebEngineFullScreenRequest: Originating page is already deleted");
+ return;
+ }
+
+ m_page->d_func()->setFullScreenMode(m_toggleOn);
}
QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebenginefullscreenrequest.h b/src/webenginewidgets/api/qwebenginefullscreenrequest.h
index c6768f4d6..26f7247e0 100644
--- a/src/webenginewidgets/api/qwebenginefullscreenrequest.h
+++ b/src/webenginewidgets/api/qwebenginefullscreenrequest.h
@@ -38,26 +38,25 @@
#define QWEBENGINEFULLSCREENREQUEST_H
#include <qtwebenginewidgetsglobal.h>
-#include <qwebenginepage.h>
-#include <QtCore/qurl.h>
+#include <qurl.h>
+#include <qpointer.h>
QT_BEGIN_NAMESPACE
-class QWebEnginePagePrivate;
+class QWebEnginePage;
class QWEBENGINEWIDGETS_EXPORT QWebEngineFullScreenRequest {
Q_GADGET
Q_PROPERTY(bool toggleOn READ toggleOn)
Q_PROPERTY(QUrl origin READ origin)
public:
- Q_INVOKABLE void reject() const;
- Q_INVOKABLE void accept() const;
+ Q_INVOKABLE void reject();
+ Q_INVOKABLE void accept();
bool toggleOn() const { return m_toggleOn; }
const QUrl &origin() const { return m_origin; }
private:
- Q_DISABLE_COPY(QWebEngineFullScreenRequest)
- QWebEngineFullScreenRequest(QWebEnginePagePrivate *pagePrivate, const QUrl &origin, bool toggleOn);
- QWebEnginePagePrivate *m_pagePrivate;
+ QWebEngineFullScreenRequest(QWebEnginePage *page, const QUrl &origin, bool toggleOn);
+ QPointer<QWebEnginePage> m_page;
const QUrl m_origin;
const bool m_toggleOn;
friend class QWebEnginePagePrivate;
diff --git a/src/webenginewidgets/api/qwebenginehistory.h b/src/webenginewidgets/api/qwebenginehistory.h
index 0471e28e6..3dcea9469 100644
--- a/src/webenginewidgets/api/qwebenginehistory.h
+++ b/src/webenginewidgets/api/qwebenginehistory.h
@@ -65,6 +65,9 @@ public:
QUrl iconUrl() const;
bool isValid() const;
+
+ void swap(QWebEngineHistoryItem &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+
private:
QWebEngineHistoryItem(QWebEngineHistoryItemPrivate *priv);
Q_DECLARE_PRIVATE_D(d.data(), QWebEngineHistoryItem)
@@ -73,6 +76,7 @@ private:
friend class QWebEngineHistoryPrivate;
};
+Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineHistoryItem)
class QWebEngineHistoryPrivate;
class QWEBENGINEWIDGETS_EXPORT QWebEngineHistory {
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index dd71db6a0..e85021832 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -55,6 +55,7 @@
#include <QIcon>
#include <QInputDialog>
#include <QLayout>
+#include <QLoggingCategory>
#include <QMenu>
#include <QMessageBox>
#include <QMimeData>
@@ -431,7 +432,7 @@ QWebEnginePage::QWebEnginePage(QObject* parent)
*/
/*!
- \fn QWebEnginePage::fullScreenRequested(const QWebEngineFullScreenRequest &request)
+ \fn QWebEnginePage::fullScreenRequested(QWebEngineFullScreenRequest request)
This signal is emitted when the web page issues the request to enter fullscreen mode for
a web-element, usually a video element.
@@ -877,9 +878,19 @@ bool QWebEnginePage::event(QEvent *e)
return QObject::event(e);
}
+void QWebEnginePagePrivate::wasShown()
+{
+ adapter->wasShown();
+}
+
+void QWebEnginePagePrivate::wasHidden()
+{
+ adapter->wasHidden();
+}
+
bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData &data)
{
- if (!view)
+ if (!view || !view->d_func()->m_pendingContextMenuEvent)
return false;
m_menuData = WebEngineContextMenuData();
@@ -905,7 +916,6 @@ bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData
return false;
break;
}
- Q_ASSERT(view->d_func()->m_pendingContextMenuEvent);
view->d_func()->m_pendingContextMenuEvent = false;
return true;
}
@@ -920,7 +930,7 @@ void QWebEnginePagePrivate::navigationRequested(int navigationType, const QUrl &
void QWebEnginePagePrivate::requestFullScreenMode(const QUrl &origin, bool fullscreen)
{
Q_Q(QWebEnginePage);
- QWebEngineFullScreenRequest request(this, origin, fullscreen);
+ QWebEngineFullScreenRequest request(q, origin, fullscreen);
Q_EMIT q->fullScreenRequested(request);
}
@@ -1230,8 +1240,12 @@ void QWebEnginePage::runJavaScript(const QString& scriptSource, const QWebEngine
}
/*!
- Returns the script collection used by this page.
- \sa QWebEngineScriptCollection
+ Returns the collection of scripts that are injected into the page.
+
+ In addition, a page might also execute scripts
+ added through QWebEngineProfile::scripts().
+
+ \sa QWebEngineScriptCollection, QWebEngineScript
*/
QWebEngineScriptCollection &QWebEnginePage::scripts()
@@ -1309,10 +1323,24 @@ bool QWebEnginePage::javaScriptPrompt(const QUrl &securityOrigin, const QString
void QWebEnginePage::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID)
{
- Q_UNUSED(level);
- Q_UNUSED(message);
- Q_UNUSED(lineNumber);
- Q_UNUSED(sourceID);
+ static QLoggingCategory loggingCategory("js", QtWarningMsg);
+ static QByteArray file = sourceID.toUtf8();
+ QMessageLogger logger(file.constData(), lineNumber, nullptr, loggingCategory.categoryName());
+
+ switch (level) {
+ case JavaScriptConsoleMessageLevel::InfoMessageLevel:
+ if (loggingCategory.isInfoEnabled())
+ logger.info().noquote() << message;
+ break;
+ case JavaScriptConsoleMessageLevel::WarningMessageLevel:
+ if (loggingCategory.isWarningEnabled())
+ logger.warning().noquote() << message;
+ break;
+ case JavaScriptConsoleMessageLevel::ErrorMessageLevel:
+ if (loggingCategory.isCriticalEnabled())
+ logger.critical().noquote() << message;
+ break;
+ }
}
bool QWebEnginePage::certificateError(const QWebEngineCertificateError &)
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index 9740c89c9..69f8822b1 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -258,7 +258,7 @@ Q_SIGNALS:
void featurePermissionRequested(const QUrl &securityOrigin, QWebEnginePage::Feature feature);
void featurePermissionRequestCanceled(const QUrl &securityOrigin, QWebEnginePage::Feature feature);
- void fullScreenRequested(const QWebEngineFullScreenRequest &fullScreenRequest);
+ void fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest);
void authenticationRequired(const QUrl &requestUrl, QAuthenticator *authenticator);
void proxyAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *authenticator, const QString &proxyHost);
@@ -292,6 +292,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_webActionTriggered(bool checked))
#endif
+ friend class QWebEngineFullScreenRequest;
friend class QWebEngineView;
friend class QWebEngineViewPrivate;
#ifndef QT_NO_ACCESSIBILITY
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 66a2cf35b..dd43b08c8 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -131,6 +131,9 @@ public:
void updateNavigationActions();
void _q_webActionTriggered(bool checked);
+ void wasShown();
+ void wasHidden();
+
QtWebEngineCore::WebContentsAdapter *webContents() { return adapter.data(); }
void recreateFromSerializedHistory(QDataStream &input);
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index 2edebdfeb..5fbc4d63c 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -199,7 +199,7 @@ void QWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info)
*/
QWebEngineProfile::QWebEngineProfile(QObject *parent)
: QObject(parent)
- , d_ptr(new QWebEngineProfilePrivate(new BrowserContextAdapter(false)))
+ , d_ptr(new QWebEngineProfilePrivate(new BrowserContextAdapter(true)))
{
d_ptr->q_ptr = this;
}
@@ -490,8 +490,10 @@ bool QWebEngineProfile::visitedLinksContainsUrl(const QUrl &url) const
}
/*!
- Returns the script collection used by this profile.
- \sa QWebEngineScriptCollection
+ Returns the collection of scripts that are injected into all pages that share
+ this profile.
+
+ \sa QWebEngineScriptCollection, QWebEngineScript, QWebEnginePage::scripts()
*/
QWebEngineScriptCollection *QWebEngineProfile::scripts() const
{
diff --git a/src/webenginewidgets/api/qwebenginescript.cpp b/src/webenginewidgets/api/qwebenginescript.cpp
index 1bd56604d..058f58475 100644
--- a/src/webenginewidgets/api/qwebenginescript.cpp
+++ b/src/webenginewidgets/api/qwebenginescript.cpp
@@ -58,6 +58,9 @@ using QtWebEngineCore::UserScript;
not accessible from a different one. ScriptWorldId provides some predefined IDs for this
purpose.
+ Use QWebEnginePage::scripts() and QWebEngineProfile::scripts() to access
+ the collection of scripts associated with a single page or a
+ number of pages sharing the same profile.
*/
/*!
\enum QWebEngineScript::InjectionPoint
diff --git a/src/webenginewidgets/api/qwebenginescript.h b/src/webenginewidgets/api/qwebenginescript.h
index 4cff2631d..29126b110 100644
--- a/src/webenginewidgets/api/qwebenginescript.h
+++ b/src/webenginewidgets/api/qwebenginescript.h
@@ -99,7 +99,7 @@ private:
QSharedDataPointer<QtWebEngineCore::UserScript> d;
};
-Q_DECLARE_SHARED(QWebEngineScript)
+Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineScript)
#ifndef QT_NO_DEBUG_STREAM
QWEBENGINEWIDGETS_EXPORT QDebug operator<<(QDebug, const QWebEngineScript &);
diff --git a/src/webenginewidgets/api/qwebenginescriptcollection.cpp b/src/webenginewidgets/api/qwebenginescriptcollection.cpp
index 80a7f9b6e..9967cde85 100644
--- a/src/webenginewidgets/api/qwebenginescriptcollection.cpp
+++ b/src/webenginewidgets/api/qwebenginescriptcollection.cpp
@@ -47,6 +47,11 @@ using QtWebEngineCore::UserScript;
\since 5.5
\brief The QWebEngineScriptCollection class represents a collection of user scripts.
+ QWebEngineScriptCollection manages a set of user scripts.
+
+ Use QWebEnginePage::scripts() and QWebEngineProfile::scripts() to access
+ the collection of scripts associated with a single page or a
+ number of pages sharing the same profile.
*/
/*!
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index 9baa8e34a..362849732 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -294,6 +294,24 @@ void QWebEngineView::contextMenuEvent(QContextMenuEvent *event)
menu->popup(event->globalPos());
}
+/*!
+ * \reimp
+ */
+void QWebEngineView::showEvent(QShowEvent *event)
+{
+ QWidget::showEvent(event);
+ page()->d_ptr->wasShown();
+}
+
+/*!
+ * \reimp
+ */
+void QWebEngineView::hideEvent(QHideEvent *event)
+{
+ QWidget::hideEvent(event);
+ page()->d_ptr->wasHidden();
+}
+
#ifndef QT_NO_ACCESSIBILITY
int QWebEngineViewAccessible::childCount() const
{
diff --git a/src/webenginewidgets/api/qwebengineview.h b/src/webenginewidgets/api/qwebengineview.h
index ae38e6c5c..e16bbf4af 100644
--- a/src/webenginewidgets/api/qwebengineview.h
+++ b/src/webenginewidgets/api/qwebengineview.h
@@ -120,6 +120,8 @@ protected:
virtual QWebEngineView *createWindow(QWebEnginePage::WebWindowType type);
virtual void contextMenuEvent(QContextMenuEvent*) Q_DECL_OVERRIDE;
virtual bool event(QEvent*) Q_DECL_OVERRIDE;
+ virtual void showEvent(QShowEvent *) Q_DECL_OVERRIDE;
+ virtual void hideEvent(QHideEvent *) Q_DECL_OVERRIDE;
private:
Q_DISABLE_COPY(QWebEngineView)
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index b7b3bf022..17dd15630 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -262,7 +262,10 @@
\a level indicates the severity of the event that triggered the message. That is, whether it
was triggered by an error or a less severe event.
- The default implementation prints nothing.
+ Since Qt 5.6, the default implementation logs the messages in a \c js
+ \l{QLoggingCategory}{logging category}.
+
+ \sa{Console Logging}
*/
/*!
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 76ca8d354..57631c4cc 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -139,14 +139,12 @@ void RenderWidgetHostViewQtDelegateWidget::show()
// want to show anything else than popups as top-level.
if (parent() || m_isPopup) {
QOpenGLWidget::show();
- m_client->notifyShown();
}
}
void RenderWidgetHostViewQtDelegateWidget::hide()
{
QOpenGLWidget::hide();
- m_client->notifyHidden();
}
bool RenderWidgetHostViewQtDelegateWidget::isVisible() const
@@ -257,6 +255,13 @@ void RenderWidgetHostViewQtDelegateWidget::showEvent(QShowEvent *event)
m_windowConnections.append(connect(w, SIGNAL(yChanged(int)), SLOT(onWindowPosChanged())));
}
m_client->windowChanged();
+ m_client->notifyShown();
+}
+
+void RenderWidgetHostViewQtDelegateWidget::hideEvent(QHideEvent *event)
+{
+ QOpenGLWidget::hideEvent(event);
+ m_client->notifyHidden();
}
bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event)
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
index d228bd487..fddc79c2f 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
@@ -84,6 +84,7 @@ protected:
bool event(QEvent *event) Q_DECL_OVERRIDE;
void resizeEvent(QResizeEvent *resizeEvent) Q_DECL_OVERRIDE;
void showEvent(QShowEvent *) Q_DECL_OVERRIDE;
+ void hideEvent(QHideEvent *) Q_DECL_OVERRIDE;
void initializeGL() Q_DECL_OVERRIDE;
void paintGL() Q_DECL_OVERRIDE;
diff --git a/tests/auto/core/core.pro b/tests/auto/core/core.pro
index ed0a61532..713c71d14 100644
--- a/tests/auto/core/core.pro
+++ b/tests/auto/core/core.pro
@@ -1,7 +1,5 @@
TEMPLATE = subdirs
-CONFIG += ordered
-
SUBDIRS += \
qwebenginecookiestoreclient \
qwebengineurlrequestinterceptor \
diff --git a/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.cpp b/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.cpp
index d78a81c21..ed2a5a55b 100644
--- a/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.cpp
+++ b/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.cpp
@@ -121,6 +121,7 @@ void tst_QWebEngineCookieStoreClient::cookieSignals()
void tst_QWebEngineCookieStoreClient::setAndDeleteCookie()
{
+ QTest::qWait(500); // remove, when QTBUG-47946 is fixed!
QWebEngineView view;
QWebEngineCookieStoreClient *client = view.page()->profile()->cookieStoreClient();
@@ -158,6 +159,7 @@ void tst_QWebEngineCookieStoreClient::setAndDeleteCookie()
void tst_QWebEngineCookieStoreClient::batchCookieTasks()
{
+ QTest::qWait(500); // remove, when QTBUG-47946 is fixed!
QWebEngineView view;
QWebEngineCookieStoreClient *client = view.page()->profile()->cookieStoreClient();
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
index 4891cafd0..4a261c46b 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -146,7 +146,6 @@ void tst_QWebEngineUrlRequestInterceptor::interceptRequest()
loadSpy.clear();
QCOMPARE(interceptor.observedUrls.count(), 4);
-
// Make sure that registering an observer does not modify the request.
TestRequestInterceptor observer(/* intercept */ false);
view.page()->profile()->setRequestInterceptor(&observer);
diff --git a/tests/auto/core/tests.pri b/tests/auto/core/tests.pri
index cd6ef8615..606ed2a8c 100644
--- a/tests/auto/core/tests.pri
+++ b/tests/auto/core/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/plugin.cpp b/tests/auto/widgets/positionplugin/plugin.cpp
new file mode 100644
index 000000000..74d30469d
--- /dev/null
+++ b/tests/auto/widgets/positionplugin/plugin.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtPositioning/qgeopositioninfosource.h>
+#include <QtPositioning/qgeopositioninfosourcefactory.h>
+#include <QObject>
+#include <QtPlugin>
+
+class DummySource : public QGeoPositionInfoSource
+{
+ Q_OBJECT
+
+public:
+ DummySource(QObject *parent=0);
+
+ void startUpdates() {}
+ void stopUpdates() {}
+ void requestUpdate(int) {}
+
+ QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const;
+ PositioningMethods supportedPositioningMethods() const;
+
+ int minimumUpdateInterval() const;
+ Error error() const;
+};
+
+DummySource::DummySource(QObject *parent) :
+ QGeoPositionInfoSource(parent)
+{
+}
+
+QGeoPositionInfoSource::Error DummySource::error() const
+{
+ return QGeoPositionInfoSource::NoError;
+}
+
+int DummySource::minimumUpdateInterval() const
+{
+ return 1000;
+}
+
+QGeoPositionInfo DummySource::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const
+{
+ Q_UNUSED(fromSatellitePositioningMethodsOnly);
+ return QGeoPositionInfo(QGeoCoordinate(54.186824, 12.087262), QDateTime::currentDateTime());
+}
+
+QGeoPositionInfoSource::PositioningMethods DummySource::supportedPositioningMethods() const
+{
+ return QGeoPositionInfoSource::AllPositioningMethods;
+}
+
+
+class QGeoPositionInfoSourceFactoryTest : public QObject, public QGeoPositionInfoSourceFactory
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/5.0"
+ FILE "plugin.json")
+ Q_INTERFACES(QGeoPositionInfoSourceFactory)
+
+public:
+ QGeoPositionInfoSource *positionInfoSource(QObject *parent);
+ QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent);
+ QGeoAreaMonitorSource *areaMonitor(QObject *parent);
+};
+
+QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryTest::positionInfoSource(QObject *parent)
+{
+ return new DummySource(parent);
+}
+
+QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryTest::satelliteInfoSource(QObject *)
+{
+ return 0;
+}
+
+QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryTest::areaMonitor(QObject* )
+{
+ return 0;
+}
+
+#include "plugin.moc"
diff --git a/tests/auto/widgets/positionplugin/plugin.json b/tests/auto/widgets/positionplugin/plugin.json
new file mode 100644
index 000000000..68acaded3
--- /dev/null
+++ b/tests/auto/widgets/positionplugin/plugin.json
@@ -0,0 +1,9 @@
+{
+ "Keys": ["test.source"],
+ "Provider": "test.source",
+ "Position": true,
+ "Satellite": false,
+ "Monitor": false,
+ "Priority": 0,
+ "Testable": true
+}
diff --git a/tests/auto/widgets/positionplugin/positionplugin.pro b/tests/auto/widgets/positionplugin/positionplugin.pro
new file mode 100644
index 000000000..bca3e5756
--- /dev/null
+++ b/tests/auto/widgets/positionplugin/positionplugin.pro
@@ -0,0 +1,12 @@
+TARGET = qtwebengine_positioning_testplugin
+QT += positioning
+
+PLUGIN_TYPE = position
+PLUGIN_CLASS_NAME = TestPositionPlugin
+PLUGIN_EXTENDS = -
+load(qt_plugin)
+
+SOURCES += plugin.cpp
+
+OTHER_FILES += \
+ plugin.json
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index da19acbf6..50914a920 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -151,7 +151,6 @@ private Q_SLOTS:
void defaultTextEncoding();
void errorPageExtension();
void errorPageExtensionLoadFinished();
- void userAgentApplicationName();
void userAgentNewlineStripping();
void undoActionHaveCustomText();
void renderWidgetHostViewNotShowTopLevel();
@@ -289,6 +288,15 @@ void tst_QWebEnginePage::cleanupFiles()
void tst_QWebEnginePage::initTestCase()
{
cleanupFiles(); // In case there are old files from previous runs
+
+ // Set custom path since the CI doesn't install test plugins.
+ // Stolen from qtlocation/tests/auto/positionplugintest.
+ QString searchPath = QCoreApplication::applicationDirPath();
+#ifdef Q_OS_WIN
+ searchPath += QStringLiteral("/..");
+#endif
+ searchPath += QStringLiteral("/../../../plugins");
+ QCoreApplication::addLibraryPath(searchPath);
}
void tst_QWebEnginePage::cleanupTestCase()
@@ -2790,28 +2798,6 @@ void tst_QWebEnginePage::errorPageExtensionLoadFinished()
#endif
}
-class FriendlyWebPage : public QWebEnginePage
-{
-public:
- friend class tst_QWebEnginePage;
-};
-
-void tst_QWebEnginePage::userAgentApplicationName()
-{
-#if !defined(QWEBENGINEPAGE_USERAGENTFORURL)
- QSKIP("QWEBENGINEPAGE_USERAGENTFORURL");
-#else
- const QString oldApplicationName = QCoreApplication::applicationName();
- FriendlyWebPage page;
-
- const QString applicationNameMarker = QString::fromUtf8("StrangeName\342\210\236");
- QCoreApplication::setApplicationName(applicationNameMarker);
- QVERIFY(page.userAgentForUrl(QUrl()).contains(applicationNameMarker));
-
- QCoreApplication::setApplicationName(oldApplicationName);
-#endif
-}
-
void tst_QWebEnginePage::userAgentNewlineStripping()
{
QWebEngineProfile profile;
@@ -3758,7 +3744,7 @@ void tst_QWebEnginePage::fullScreenRequested()
// FullscreenRequest must be a user gesture
bool acceptRequest = true;
connect(page, &QWebEnginePage::fullScreenRequested,
- [&acceptRequest](const QWebEngineFullScreenRequest &request) {
+ [&acceptRequest](QWebEngineFullScreenRequest request) {
if (acceptRequest) request.accept(); else request.reject();
});
diff --git a/tests/auto/widgets/qwebengineprofile/qwebengineprofile.pro b/tests/auto/widgets/qwebengineprofile/qwebengineprofile.pro
new file mode 100644
index 000000000..e56bbe8f7
--- /dev/null
+++ b/tests/auto/widgets/qwebengineprofile/qwebengineprofile.pro
@@ -0,0 +1,3 @@
+include(../tests.pri)
+exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc
+QT *= core-private gui-private
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
new file mode 100644
index 000000000..09929d33f
--- /dev/null
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 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 "../util.h"
+#include <QtTest/QtTest>
+#include <qwebengineprofile.h>
+
+class tst_QWebEngineProfile : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void defaultProfile();
+ void profileConstructors();
+};
+
+void tst_QWebEngineProfile::defaultProfile()
+{
+ QWebEngineProfile *profile = QWebEngineProfile::defaultProfile();
+ QVERIFY(profile);
+ QVERIFY(!profile->isOffTheRecord());
+ QCOMPARE(profile->storageName(), QStringLiteral("Default"));
+ QCOMPARE(profile->httpCacheType(), QWebEngineProfile::DiskHttpCache);
+ QCOMPARE(profile->persistentCookiesPolicy(), QWebEngineProfile::AllowPersistentCookies);
+}
+
+void tst_QWebEngineProfile::profileConstructors()
+{
+ QWebEngineProfile otrProfile;
+ QWebEngineProfile diskProfile(QStringLiteral("Test"));
+
+ QVERIFY(otrProfile.isOffTheRecord());
+ QVERIFY(!diskProfile.isOffTheRecord());
+ QCOMPARE(diskProfile.storageName(), QStringLiteral("Test"));
+ QCOMPARE(otrProfile.httpCacheType(), QWebEngineProfile::MemoryHttpCache);
+ QCOMPARE(diskProfile.httpCacheType(), QWebEngineProfile::DiskHttpCache);
+ QCOMPARE(otrProfile.persistentCookiesPolicy(), QWebEngineProfile::NoPersistentCookies);
+ QCOMPARE(diskProfile.persistentCookiesPolicy(), QWebEngineProfile::AllowPersistentCookies);
+
+}
+
+QTEST_MAIN(tst_QWebEngineProfile)
+#include "tst_qwebengineprofile.moc"
diff --git a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
index b29d8fae6..53762f54c 100644
--- a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
+++ b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
@@ -25,18 +25,6 @@
#include <qwebengineview.h>
#include "../util.h"
-//#define DEBUG_SCRIPT_MESSAGES
-#ifdef DEBUG_SCRIPT_MESSAGES
-class WebEnginePage : public QWebEnginePage {
- void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID) {
- qDebug() << level << message << lineNumber << sourceID;
- }
-
-};
-#else
-typedef QWebEnginePage WebEnginePage;
-#endif
-
class tst_QWebEngineScript: public QObject {
Q_OBJECT
@@ -49,10 +37,9 @@ private Q_SLOTS:
};
-
void tst_QWebEngineScript::domEditing()
{
- WebEnginePage page;
+ QWebEnginePage page;
QWebEngineView view;
view.setPage(&page);
QWebEngineScript s;
@@ -88,7 +75,7 @@ void tst_QWebEngineScript::injectionPoint()
s.setSourceCode("var foo = \"foobar\";");
s.setInjectionPoint(static_cast<QWebEngineScript::InjectionPoint>(injectionPoint));
s.setWorldId(QWebEngineScript::MainWorld);
- WebEnginePage page;
+ QWebEnginePage page;
page.scripts().insert(s);
page.setHtml(QStringLiteral("<html><head><script> var contents;") + testScript
+ QStringLiteral("document.addEventListener(\"load\", setTimeout(function(event) {\
@@ -96,8 +83,7 @@ void tst_QWebEngineScript::injectionPoint()
}, 550));\
</script></head><body></body></html>"));
waitForSignal(&page, SIGNAL(loadFinished(bool)));
- QTest::qWait(550);
- QCOMPARE(evaluateJavaScriptSync(&page, "document.body.innerText"), QVariant::fromValue(QStringLiteral("SUCCESS")));
+ QTRY_COMPARE(evaluateJavaScriptSync(&page, "document.body.innerText"), QVariant::fromValue(QStringLiteral("SUCCESS")));
}
void tst_QWebEngineScript::injectionPoint_data()
@@ -108,9 +94,10 @@ void tst_QWebEngineScript::injectionPoint_data()
<< QStringLiteral("var contents = (typeof(foo) == \"undefined\")? \"FAILURE\" : \"SUCCESS\";");
QTest::newRow("DocumentReady") << static_cast<int>(QWebEngineScript::DocumentReady)
// use a zero timeout to make sure the user script got a chance to run as the order is undefined.
- << QStringLiteral("document.addEventListener(\"DOMContentLoaded\", setTimeout(function(event) {\
+ << QStringLiteral("document.addEventListener(\"DOMContentLoaded\", function() {\
+ setTimeout(function() {\
contents = (typeof(foo) == \"undefined\")? \"FAILURE\" : \"SUCCESS\";\
- }, 0));");
+ }, 0)});");
QTest::newRow("Deferred") << static_cast<int>(QWebEngineScript::Deferred)
<< QStringLiteral("document.addEventListener(\"load\", setTimeout(function(event) {\
contents = (typeof(foo) == \"undefined\")? \"FAILURE\" : \"SUCCESS\";\
@@ -119,7 +106,7 @@ void tst_QWebEngineScript::injectionPoint_data()
void tst_QWebEngineScript::scriptWorld()
{
- WebEnginePage page;
+ QWebEnginePage page;
QWebEngineScript script;
script.setInjectionPoint(QWebEngineScript::DocumentCreation);
script.setWorldId(QWebEngineScript::MainWorld);
@@ -138,7 +125,7 @@ void tst_QWebEngineScript::scriptWorld()
void tst_QWebEngineScript::scriptModifications()
{
- WebEnginePage page;
+ QWebEnginePage page;
QWebEngineScript script;
script.setName(QStringLiteral("String1"));
script.setInjectionPoint(QWebEngineScript::DocumentCreation);
diff --git a/tests/auto/widgets/qwebenginesettings/qwebenginesettings.pro b/tests/auto/widgets/qwebenginesettings/qwebenginesettings.pro
new file mode 100644
index 000000000..70786e70f
--- /dev/null
+++ b/tests/auto/widgets/qwebenginesettings/qwebenginesettings.pro
@@ -0,0 +1,2 @@
+include(../tests.pri)
+QT *= core-private gui-private
diff --git a/tests/auto/widgets/qwebenginesettings/tst_qwebenginesettings.cpp b/tests/auto/widgets/qwebenginesettings/tst_qwebenginesettings.cpp
new file mode 100644
index 000000000..0f6a6062e
--- /dev/null
+++ b/tests/auto/widgets/qwebenginesettings/tst_qwebenginesettings.cpp
@@ -0,0 +1,63 @@
+/*
+ Copyright (C) 2015 The Qt Company Ltd.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <QtTest/QtTest>
+
+#include <qwebengineprofile.h>
+#include <qwebenginesettings.h>
+
+class tst_QWebEngineSettings: public QObject {
+ Q_OBJECT
+
+private Q_SLOTS:
+ void resetAttributes();
+};
+
+void tst_QWebEngineSettings::resetAttributes()
+{
+ QWebEngineProfile profile;
+ QWebEngineSettings *settings = profile.settings();
+
+ // Attribute
+ bool defaultValue = settings->testAttribute(QWebEngineSettings::FullScreenSupportEnabled);
+ settings->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, !defaultValue);
+ QCOMPARE(!defaultValue, settings->testAttribute(QWebEngineSettings::FullScreenSupportEnabled));
+ settings->resetAttribute(QWebEngineSettings::FullScreenSupportEnabled);
+ QCOMPARE(defaultValue, settings->testAttribute(QWebEngineSettings::FullScreenSupportEnabled));
+
+ // Font family
+ QString defaultFamily = settings->fontFamily(QWebEngineSettings::StandardFont);
+ QString newFontFamily("PugDog");
+ settings->setFontFamily(QWebEngineSettings::StandardFont, newFontFamily);
+ QCOMPARE(newFontFamily, settings->fontFamily(QWebEngineSettings::StandardFont));
+ settings->resetFontFamily(QWebEngineSettings::StandardFont);
+ QCOMPARE(defaultFamily, settings->fontFamily(QWebEngineSettings::StandardFont));
+
+ // Font size
+ int defaultSize = settings->fontSize(QWebEngineSettings::MinimumFontSize);
+ int newSize = defaultSize + 10;
+ settings->setFontSize(QWebEngineSettings::MinimumFontSize, newSize);
+ QCOMPARE(newSize, settings->fontSize(QWebEngineSettings::MinimumFontSize));
+ settings->resetFontSize(QWebEngineSettings::MinimumFontSize);
+ QCOMPARE(defaultSize, settings->fontSize(QWebEngineSettings::MinimumFontSize));
+}
+
+QTEST_MAIN(tst_QWebEngineSettings)
+
+#include "tst_qwebenginesettings.moc"
diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro
index b2df0880d..986d5bbee 100644
--- a/tests/auto/widgets/widgets.pro
+++ b/tests/auto/widgets/widgets.pro
@@ -1,12 +1,17 @@
TEMPLATE = subdirs
-CONFIG += ordered
-
SUBDIRS += \
qwebengineaccessibility \
qwebenginepage \
- qwebenginehistoryinterface \
- qwebengineview \
qwebenginehistory \
+ qwebenginehistoryinterface \
qwebengineinspector \
+ qwebengineprofile \
qwebenginescript \
+ qwebenginesettings \
+ qwebengineview
+
+qtHaveModule(positioning) {
+ SUBDIRS += positionplugin
+ qwebenginepage.depends = positionplugin
+}
diff --git a/tests/quicktestbrowser/BrowserWindow.qml b/tests/quicktestbrowser/BrowserWindow.qml
index ca0b6499b..3fcca4aab 100644
--- a/tests/quicktestbrowser/BrowserWindow.qml
+++ b/tests/quicktestbrowser/BrowserWindow.qml
@@ -61,8 +61,10 @@ ApplicationWindow {
// This is for the case where the system forces us to leave fullscreen.
if (currentWebView && !isFullScreen) {
currentWebView.state = ""
- if (currentWebView.isFullScreen)
+ if (currentWebView.isFullScreen) {
currentWebView.fullScreenCancelled()
+ fullScreenNotification.hide()
+ }
}
}
@@ -397,9 +399,11 @@ ApplicationWindow {
webEngineView.state = "FullScreen"
browserWindow.previousVisibility = browserWindow.visibility
browserWindow.showFullScreen()
+ fullScreenNotification.show()
} else {
webEngineView.state = ""
browserWindow.visibility = browserWindow.previousVisibility
+ fullScreenNotification.hide()
}
request.accept()
}
@@ -502,6 +506,10 @@ ApplicationWindow {
}
}
+ FullScreenNotification {
+ id: fullScreenNotification
+ }
+
DownloadView {
id: downloadView
visible: false
diff --git a/tests/quicktestbrowser/FullScreenNotification.qml b/tests/quicktestbrowser/FullScreenNotification.qml
new file mode 100644
index 000000000..80a63d479
--- /dev/null
+++ b/tests/quicktestbrowser/FullScreenNotification.qml
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 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: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.5
+
+Rectangle {
+ id: fullScreenNotification
+ width: 500
+ height: 40
+ color: "white"
+ radius: 7
+
+ visible: false
+ opacity: 0
+
+ function show() {
+ visible = true
+ opacity = 1
+ reset.start()
+ }
+
+ function hide() {
+ reset.stop()
+ opacity = 0
+ }
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: 750
+ onStopped: {
+ if (opacity == 0)
+ visible = false
+ }
+ }
+ }
+
+ Timer {
+ id: reset
+ interval: 5000
+ onTriggered: hide()
+ }
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ y: 125
+
+ Text {
+ id: message
+ width: parent.width
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+
+ wrapMode: Text.WordWrap
+ elide: Text.ElideNone
+ clip: true
+
+ text: qsTr("You are now in fullscreen mode. Press ESC to quit!")
+ }
+}
diff --git a/tests/quicktestbrowser/quicktestbrowser.pro b/tests/quicktestbrowser/quicktestbrowser.pro
index 7d6dfa6df..996e82a63 100644
--- a/tests/quicktestbrowser/quicktestbrowser.pro
+++ b/tests/quicktestbrowser/quicktestbrowser.pro
@@ -14,7 +14,8 @@ OTHER_FILES += ApplicationRoot.qml \
ButtonWithMenu.qml \
ContextMenuExtras.qml \
DownloadView.qml \
- FeaturePermissionBar.qml
+ FeaturePermissionBar.qml \
+ FullScreenNotification.qml
RESOURCES += resources.qrc
diff --git a/tests/quicktestbrowser/resources.qrc b/tests/quicktestbrowser/resources.qrc
index 80f1d1543..2dcda4d0d 100644
--- a/tests/quicktestbrowser/resources.qrc
+++ b/tests/quicktestbrowser/resources.qrc
@@ -5,6 +5,7 @@
<file>BrowserWindow.qml</file>
<file>ContextMenuExtras.qml</file>
<file>FeaturePermissionBar.qml</file>
+ <file>FullScreenNotification.qml</file>
<file>ButtonWithMenu.qml</file>
<file>DownloadView.qml</file>
<file>ZoomController.qml</file>
diff --git a/tools/qmake/mkspecs/features/configure.prf b/tools/qmake/mkspecs/features/configure.prf
index 5799d01ae..7f749146a 100644
--- a/tools/qmake/mkspecs/features/configure.prf
+++ b/tools/qmake/mkspecs/features/configure.prf
@@ -25,14 +25,11 @@ defineTest(runConfigure) {
!config_libcap:skipBuild("libcap development package appears to be missing")
!config_khr:skipBuild("khronos development headers appear to be missing (mesa/libegl1-mesa-dev)")
- REQUIRED_PACKAGES = dbus-1 fontconfig freetype2
+ REQUIRED_PACKAGES = dbus-1 fontconfig
contains(QT_CONFIG, xcb): REQUIRED_PACKAGES += libdrm xcomposite xcursor xi xrandr xscrnsaver xtst
contains(QT_CONFIG, pulseaudio): REQUIRED_PACKAGES += libpulse
contains(QT_CONFIG, system-png): REQUIRED_PACKAGES += libpng
- contains(QT_CONFIG, system-harfbuzz)|packagesExist("\'freetype2 >= 2.5.3\'"): {
- WEBENGINE_CONFIG += use_system_harfbuzz
- REQUIRED_PACKAGES += harfbuzz
- }
+ contains(QT_CONFIG, system-harfbuzz): REQUIRED_PACKAGES += harfbuzz
!cross_compile: REQUIRED_PACKAGES += libpci
for(package, $$list($$REQUIRED_PACKAGES)) {
@@ -55,9 +52,10 @@ defineTest(runConfigure) {
config_snappy: WEBENGINE_CONFIG += use_system_snappy
else: log("System snappy not found. Using Chromium's copy.$${EOL}")
- # Optional dependencies
- packagesExist(nss): WEBENGINE_CONFIG += use_nss
- else: log("System NSS not found, BoringSSL will be used.$${EOL}")
+ !cross_compile {
+ packagesExist(nss): WEBENGINE_CONFIG += use_nss
+ else: log("System NSS not found, BoringSSL will be used.$${EOL}")
+ }
}
isEmpty(skipBuildReason): {
diff --git a/tools/qmake/mkspecs/features/functions.prf b/tools/qmake/mkspecs/features/functions.prf
index 9f54f4f3c..d5265ab00 100644
--- a/tools/qmake/mkspecs/features/functions.prf
+++ b/tools/qmake/mkspecs/features/functions.prf
@@ -1,4 +1,8 @@
defineTest(isPlatformSupported) {
+ !linux-g++*:!linux-clang:!win32-msvc2013*:!win32-msvc2015*:!macx-clang*:!boot2qt {
+ skipBuild("Qt WebEngine can currently only be built for Linux (GCC/clang), Windows (MSVC 2013 or 2015), OS X (10.9/XCode 5.1+) or Qt for Device Creation.")
+ return(false)
+ }
!contains(QT_CONFIG, c++11) {
skipBuild("C++11 support is required in order to build chromium.")
return(false)
@@ -22,11 +26,7 @@ defineTest(isPlatformSupported) {
linux-g++*:!isGCCVersionSupported(): return(false)
!isPythonVersionSupported(): return(false)
- linux-g++*|linux-clang|win32-msvc2013*|win32-msvc2015*|macx-clang*: return(true)
- boot2qt: return(true)
-
- skipBuild("Qt WebEngine can currently only be built for Linux (GCC/clang), Windows (MSVC 2013 or 2015), OS X (10.9/XCode 5.1+) or Qt for Device Creation.")
- return(false)
+ return(true)
}
defineTest(isPythonVersionSupported) {