summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dist/changes-5.9.161
-rw-r--r--examples/webengine/customdialogs/doc/src/customdialogs.qdoc9
-rw-r--r--examples/webengine/quicknanobrowser/doc/src/quicknanobrowser.qdoc2
-rw-r--r--examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc12
-rw-r--r--examples/webenginewidgets/contentmanipulation/mainwindow.cpp64
-rw-r--r--examples/webenginewidgets/demobrowser/browserapplication.cpp4
-rw-r--r--examples/webenginewidgets/demobrowser/browsermainwindow.cpp12
-rw-r--r--examples/webenginewidgets/demobrowser/browsermainwindow.h6
-rw-r--r--examples/webenginewidgets/demobrowser/printtopdfdialog.cpp7
-rw-r--r--examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc2
-rw-r--r--mkspecs/features/configure.prf4
-rw-r--r--mkspecs/features/functions.prf10
-rw-r--r--mkspecs/features/gn_generator.prf3
m---------src/3rdparty0
-rw-r--r--src/buildtools/configure_host.pro9
-rw-r--r--src/core/api/core_api.pro8
-rw-r--r--src/core/api/qtbug-60565.cpp9
-rw-r--r--src/core/browser_context_qt.cpp20
-rw-r--r--src/core/config/linux.pri7
-rw-r--r--src/core/config/windows.pri13
-rw-r--r--src/core/content_main_delegate_qt.cpp13
-rw-r--r--src/core/core.pro17
-rw-r--r--src/core/core_module.pro4
-rw-r--r--src/core/media_capture_devices_dispatcher.cpp36
-rw-r--r--src/core/qtwebengine.gni7
-rw-r--r--src/core/render_widget_host_view_qt.cpp16
-rw-r--r--src/core/resource_bundle_qt.cpp3
-rw-r--r--src/core/url_request_context_getter_qt.cpp6
-rw-r--r--src/core/web_contents_adapter.cpp3
-rw-r--r--src/core/web_contents_adapter_client.h4
-rw-r--r--src/core/web_contents_delegate_qt.cpp7
-rw-r--r--src/core/web_contents_delegate_qt.h2
-rw-r--r--src/webengine/api/qquickwebengineview.cpp10
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h4
-rw-r--r--src/webengine/doc/src/qtwebengine-platform-notes.qdoc2
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.cpp10
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp17
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h8
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h4
-rw-r--r--src/webenginewidgets/api/qwebenginesettings.cpp6
-rw-r--r--src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc34
-rw-r--r--src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc6
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp19
-rw-r--r--tests/auto/quick/qmltests/data/tst_download.qml17
-rw-r--r--tests/auto/quick/qmltests/data/tst_findText.qml58
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadProgress.qml21
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadProgressSignal.qml60
-rw-r--r--tests/auto/quick/qmltests/data/tst_newViewRequest.qml18
-rw-r--r--tests/auto/quick/qmltests/qmltests.pro1
-rw-r--r--tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp131
-rw-r--r--tests/auto/widgets/qwebengineview/BLACKLIST3
-rw-r--r--tests/auto/widgets/qwebengineview/resources/input_types.html14
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp270
53 files changed, 580 insertions, 513 deletions
diff --git a/dist/changes-5.9.1 b/dist/changes-5.9.1
new file mode 100644
index 000000000..8d361db10
--- /dev/null
+++ b/dist/changes-5.9.1
@@ -0,0 +1,61 @@
+Qt 5.9.1 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.9.0.
+
+Qt 5.9 introduces many new features and improvements as well as bugfixes
+over the 5.8.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.9 series is binary compatible with the 5.8.x series.
+Applications compiled for 5.8 will continue to run with 5.9.
+
+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 *
+****************************************************************************
+
+ - Chromium Snapshot:
+ * Security fixes from Chromium up to version 59.0.3071.104
+ Including: CVE-2017-5070, CVE-2017-5071, CVE-2017-5075, CVE-2017-5076,
+ CVE-2017-5077, CVE-2017-5078, CVE-2017-5079, CVE-2017-5083,
+ CVE-2017-5088, CVE-2017-5089
+ * Fixed building with WebRTC disabled
+
+ - QtWebEngineCore:
+ * [QTBUG-59690] Fixed issue with drops
+ * [QTBUG-60588] Fixed error in updating user-agent and accept-language
+ * [QTBUG-61047] Fixed assert in URLRequestContextGetterQt
+ * [QTBUG-61165] Fixed building with spellchecker disabled
+ * [QTBUG-61186] Fixed cancellation of upload folder dialogs
+ * [QTBUG-61200] Fixed runtime crash when configured with -no-accessibility
+
+ - QtWebEngine:
+ * [QTBUG-57675] Fixed WebEngineNewViewRequest::requestedUrl when opening
+ window from JavaScript
+
+
+****************************************************************************
+* Platform Specific Changes *
+****************************************************************************
+
+ - Linux:
+ * [QTBUG-60886] Support building with system ICU 59
+ * [QTBUG-61128] Support building on Aarch64 hosts
+
+ - Windows:
+ * [QTBUG-61170] Fixed building with plugins disabled
+ * Re-enabled building on 32-bit Windows hosts
+
+ - macOS:
+ * [QTBUG-55165] Fixed WebRTC screen sharing on macOS
+ * [QTBUG-60706] Find Google Chrome's flash plugin again
+ * [QTBUG-60707] Fixed spellchecker installation error
+ * [QTBUG-61413] Fixed erroneous extra rpath
diff --git a/examples/webengine/customdialogs/doc/src/customdialogs.qdoc b/examples/webengine/customdialogs/doc/src/customdialogs.qdoc
index f5a18b591..2162fe4ca 100644
--- a/examples/webengine/customdialogs/doc/src/customdialogs.qdoc
+++ b/examples/webengine/customdialogs/doc/src/customdialogs.qdoc
@@ -58,10 +58,11 @@
\section1 Triggering Dialogs
- The technical details on how the dialogs are triggered are beyond the scope
- of this example. The only thing worth mentioning is that we fire up the
- localhost TCP server when the example starts up. The server is needed to
- get proxy and HTTP authentication requests.
+ As mentioned, the \l {webengine/customdialogs/index.html}{index.html} file
+ is responsible for triggering the dialogs from the side of HTML and
+ JavaScript. Additionally, the example program starts a localhost TCP server
+ returning the mocked HTTP responses needed to trigger proxy and HTTP
+ authentication dialogs.
\section1 Custom Dialogs
diff --git a/examples/webengine/quicknanobrowser/doc/src/quicknanobrowser.qdoc b/examples/webengine/quicknanobrowser/doc/src/quicknanobrowser.qdoc
index 75c2997e8..93b3ed51a 100644
--- a/examples/webengine/quicknanobrowser/doc/src/quicknanobrowser.qdoc
+++ b/examples/webengine/quicknanobrowser/doc/src/quicknanobrowser.qdoc
@@ -43,7 +43,7 @@
screen mode by using a toolbar button. They can leave fullscreen mode by using a keyboard
shortcut. Additional toolbar buttons enable moving backwards and forwards in the browser
history, reloading tab content, and opening a settings menu for enabling the following features:
- JavaScript, plugins, fullscreen mode, off the record, HTTP disc cache, autoloading images, and
+ JavaScript, plugins, fullscreen mode, off the record, HTTP disk cache, autoloading images, and
ignoring certificate errors.
\include examples-run.qdocinc
diff --git a/examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc b/examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc
index aa94b17da..66a1252dc 100644
--- a/examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc
+++ b/examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc
@@ -36,7 +36,7 @@
\e{Content Manipulation} shows how to use JQuery with \l {Qt WebEngine Widgets} to
create a web browser with special effects and content manipulation.
- In the application, we call QWebEnginePage::runJavaScript() to
+ In the application, we call \l {QWebEnginePage::runJavaScript()} to
execute jQuery JavaScript code. We implement a QMainWindow with a QWebEngineView
as a central widget to build up the browser itself.
@@ -51,7 +51,7 @@
\skipto class MainWindow :
\printuntil /^\}/
- We also declare a QString that contains the jQuery, a QWebEngineView
+ We also declare a QString that contains jQuery, a QWebEngineView
that displays the web content, and a QLineEdit that acts as the
address bar.
@@ -74,9 +74,9 @@
The second part of the constructor creates a QWebEngineView and connects
slots to the view's signals:
- \printuntil SLOT(finishLoading
+ \printuntil MainWindow::finishLoading
- Furthermore, we create a QLineEdit as the browser's address bar. We then set the horizontal
+ Furthermore, we create a QLineEdit as the browser's address bar. We then set the vertical
QSizePolicy to fill the available area in the browser at all times. We add the
QLineEdit to a QToolBar together with a set of navigation actions from
QWebEngineView::pageAction():
@@ -136,10 +136,6 @@
\printuntil }
\printuntil }
- We append \c undefined after the jQuery call to prevent a possible recursion loop
- and crash caused by the way the elements returned by the each iterator elements
- reference each other, which causes problems upon converting them to QVariant.
-
The \c rotateImages() function rotates the images on the current
web page. This JavaScript code relies on CSS transforms. It
looks up all \e {img} elements and rotates the images 180 degrees
diff --git a/examples/webenginewidgets/contentmanipulation/mainwindow.cpp b/examples/webenginewidgets/contentmanipulation/mainwindow.cpp
index 74d647c69..154a37747 100644
--- a/examples/webenginewidgets/contentmanipulation/mainwindow.cpp
+++ b/examples/webenginewidgets/contentmanipulation/mainwindow.cpp
@@ -52,22 +52,6 @@
#include <QtWebEngineWidgets>
#include "mainwindow.h"
-template<typename Arg, typename R, typename C>
-struct InvokeWrapper {
- R *receiver;
- void (C::*memberFun)(Arg);
- void operator()(Arg result) {
- (receiver->*memberFun)(result);
- }
-};
-
-template<typename Arg, typename R, typename C>
-InvokeWrapper<Arg, R, C> invoke(R *receiver, void (C::*memberFun)(Arg))
-{
- InvokeWrapper<Arg, R, C> wrapper = {receiver, memberFun};
- return wrapper;
-}
-
MainWindow::MainWindow(const QUrl& url)
{
setAttribute(Qt::WA_DeleteOnClose, true);
@@ -82,14 +66,14 @@ MainWindow::MainWindow(const QUrl& url)
view = new QWebEngineView(this);
view->load(url);
- connect(view, SIGNAL(loadFinished(bool)), SLOT(adjustLocation()));
- connect(view, SIGNAL(titleChanged(QString)), SLOT(adjustTitle()));
- connect(view, SIGNAL(loadProgress(int)), SLOT(setProgress(int)));
- connect(view, SIGNAL(loadFinished(bool)), SLOT(finishLoading(bool)));
+ connect(view, &QWebEngineView::loadFinished, this, &MainWindow::adjustLocation);
+ connect(view, &QWebEngineView::titleChanged, this, &MainWindow::adjustTitle);
+ connect(view, &QWebEngineView::loadProgress, this, &MainWindow::setProgress);
+ connect(view, &QWebEngineView::loadFinished, this, &MainWindow::finishLoading);
locationEdit = new QLineEdit(this);
locationEdit->setSizePolicy(QSizePolicy::Expanding, locationEdit->sizePolicy().verticalPolicy());
- connect(locationEdit, SIGNAL(returnPressed()), SLOT(changeLocation()));
+ connect(locationEdit, &QLineEdit::returnPressed, this, &MainWindow::changeLocation);
QToolBar *toolBar = addToolBar(tr("Navigation"));
toolBar->addAction(view->pageAction(QWebEnginePage::Back));
@@ -99,38 +83,40 @@ MainWindow::MainWindow(const QUrl& url)
toolBar->addWidget(locationEdit);
QMenu *viewMenu = menuBar()->addMenu(tr("&View"));
- QAction* viewSourceAction = new QAction("Page Source", this);
- connect(viewSourceAction, SIGNAL(triggered()), SLOT(viewSource()));
+ QAction *viewSourceAction = new QAction(tr("Page Source"), this);
+ connect(viewSourceAction, &QAction::triggered, this, &MainWindow::viewSource);
viewMenu->addAction(viewSourceAction);
QMenu *effectMenu = menuBar()->addMenu(tr("&Effect"));
- effectMenu->addAction("Highlight all links", this, SLOT(highlightAllLinks()));
+ effectMenu->addAction(tr("Highlight all links"), this, &MainWindow::highlightAllLinks);
rotateAction = new QAction(this);
rotateAction->setIcon(style()->standardIcon(QStyle::SP_FileDialogDetailedView));
rotateAction->setCheckable(true);
rotateAction->setText(tr("Turn images upside down"));
- connect(rotateAction, SIGNAL(toggled(bool)), this, SLOT(rotateImages(bool)));
+ connect(rotateAction, &QAction::toggled, this, &MainWindow::rotateImages);
effectMenu->addAction(rotateAction);
QMenu *toolsMenu = menuBar()->addMenu(tr("&Tools"));
- toolsMenu->addAction(tr("Remove GIF images"), this, SLOT(removeGifImages()));
- toolsMenu->addAction(tr("Remove all inline frames"), this, SLOT(removeInlineFrames()));
- toolsMenu->addAction(tr("Remove all object elements"), this, SLOT(removeObjectElements()));
- toolsMenu->addAction(tr("Remove all embedded elements"), this, SLOT(removeEmbeddedElements()));
+ toolsMenu->addAction(tr("Remove GIF images"), this, &MainWindow::removeGifImages);
+ toolsMenu->addAction(tr("Remove all inline frames"), this, &MainWindow::removeInlineFrames);
+ toolsMenu->addAction(tr("Remove all object elements"), this, &MainWindow::removeObjectElements);
+ toolsMenu->addAction(tr("Remove all embedded elements"), this, &MainWindow::removeEmbeddedElements);
setCentralWidget(view);
}
void MainWindow::viewSource()
{
- QTextEdit* textEdit = new QTextEdit(NULL);
+ QTextEdit *textEdit = new QTextEdit(nullptr);
textEdit->setAttribute(Qt::WA_DeleteOnClose);
textEdit->adjustSize();
textEdit->move(this->geometry().center() - textEdit->rect().center());
textEdit->show();
- view->page()->toHtml(invoke(textEdit, &QTextEdit::setPlainText));
+ view->page()->toHtml([textEdit](const QString &html){
+ textEdit->setPlainText(html);
+ });
}
void MainWindow::adjustLocation()
@@ -150,7 +136,7 @@ void MainWindow::adjustTitle()
if (progress <= 0 || progress >= 100)
setWindowTitle(view->title());
else
- setWindowTitle(QString("%1 (%2%)").arg(view->title()).arg(progress));
+ setWindowTitle(QStringLiteral("%1 (%2%)").arg(view->title()).arg(progress));
}
void MainWindow::setProgress(int p)
@@ -170,7 +156,7 @@ void MainWindow::finishLoading(bool)
void MainWindow::highlightAllLinks()
{
- QString code = "qt.jQuery('a').each( function () { qt.jQuery(this).css('background-color', 'yellow') } ); undefined";
+ QString code = QStringLiteral("qt.jQuery('a').each( function () { qt.jQuery(this).css('background-color', 'yellow') } )");
view->page()->runJavaScript(code);
}
@@ -179,32 +165,32 @@ void MainWindow::rotateImages(bool invert)
QString code;
if (invert)
- code = "qt.jQuery('img').each( function () { qt.jQuery(this).css('-webkit-transition', '-webkit-transform 2s'); qt.jQuery(this).css('-webkit-transform', 'rotate(180deg)') } ); undefined";
+ code = QStringLiteral("qt.jQuery('img').each( function () { qt.jQuery(this).css('transition', 'transform 2s'); qt.jQuery(this).css('transform', 'rotate(180deg)') } )");
else
- code = "qt.jQuery('img').each( function () { qt.jQuery(this).css('-webkit-transition', '-webkit-transform 2s'); qt.jQuery(this).css('-webkit-transform', 'rotate(0deg)') } ); undefined";
+ code = QStringLiteral("qt.jQuery('img').each( function () { qt.jQuery(this).css('transition', 'transform 2s'); qt.jQuery(this).css('transform', 'rotate(0deg)') } )");
view->page()->runJavaScript(code);
}
void MainWindow::removeGifImages()
{
- QString code = "qt.jQuery('[src*=gif]').remove()";
+ QString code = QStringLiteral("qt.jQuery('[src*=gif]').remove()");
view->page()->runJavaScript(code);
}
void MainWindow::removeInlineFrames()
{
- QString code = "qt.jQuery('iframe').remove()";
+ QString code = QStringLiteral("qt.jQuery('iframe').remove()");
view->page()->runJavaScript(code);
}
void MainWindow::removeObjectElements()
{
- QString code = "qt.jQuery('object').remove()";
+ QString code = QStringLiteral("qt.jQuery('object').remove()");
view->page()->runJavaScript(code);
}
void MainWindow::removeEmbeddedElements()
{
- QString code = "qt.jQuery('embed').remove()";
+ QString code = QStringLiteral("qt.jQuery('embed').remove()");
view->page()->runJavaScript(code);
}
diff --git a/examples/webenginewidgets/demobrowser/browserapplication.cpp b/examples/webenginewidgets/demobrowser/browserapplication.cpp
index 32429a675..c3f3ef9b9 100644
--- a/examples/webenginewidgets/demobrowser/browserapplication.cpp
+++ b/examples/webenginewidgets/demobrowser/browserapplication.cpp
@@ -314,7 +314,9 @@ void BrowserApplication::loadSettings()
settings.endGroup();
settings.beginGroup(QLatin1String("cookies"));
- QWebEngineProfile::PersistentCookiesPolicy persistentCookiesPolicy = QWebEngineProfile::PersistentCookiesPolicy(settings.value(QLatin1String("persistentCookiesPolicy")).toInt());
+ QWebEngineProfile::PersistentCookiesPolicy persistentCookiesPolicy =
+ QWebEngineProfile::PersistentCookiesPolicy(settings.value(QLatin1String("persistentCookiesPolicy"),
+ QWebEngineProfile::AllowPersistentCookies).toInt());
defaultProfile->setPersistentCookiesPolicy(persistentCookiesPolicy);
QString pdataPath = settings.value(QLatin1String("persistentDataPath")).toString();
defaultProfile->setPersistentStoragePath(pdataPath);
diff --git a/examples/webenginewidgets/demobrowser/browsermainwindow.cpp b/examples/webenginewidgets/demobrowser/browsermainwindow.cpp
index 327d7a9d3..14d49f7f3 100644
--- a/examples/webenginewidgets/demobrowser/browsermainwindow.cpp
+++ b/examples/webenginewidgets/demobrowser/browsermainwindow.cpp
@@ -109,9 +109,7 @@ BrowserMainWindow::BrowserMainWindow(QWidget *parent, Qt::WindowFlags flags)
, m_historyForward(0)
, m_stop(0)
, m_reload(0)
-#ifndef QT_NO_PRINTER
, m_currentPrinter(nullptr)
-#endif
{
setToolButtonStyle(Qt::ToolButtonFollowStyle);
setAttribute(Qt::WA_DeleteOnClose, true);
@@ -312,9 +310,7 @@ void BrowserMainWindow::setupMenu()
#if defined(QWEBENGINEPAGE_PRINT)
fileMenu->addAction(tr("P&rint Preview..."), this, SLOT(slotFilePrintPreview()));
#endif
-#ifndef QT_NO_PRINTER
fileMenu->addAction(tr("&Print..."), this, SLOT(slotFilePrint()), QKeySequence::Print);
-#endif
fileMenu->addAction(tr("&Print to PDF..."), this, SLOT(slotFilePrintToPDF()));
fileMenu->addSeparator();
@@ -702,23 +698,19 @@ void BrowserMainWindow::slotFileOpen()
void BrowserMainWindow::slotFilePrintPreview()
{
-#ifndef QT_NO_PRINTPREVIEWDIALOG
if (!currentTab())
return;
QPrintPreviewDialog *dialog = new QPrintPreviewDialog(this);
connect(dialog, SIGNAL(paintRequested(QPrinter*)),
currentTab(), SLOT(print(QPrinter*)));
dialog->exec();
-#endif
}
void BrowserMainWindow::slotFilePrint()
{
-#ifndef QT_NO_PRINTER
if (!currentTab())
return;
printRequested(currentTab()->page());
-#endif
}
void BrowserMainWindow::slotHandlePdfPrinted(const QByteArray& result)
@@ -751,7 +743,6 @@ void BrowserMainWindow::slotFilePrintToPDF()
currentTab()->page()->printToPdf(invoke(this, &BrowserMainWindow::slotHandlePdfPrinted), dialog->pageLayout());
}
-#ifndef QT_NO_PRINTER
void BrowserMainWindow::slotHandlePagePrinted(bool result)
{
Q_UNUSED(result);
@@ -763,7 +754,6 @@ void BrowserMainWindow::slotHandlePagePrinted(bool result)
void BrowserMainWindow::printRequested(QWebEnginePage *page)
{
-#ifndef QT_NO_PRINTDIALOG
if (m_currentPrinter)
return;
m_currentPrinter = new QPrinter();
@@ -774,9 +764,7 @@ void BrowserMainWindow::printRequested(QWebEnginePage *page)
return;
}
page->print(m_currentPrinter, invoke(this, &BrowserMainWindow::slotHandlePagePrinted));
-#endif
}
-#endif
void BrowserMainWindow::slotPrivateBrowsing()
{
diff --git a/examples/webenginewidgets/demobrowser/browsermainwindow.h b/examples/webenginewidgets/demobrowser/browsermainwindow.h
index 91e1c1d2f..5bbbb2924 100644
--- a/examples/webenginewidgets/demobrowser/browsermainwindow.h
+++ b/examples/webenginewidgets/demobrowser/browsermainwindow.h
@@ -56,9 +56,7 @@
#include <QtCore/QUrl>
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_PRINTER
class QPrinter;
-#endif
class QWebEnginePage;
QT_END_NAMESPACE
@@ -142,10 +140,8 @@ private slots:
void slotSwapFocus();
void slotHandlePdfPrinted(const QByteArray&);
-#ifndef QT_NO_PRINTER
void slotHandlePagePrinted(bool result);
void printRequested(QWebEnginePage *page);
-#endif
void geometryChangeRequested(const QRect &geometry);
void updateToolbarActionText(bool visible);
void updateBookmarksToolbarActionText(bool visible);
@@ -180,9 +176,7 @@ private:
QAction *m_restoreLastSession;
QAction *m_addBookmark;
-#ifndef QT_NO_PRINTER
QPrinter *m_currentPrinter;
-#endif
QIcon m_reloadIcon;
QIcon m_stopIcon;
diff --git a/examples/webenginewidgets/demobrowser/printtopdfdialog.cpp b/examples/webenginewidgets/demobrowser/printtopdfdialog.cpp
index 0f3b1765e..50a8bb91a 100644
--- a/examples/webenginewidgets/demobrowser/printtopdfdialog.cpp
+++ b/examples/webenginewidgets/demobrowser/printtopdfdialog.cpp
@@ -52,10 +52,8 @@
#include "ui_printtopdfdialog.h"
#include <QtCore/QDir>
-#ifndef QT_NO_PRINTER
#include <QtPrintSupport/QPageSetupDialog>
#include <QtPrintSupport/QPrinter>
-#endif // QT_NO_PRINTER
#include <QtWidgets/QFileDialog>
PrintToPdfDialog::PrintToPdfDialog(const QString &filePath, QWidget *parent) :
@@ -66,11 +64,8 @@ PrintToPdfDialog::PrintToPdfDialog(const QString &filePath, QWidget *parent) :
ui->setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
connect(ui->chooseFilePathButton, &QToolButton::clicked, this, &PrintToPdfDialog::onChooseFilePathButtonClicked);
-#ifndef QT_NO_PRINTER
connect(ui->choosePageLayoutButton, &QToolButton::clicked, this, &PrintToPdfDialog::onChoosePageLayoutButtonClicked);
-#else
ui->choosePageLayoutButton->hide();
-#endif // QT_NO_PRINTER
updatePageLayoutLabel();
setFilePath(filePath);
}
@@ -82,7 +77,6 @@ PrintToPdfDialog::~PrintToPdfDialog()
void PrintToPdfDialog::onChoosePageLayoutButtonClicked()
{
-#ifndef QT_NO_PRINTER
QPrinter printer;
printer.setPageLayout(currentPageLayout);
@@ -92,7 +86,6 @@ void PrintToPdfDialog::onChoosePageLayoutButtonClicked()
currentPageLayout.setPageSize(printer.pageLayout().pageSize());
currentPageLayout.setOrientation(printer.pageLayout().orientation());
updatePageLayoutLabel();
-#endif // QT_NO_PRINTER
}
void PrintToPdfDialog::onChooseFilePathButtonClicked()
diff --git a/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc b/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
index 0239c1065..a20dc04c5 100644
--- a/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
+++ b/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
@@ -139,7 +139,7 @@
\printto defaultTextFile
- The menu items are connected to the mapping member slots. The
+ The menu items are connected to the corresponding member slots. The
\uicontrol Save item is activated or deactivated depending on whether
the user has edited the content.
diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf
index c1e919603..f7a38ac12 100644
--- a/mkspecs/features/configure.prf
+++ b/mkspecs/features/configure.prf
@@ -133,10 +133,6 @@ defineTest(runConfigure) {
cache(WEBENGINE_CONFIG, add, $$list($$WEBENGINE_CONFIG))
export(WEBENGINE_CONFIG)
}
- # Set a global WEBENGINE_ARCH for the target architecture we can also read from option(host_build)
- WEBENGINE_ARCH = $$QT_ARCH
- cache(WEBENGINE_ARCH)
- export(WEBENGINE_ARCH)
}
unix:!darwin {
diff --git a/mkspecs/features/functions.prf b/mkspecs/features/functions.prf
index 8dd21f410..56894e58a 100644
--- a/mkspecs/features/functions.prf
+++ b/mkspecs/features/functions.prf
@@ -16,7 +16,7 @@ defineTest(isQtMinimum) {
defineTest(isPlatformSupported) {
QT_FOR_CONFIG += gui-private
linux {
- !gcc:!clang {
+ if(!gcc:!clang)|intel_icc {
skipBuild("Qt WebEngine on Linux requires clang or GCC.")
return(false)
}
@@ -29,6 +29,10 @@ defineTest(isPlatformSupported) {
isBuildingOnWin32() {
skipBuild("Qt WebEngine on Windows must be built on a 64-bit machine.")
}
+ !msvc|intel_icl {
+ skipBuild("Qt WebEngine on Windows requires MSVC.")
+ return(false)
+ }
!isMinWinSDKVersion(10, 10586): {
skipBuild("Qt WebEngine on Windows requires a Windows SDK version 10.0.10586 or newer.")
return(false)
@@ -38,6 +42,10 @@ defineTest(isPlatformSupported) {
skipBuild("Using XCode version $$QMAKE_XCODE_VERSION, but at least version 5.1 is required to build Qt WebEngine.")
return(false)
}
+ !clang|intel_icc {
+ skipBuild("Qt WebEngine on macOS requires Clang.")
+ return(false)
+ }
# We require OS X 10.0 (darwin version 14.0.0) or newer
darwin_major_version = $$section(QMAKE_HOST.version, ., 0, 0)
lessThan(darwin_major_version, 14) {
diff --git a/mkspecs/features/gn_generator.prf b/mkspecs/features/gn_generator.prf
index 1f730acd0..b2b749154 100644
--- a/mkspecs/features/gn_generator.prf
+++ b/mkspecs/features/gn_generator.prf
@@ -186,8 +186,7 @@ for (flag, QMAKE_LFLAGS): GN_CONTENTS += " \"$$filter_flag_values($$flag)\","
for (flag, GN_FLAGS): GN_CONTENTS += " \"$$flag\","
!isEmpty(QMAKE_RPATHDIR) {
for (rpath, QMAKE_RPATHDIR) {
- macos: GN_CONTENTS += " \"-Wl,-rpath,$${rpath}\","
- else:unix: GN_CONTENTS += " \"-Wl,-rpath=$${rpath}\","
+ unix:!macos: GN_CONTENTS += " \"-Wl,-rpath=$${rpath}\","
}
}
!isEmpty(QMAKE_RPATHLINKDIR): GN_CONTENTS += " \"-Wl,-rpath-link=$${QMAKE_RPATHLINKDIR}\","
diff --git a/src/3rdparty b/src/3rdparty
-Subproject 4a23e0462a610f421d22fba38b0f9ba72120ae1
+Subproject 0e828760a46a39f26c7d9fd86654c363f4218be
diff --git a/src/buildtools/configure_host.pro b/src/buildtools/configure_host.pro
index fd27643ec..f1b3d47b0 100644
--- a/src/buildtools/configure_host.pro
+++ b/src/buildtools/configure_host.pro
@@ -4,8 +4,9 @@ TEMPLATE = aux
# Pick up the host toolchain
option(host_build)
-GN_HOST_CPU = $$gnArch($$QMAKE_HOST.arch)
-GN_TARGET_CPU = $$gnArch($$WEBENGINE_ARCH)
+GN_HOST_CPU = $$gnArch($$QT_ARCH)
+!isEmpty(QT_TARGET_ARCH): GN_TARGET_CPU = $$gnArch($$QT_TARGET_ARCH)
+else: GN_TARGET_CPU = $$GN_HOST_CPU
GN_OS = $$gnOS()
clang: GN_CLANG = true
@@ -15,11 +16,11 @@ use_gold_linker: GN_USE_GOLD=true
else: GN_USE_GOLD=false
GN_V8_HOST_CPU = $$GN_HOST_CPU
-contains(GN_TARGET_CPU, "arm")|contains(GN_TARGET_CPU, "mips")|contains(GN_TARGET_CPU, "x86") {
+contains(GN_TARGET_CPU, "arm")|contains(GN_TARGET_CPU, "mipsel")|contains(GN_TARGET_CPU, "x86") {
# The v8 snapshot need a host that matches bitwidth, so we build makesnapshot to 32-bit variants of host.
contains(GN_V8_HOST_CPU, x64): GN_V8_HOST_CPU = "x86"
else: contains(GN_V8_HOST_CPU, arm64): GN_V8_HOST_CPU = "arm"
- else: contains(GN_V8_HOST_CPU, mips64): GN_V8_HOST_CPU = "mips"
+ else: contains(GN_V8_HOST_CPU, mips64el): GN_V8_HOST_CPU = "mipsel"
}
# We always use the gcc_toolchain, because clang_toolchain is just
diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro
index 22c165e2a..d3d47e03a 100644
--- a/src/core/api/core_api.pro
+++ b/src/core/api/core_api.pro
@@ -53,11 +53,3 @@ SOURCES = \
unix:!isEmpty(QMAKE_LFLAGS_VERSION_SCRIPT):!static {
SOURCES += qtbug-60565.cpp
}
-
-msvc {
- # Create a list of object files that can be used as response file for the linker.
- # This is done to simulate -whole-archive on MSVC.
- QMAKE_POST_LINK = \
- "if exist $(DESTDIR_TARGET).objects del $(DESTDIR_TARGET).objects$$escape_expand(\\n\\t)" \
- "for %%a in ($(OBJECTS)) do echo $$shell_quote($$shell_path($$OUT_PWD))\\%%a >> $(DESTDIR_TARGET).objects"
-}
diff --git a/src/core/api/qtbug-60565.cpp b/src/core/api/qtbug-60565.cpp
index 21b545cca..be601b7e4 100644
--- a/src/core/api/qtbug-60565.cpp
+++ b/src/core/api/qtbug-60565.cpp
@@ -47,6 +47,7 @@
#endif
#define SHIM_ALIAS_SYMBOL(fn) __attribute__((weak, alias(#fn)))
+#define SHIM_HIDDEN __attribute__ ((visibility ("hidden")))
extern "C" {
@@ -87,19 +88,19 @@ static void* __shimCppNewArray(size_t size);
static void __shimCppDelete(void *address);
static void __shimCppDeleteArray(void *address);
-static void* ShimCppNew(size_t size) {
+SHIM_HIDDEN void* ShimCppNew(size_t size) {
return __shimCppNew(size);
}
-static void* ShimCppNewArray(size_t size) {
+SHIM_HIDDEN void* ShimCppNewArray(size_t size) {
return __shimCppNewArray(size);
}
-static void ShimCppDelete(void* address) {
+SHIM_HIDDEN void ShimCppDelete(void* address) {
__shimCppDelete(address);
}
-static void ShimCppDeleteArray(void* address) {
+SHIM_HIDDEN void ShimCppDeleteArray(void* address) {
__shimCppDeleteArray(address);
}
} // extern "C"
diff --git a/src/core/browser_context_qt.cpp b/src/core/browser_context_qt.cpp
index 133006d70..ffee001ff 100644
--- a/src/core/browser_context_qt.cpp
+++ b/src/core/browser_context_qt.cpp
@@ -63,8 +63,9 @@
#include "components/prefs/pref_registry_simple.h"
#include "components/user_prefs/user_prefs.h"
#if BUILDFLAG(ENABLE_SPELLCHECK)
-#include "chrome/common/pref_names.h"
#include "chrome/browser/spellchecker/spellcheck_service.h"
+#include "chrome/common/pref_names.h"
+#include "components/spellcheck/browser/pref_names.h"
#endif
namespace QtWebEngineCore {
@@ -80,12 +81,11 @@ BrowserContextQt::BrowserContextQt(BrowserContextAdapter *adapter)
#if BUILDFLAG(ENABLE_SPELLCHECK)
// Initial spellcheck settings
- registry->RegisterListPref(prefs::kSpellCheckDictionaries, new base::ListValue());
registry->RegisterStringPref(prefs::kAcceptLanguages, std::string());
- registry->RegisterStringPref(prefs::kSpellCheckDictionary, std::string());
- registry->RegisterBooleanPref(prefs::kSpellCheckUseSpellingService, false);
- registry->RegisterBooleanPref(prefs::kEnableContinuousSpellcheck, false);
- registry->RegisterBooleanPref(prefs::kEnableAutoSpellCorrect, false);
+ registry->RegisterListPref(spellcheck::prefs::kSpellCheckDictionaries, new base::ListValue());
+ registry->RegisterStringPref(spellcheck::prefs::kSpellCheckDictionary, std::string());
+ registry->RegisterBooleanPref(spellcheck::prefs::kEnableSpellcheck, false);
+ registry->RegisterBooleanPref(spellcheck::prefs::kSpellCheckUseSpellingService, false);
#endif //ENABLE_SPELLCHECK
m_prefService = factory.Create(std::move(registry.get()));
user_prefs::UserPrefs::Set(this, m_prefService.get());
@@ -216,7 +216,7 @@ void BrowserContextQt::failedToLoadDictionary(const std::string &language)
void BrowserContextQt::setSpellCheckLanguages(const QStringList &languages)
{
StringListPrefMember dictionaries_pref;
- dictionaries_pref.Init(prefs::kSpellCheckDictionaries, m_prefService.get());
+ dictionaries_pref.Init(spellcheck::prefs::kSpellCheckDictionaries, m_prefService.get());
std::vector<std::string> dictionaries;
dictionaries.reserve(languages.size());
for (const auto &language : languages)
@@ -227,7 +227,7 @@ void BrowserContextQt::setSpellCheckLanguages(const QStringList &languages)
QStringList BrowserContextQt::spellCheckLanguages() const
{
QStringList spellcheck_dictionaries;
- for (const auto &value : *m_prefService->GetList(prefs::kSpellCheckDictionaries)) {
+ for (const auto &value : *m_prefService->GetList(spellcheck::prefs::kSpellCheckDictionaries)) {
std::string dictionary;
if (value->GetAsString(&dictionary))
spellcheck_dictionaries.append(QString::fromStdString(dictionary));
@@ -238,12 +238,12 @@ QStringList BrowserContextQt::spellCheckLanguages() const
void BrowserContextQt::setSpellCheckEnabled(bool enabled)
{
- m_prefService->SetBoolean(prefs::kEnableContinuousSpellcheck, enabled);
+ m_prefService->SetBoolean(spellcheck::prefs::kEnableSpellcheck, enabled);
}
bool BrowserContextQt::isSpellCheckEnabled() const
{
- return m_prefService->GetBoolean(prefs::kEnableContinuousSpellcheck);
+ return m_prefService->GetBoolean(spellcheck::prefs::kEnableSpellcheck);
}
#endif //ENABLE_SPELLCHECK
} // namespace QtWebEngineCore
diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri
index 24951cd07..60cfa6857 100644
--- a/src/core/config/linux.pri
+++ b/src/core/config/linux.pri
@@ -98,17 +98,18 @@ contains(QT_ARCH, "mips"):!host_build {
host_build {
gn_args += custom_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:host\"
+ GN_HOST_CPU = $$gnArch($$QT_ARCH)
+ gn_args += host_cpu=\"$$GN_HOST_CPU\"
# Don't bother trying to use system libraries in this case
gn_args += use_glib=false
gn_args += use_system_libffi=false
} else {
gn_args += custom_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:target\"
+ gn_args += host_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:host\"
cross_compile {
- gn_args += host_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:host\"
gn_args += v8_snapshot_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:v8_snapshot\"
- GN_HOST_CPU = $$gnArch($$QMAKE_HOST.arch)
GN_TARGET_CPU = $$gnArch($$QT_ARCH)
- gn_args += host_cpu=\"$$GN_HOST_CPU\" target_cpu=\"$$GN_TARGET_CPU\"
+ gn_args += target_cpu=\"$$GN_TARGET_CPU\"
}
!contains(QT_CONFIG, no-pkg-config) {
# Strip '>2 /dev/null' from $$pkgConfigExecutable()
diff --git a/src/core/config/windows.pri b/src/core/config/windows.pri
index 49c725475..f5dd4a9d3 100644
--- a/src/core/config/windows.pri
+++ b/src/core/config/windows.pri
@@ -36,10 +36,8 @@ defineTest(usingMSVC32BitCrossCompiler) {
msvc:contains(QT_ARCH, "i386"):!usingMSVC32BitCrossCompiler() {
# The 32 bit MSVC linker runs out of memory if we do not remove all debug information.
- gn_args += symbol_level=0
-} else {
- # Chromium builds with debug info in release by default but Qt doesn't
- CONFIG(release, debug|release):!force_debug_info: gn_args += symbol_level=1
+ force_debug_info: gn_args -= symbol_level=1
+ gn_args *= symbol_level=0
}
msvc {
@@ -55,10 +53,11 @@ msvc {
SDK_PATH = $$(WINDOWSSDKDIR)
VS_PATH= $$(VSINSTALLDIR)
- gn_args += visual_studio_path=$$shell_quote($$VS_PATH)
- gn_args += windows_sdk_path=$$shell_quote($$SDK_PATH)
+ gn_args += visual_studio_path=\"$$clean_path($$VS_PATH)\"
+ gn_args += windows_sdk_path=\"$$clean_path($$SDK_PATH)\"
- contains(QT_ARCH, "i386"): gn_args += target_cpu=\"x86\"
+ GN_TARGET_CPU = $$gnArch($$QT_ARCH)
+ gn_args += target_cpu=\"$$GN_TARGET_CPU\"
} else {
fatal("Qt WebEngine for Windows can only be built with the Microsoft Visual Studio C++ compiler")
diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp
index 38f66d641..8284029a0 100644
--- a/src/core/content_main_delegate_qt.cpp
+++ b/src/core/content_main_delegate_qt.cpp
@@ -139,10 +139,15 @@ content::ContentRendererClient *ContentMainDelegateQt::CreateContentRendererClie
{
#if defined(OS_LINUX)
base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess();
-
- if (parsedCommandLine->HasSwitch(switches::kLang)) {
- const std::string &locale = parsedCommandLine->GetSwitchValueASCII(switches::kLang);
- ui::ResourceBundle::GetSharedInstance().ReloadLocaleResources(locale);
+ std::string process_type = parsedCommandLine->GetSwitchValueASCII(switches::kProcessType);
+ bool no_sandbox = parsedCommandLine->HasSwitch(switches::kNoSandbox);
+
+ // Reload locale if the renderer process is sandboxed
+ if (process_type == switches::kRendererProcess && !no_sandbox) {
+ if (parsedCommandLine->HasSwitch(switches::kLang)) {
+ const std::string &locale = parsedCommandLine->GetSwitchValueASCII(switches::kLang);
+ ui::ResourceBundle::GetSharedInstance().ReloadLocaleResources(locale);
+ }
}
#endif
diff --git a/src/core/core.pro b/src/core/core.pro
index 6cc8080e0..9709e62c3 100644
--- a/src/core/core.pro
+++ b/src/core/core.pro
@@ -17,23 +17,6 @@ core_generator.depends = core_headers
# core_gn_generator.pro is a dummy .pro file that is used by qmake
# to generate our main BUILD.gn file
-core_icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat
-core_icu.path = $$[QT_INSTALL_DATA]/resources
-core_icu.CONFIG += no_check_exist
-
-core_locales.files = $$OUT_PWD/$$getConfigDir()/qtwebengine_locales/*.pak
-core_locales.path = $$[QT_INSTALL_TRANSLATIONS]/qtwebengine_locales
-core_locales.CONFIG += no_check_exist
-
-core_resources.files = \
- $$OUT_PWD/$$getConfigDir()/qtwebengine_resources.pak \
- $$OUT_PWD/$$getConfigDir()/qtwebengine_resources_100p.pak \
- $$OUT_PWD/$$getConfigDir()/qtwebengine_resources_200p.pak \
- $$OUT_PWD/$$getConfigDir()/qtwebengine_devtools_resources.pak
-core_resources.path = $$[QT_INSTALL_DATA]/resources
-core_resources.CONFIG += no_check_exist
-INSTALLS += core_resources core_locales core_icu
-
gn_run.file = gn_run.pro
gn_run.depends = core_generator
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index 44e8ac613..3785ddc46 100644
--- a/src/core/core_module.pro
+++ b/src/core/core_module.pro
@@ -47,10 +47,8 @@ CONFIG *= no_smart_library_merge
osx {
LIBS_PRIVATE += -Wl,-force_load,$${api_library_path}$${QMAKE_DIR_SEP}lib$${api_library_name}.a
} else:msvc {
- # Simulate -whole-archive by passing the list of object files that belong to the public
- # API library as response file to the linker.
QMAKE_LFLAGS += /OPT:REF
- QMAKE_LFLAGS += @$${api_library_path}$${QMAKE_DIR_SEP}$${api_library_name}.lib.objects
+ QMAKE_LFLAGS += /WHOLEARCHIVE:$${api_library_path}$${QMAKE_DIR_SEP}$${api_library_name}.lib
} else {
LIBS_PRIVATE += -Wl,-whole-archive -l$$api_library_name -Wl,-no-whole-archive
}
diff --git a/src/core/media_capture_devices_dispatcher.cpp b/src/core/media_capture_devices_dispatcher.cpp
index b3c42aa08..8bdbaadd2 100644
--- a/src/core/media_capture_devices_dispatcher.cpp
+++ b/src/core/media_capture_devices_dispatcher.cpp
@@ -62,8 +62,14 @@
#include "content/public/common/media_stream_request.h"
#include "media/audio/audio_device_description.h"
#include "media/audio/audio_manager_base.h"
+#include "media/media_features.h"
#include "ui/base/l10n/l10n_util.h"
+#if BUILDFLAG(ENABLE_WEBRTC)
+#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
+#endif
+
#include <QtCore/qcoreapplication.h>
namespace QtWebEngineCore {
@@ -330,10 +336,38 @@ void MediaCaptureDevicesDispatcher::handleScreenCaptureAccessRequest(content::We
{
content::MediaStreamDevices devices;
std::unique_ptr<content::MediaStreamUI> ui;
+#if BUILDFLAG(ENABLE_WEBRTC)
if (userAccepted) {
- content::DesktopMediaID screenId = content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0);
+ // Source id patterns are different across platforms.
+ // On Linux, the hardcoded value "0" is used.
+ // On Windows, the screens are enumerated consecutively in increasing order from 0.
+ // On macOS the source ids are randomish numbers assigned by the OS.
+ webrtc::DesktopCapturer::SourceId id = 0;
+
+ // In order to provide a correct screen id, we query for the available screen ids, and
+ // select the first one as the main display id.
+ // The code is based on the file
+ // src/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc.
+ webrtc::DesktopCaptureOptions options =
+ webrtc::DesktopCaptureOptions::CreateDefault();
+ options.set_disable_effects(false);
+ std::unique_ptr<webrtc::DesktopCapturer> screen_capturer(
+ webrtc::DesktopCapturer::CreateScreenCapturer(options));
+
+ if (screen_capturer) {
+ webrtc::DesktopCapturer::SourceList screens;
+ if (screen_capturer->GetSourceList(&screens)) {
+ if (screens.size() > 0) {
+ id = screens[0].id;
+ }
+ }
+ }
+
+ content::DesktopMediaID screenId = content::DesktopMediaID(
+ content::DesktopMediaID::TYPE_SCREEN, id);
ui = getDevicesForDesktopCapture(&devices, screenId, false/*capture_audio*/, false/*display_notification*/, getContentsUrl(webContents));
}
+#endif
std::map<content::WebContents*, RequestsQueue>::iterator it =
m_pendingRequests.find(webContents);
if (it == m_pendingRequests.end()) {
diff --git a/src/core/qtwebengine.gni b/src/core/qtwebengine.gni
index de1fa1836..c9f766a36 100644
--- a/src/core/qtwebengine.gni
+++ b/src/core/qtwebengine.gni
@@ -1,3 +1,4 @@
+import("//media/media_options.gni")
import("//third_party/widevine/cdm/widevine.gni")
chromium_version = exec_script("//build/util/version.py", [ "-f", rebase_path("//chrome/VERSION"),
@@ -18,10 +19,12 @@ deps = [
"//components/visitedlink/renderer",
"//components/web_cache/browser",
"//components/web_cache/renderer",
+ "//components/spellcheck:build_features",
"//content/public/app:browser",
"//content/public/browser",
"//content/public/common",
"//content/public/renderer",
+ "//media:media_features",
"//net:net_browser_services",
"//net:net_with_v8",
"//skia",
@@ -36,6 +39,10 @@ if (enable_widevine) {
deps += [ "//components/cdm/renderer"]
}
+if (enable_webrtc) {
+ deps += [ "//third_party/webrtc/base:base" ]
+}
+
if (is_linux && !is_desktop_linux) {
deps += [ "//ui/events/ozone:events_ozone_evdev"]
}
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 3d51d4108..4e98a1016 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -942,10 +942,17 @@ QVariant RenderWidgetHostViewQt::inputMethodQuery(Qt::InputMethodQuery query)
case Qt::ImFont:
// TODO: Implement this
return QVariant();
- case Qt::ImCursorRectangle:
- if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
- return QVariant();
- return toQt(text_input_manager_->GetSelectionRegion()->caret_rect);
+ case Qt::ImCursorRectangle: {
+ if (text_input_manager_) {
+ if (auto *region = text_input_manager_->GetSelectionRegion()) {
+ gfx::Rect caretRect = gfx::RectBetweenSelectionBounds(region->anchor, region->focus);
+ if (caretRect.width() == 0)
+ caretRect.set_width(1); // IME API on Windows expects a width > 0
+ return toQt(caretRect);
+ }
+ }
+ return QVariant();
+ }
case Qt::ImCursorPosition:
return m_cursorPosition;
case Qt::ImAnchorPosition:
@@ -1253,7 +1260,6 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev)
// to the same focused object, and cancelling the composition on the next event loop tick.
if (!m_receivedEmptyImeText && m_imeInProgress && !hasSelection) {
m_receivedEmptyImeText = true;
- m_imeInProgress = false;
QInputMethodEvent *eventCopy = new QInputMethodEvent(*ev);
QGuiApplication::postEvent(qApp->focusObject(), eventCopy);
} else {
diff --git a/src/core/resource_bundle_qt.cpp b/src/core/resource_bundle_qt.cpp
index 52355e996..c37854ea6 100644
--- a/src/core/resource_bundle_qt.cpp
+++ b/src/core/resource_bundle_qt.cpp
@@ -75,7 +75,8 @@ bool ResourceBundle::LocaleDataPakExists(const std::string& locale)
#if defined(OS_LINUX)
base::CommandLine *parsed_command_line = base::CommandLine::ForCurrentProcess();
std::string process_type = parsed_command_line->GetSwitchValueASCII(switches::kProcessType);
- if (process_type == switches::kRendererProcess) {
+ bool no_sandbox = parsed_command_line->HasSwitch(switches::kNoSandbox);
+ if (process_type == switches::kRendererProcess && !no_sandbox) {
// The Renderer Process is sandboxed thus only one locale is available in it.
// The particular one is passed by the --lang command line option.
if (!parsed_command_line->HasSwitch(switches::kLang) || parsed_command_line->GetSwitchValueASCII(switches::kLang) != locale)
diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp
index 9fc8add01..fe1758655 100644
--- a/src/core/url_request_context_getter_qt.cpp
+++ b/src/core/url_request_context_getter_qt.cpp
@@ -340,8 +340,7 @@ void URLRequestContextGetterQt::generateCookieStore()
cookieMonster->SetCookieableSchemes(cookieableSchemes);
m_cookieDelegate->setCookieMonster(cookieMonster);
- if (!m_updateAllStorage) {
- Q_ASSERT(m_updateHttpCache);
+ if (!m_updateAllStorage && m_updateHttpCache) {
// HttpCache needs to be regenerated when we generate a new channel id service
generateHttpCache();
}
@@ -469,6 +468,9 @@ void URLRequestContextGetterQt::generateHttpCache()
QMutexLocker lock(&m_mutex);
m_updateHttpCache = false;
+ if (m_updateCookieStore)
+ generateCookieStore();
+
net::HttpCache::DefaultBackend* main_backend = 0;
switch (m_httpCacheType) {
case BrowserContextAdapter::MemoryHttpCache:
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 270096553..399c036a4 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -402,6 +402,7 @@ void WebContentsAdapter::initialize(WebContentsAdapterClient *adapterClient)
// We keep a reference to browserContextAdapter to keep it alive as long as we use it.
// This is needed in case the QML WebEngineProfile is garbage collected before the WebEnginePage.
d->browserContextAdapter = adapterClient->browserContextAdapter();
+ Q_ASSERT(d->browserContextAdapter);
// Create our own if a WebContents wasn't provided at construction.
if (!d->webContents)
@@ -1228,7 +1229,7 @@ static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeDat
return;
if (mimeData->hasHtml())
dropData->html = toNullableString16(mimeData->html());
- else if (mimeData->hasText())
+ if (mimeData->hasText())
dropData->text = toNullableString16(mimeData->text());
}
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index ee7dbe1ce..8d75f24b7 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -339,7 +339,7 @@ public:
virtual void loadFinished(bool success, const QUrl &url, bool isErrorPage = false, int errorCode = 0, const QString &errorDescription = QString()) = 0;
virtual void focusContainer() = 0;
virtual void unhandledKeyEvent(QKeyEvent *event) = 0;
- virtual void adoptNewWindow(QSharedPointer<WebContentsAdapter> newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect & initialGeometry) = 0;
+ virtual void adoptNewWindow(QSharedPointer<WebContentsAdapter> newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect & initialGeometry, const QUrl &targetUrl) = 0;
virtual bool isBeingAdopted() = 0;
virtual void close() = 0;
virtual void windowCloseRejected() = 0;
@@ -359,9 +359,7 @@ public:
virtual void passOnFocus(bool reverse) = 0;
// returns the last QObject (QWidget/QQuickItem) based object in the accessibility
// hierarchy before going into the BrowserAccessibility tree
-#ifndef QT_NO_ACCESSIBILITY
virtual QObject *accessibilityParentObject() = 0;
-#endif // QT_NO_ACCESSIBILITY
virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) = 0;
virtual void authenticationRequired(QSharedPointer<AuthenticationDialogController>) = 0;
virtual void runGeolocationPermissionRequest(const QUrl &securityOrigin) = 0;
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 5bcb83c6b..a6e1fb438 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -306,6 +306,11 @@ void WebContentsDelegateQt::DidUpdateFaviconURL(const std::vector<content::Favic
m_faviconManager->update(faviconCandidates);
}
+void WebContentsDelegateQt::WebContentsCreated(content::WebContents* /*source_contents*/, int /*opener_render_process_id*/, int /*opener_render_frame_id*/, const std::string& /*frame_name*/, const GURL& target_url, content::WebContents* new_contents)
+{
+ this->m_initialTargetUrl = toQt(target_url);
+}
+
content::ColorChooser *WebContentsDelegateQt::OpenColorChooser(content::WebContents *source, SkColor color, const std::vector<content::ColorSuggestion> &suggestion)
{
Q_UNUSED(suggestion);
@@ -445,7 +450,7 @@ QWeakPointer<WebContentsAdapter> WebContentsDelegateQt::createWindow(content::We
{
QSharedPointer<WebContentsAdapter> newAdapter = QSharedPointer<WebContentsAdapter>::create(new_contents);
- m_viewClient->adoptNewWindow(newAdapter, static_cast<WebContentsAdapterClient::WindowOpenDisposition>(disposition), user_gesture, toQt(initial_pos));
+ m_viewClient->adoptNewWindow(newAdapter, static_cast<WebContentsAdapterClient::WindowOpenDisposition>(disposition), user_gesture, toQt(initial_pos), m_initialTargetUrl);
// If the client didn't reference the adapter, it will be deleted now, and the weak pointer zeroed.
return newAdapter;
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 5ae442bbc..84799c2cd 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -104,6 +104,7 @@ public:
void LoadProgressChanged(content::WebContents* source, double progress) override;
void HandleKeyboardEvent(content::WebContents *source, const content::NativeWebKeyboardEvent &event) override;
content::ColorChooser *OpenColorChooser(content::WebContents *source, SkColor color, const std::vector<content::ColorSuggestion> &suggestion) override;
+ void WebContentsCreated(content::WebContents* source_contents, int opener_render_process_id, int opener_render_frame_id, const std::string& frame_name, const GURL& target_url, content::WebContents* new_contents) override;
content::JavaScriptDialogManager *GetJavaScriptDialogManager(content::WebContents *source) override;
void EnterFullscreenModeForTab(content::WebContents* web_contents, const GURL& origin) override;
void ExitFullscreenModeForTab(content::WebContents*) override;
@@ -156,6 +157,7 @@ private:
QScopedPointer<FaviconManager> m_faviconManager;
SavePageInfo m_savePageInfo;
QSharedPointer<FilePickerController> m_filePickerController;
+ QUrl m_initialTargetUrl;
};
} // namespace QtWebEngineCore
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index bf3ea955c..1fceb4366 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -591,7 +591,7 @@ void QQuickWebEngineViewPrivate::unhandledKeyEvent(QKeyEvent *event)
q->window()->sendEvent(q->parentItem(), event);
}
-void QQuickWebEngineViewPrivate::adoptNewWindow(QSharedPointer<WebContentsAdapter> newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &)
+void QQuickWebEngineViewPrivate::adoptNewWindow(QSharedPointer<WebContentsAdapter> newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &, const QUrl &targetUrl)
{
Q_Q(QQuickWebEngineView);
QQuickWebEngineNewViewRequest request;
@@ -599,8 +599,7 @@ void QQuickWebEngineViewPrivate::adoptNewWindow(QSharedPointer<WebContentsAdapte
// to start loading it and possibly return it to its parent page window.open().
request.m_adapter = newWebContents;
request.m_isUserInitiated = userGesture;
- if (newWebContents)
- request.m_requestedUrl = newWebContents->requestedUrl();
+ request.m_requestedUrl = targetUrl;
switch (disposition) {
case WebContentsAdapterClient::NewForegroundTabDisposition:
@@ -716,13 +715,11 @@ void QQuickWebEngineViewPrivate::runMouseLockPermissionRequest(const QUrl &secur
adapter->grantMouseLockPermission(false);
}
-#ifndef QT_NO_ACCESSIBILITY
QObject *QQuickWebEngineViewPrivate::accessibilityParentObject()
{
Q_Q(QQuickWebEngineView);
return q;
}
-#endif // QT_NO_ACCESSIBILITY
QSharedPointer<BrowserContextAdapter> QQuickWebEngineViewPrivate::browserContextAdapter()
{
@@ -1102,9 +1099,10 @@ void QQuickWebEngineViewPrivate::didFindText(quint64 requestId, int matchCount)
void QQuickWebEngineViewPrivate::didPrintPage(quint64 requestId, const QByteArray &result)
{
+ Q_Q(QQuickWebEngineView);
QJSValue callback = m_callbacks.take(requestId);
QJSValueList args;
- args.append(QJSValue(result.data()));
+ args.append(qmlEngine(q)->toScriptValue(result));
callback.call(args);
}
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index 2ecd70d78..19ecf5e1f 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -107,7 +107,7 @@ public:
virtual void loadFinished(bool success, const QUrl &url, bool isErrorPage = false, int errorCode = 0, const QString &errorDescription = QString()) Q_DECL_OVERRIDE;
virtual void focusContainer() Q_DECL_OVERRIDE;
virtual void unhandledKeyEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
- virtual void adoptNewWindow(QSharedPointer<QtWebEngineCore::WebContentsAdapter> newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &) Q_DECL_OVERRIDE;
+ virtual void adoptNewWindow(QSharedPointer<QtWebEngineCore::WebContentsAdapter> newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &, const QUrl &targetUrl) Q_DECL_OVERRIDE;
virtual bool isBeingAdopted() Q_DECL_OVERRIDE;
virtual void close() Q_DECL_OVERRIDE;
virtual void windowCloseRejected() Q_DECL_OVERRIDE;
@@ -129,9 +129,7 @@ public:
virtual void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) Q_DECL_OVERRIDE;
virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) Q_DECL_OVERRIDE;
virtual void runMouseLockPermissionRequest(const QUrl &securityOrigin) Q_DECL_OVERRIDE;
-#ifndef QT_NO_ACCESSIBILITY
virtual QObject *accessibilityParentObject() Q_DECL_OVERRIDE;
-#endif // QT_NO_ACCESSIBILITY
virtual QtWebEngineCore::WebEngineSettings *webEngineSettings() const Q_DECL_OVERRIDE;
virtual void allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController) Q_DECL_OVERRIDE;
virtual void runGeolocationPermissionRequest(QUrl const&) Q_DECL_OVERRIDE;
diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
index 2eeda6e8a..ec678672c 100644
--- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
+++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
@@ -69,7 +69,7 @@
\section2 Windows
- On Windows, Visual Studio 2015 and Windows 10 SDK are required.
+ On Windows, Visual Studio 2015 or 2017 and Windows 10 SDK are required.
\section2 Linux
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
index 86f3aaa64..a0ed00918 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
@@ -241,14 +241,8 @@ void RenderWidgetHostViewQtDelegateQuick::inputMethodStateChanged(bool editorVis
bool RenderWidgetHostViewQtDelegateQuick::event(QEvent *event)
{
- if (event->type() == QEvent::ShortcutOverride) {
- QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
- if (m_client->handleShortcutOverrideEvent(keyEvent))
- return true;
- if (editorActionForKeyEvent(keyEvent) != QQuickWebEngineView::NoWebAction)
- event->accept();
- return true;
- }
+ if (event->type() == QEvent::ShortcutOverride)
+ return m_client->handleShortcutOverrideEvent(static_cast<QKeyEvent *>(event));
if (event->type() == QEvent::NativeGesture)
return m_client->forwardEvent(event);
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index ea0117b95..d0305f81a 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -81,11 +81,9 @@
#include <QMenu>
#include <QMessageBox>
#include <QMimeData>
-#if defined(QT_PRINTSUPPORT_LIB)
-#ifndef QT_NO_PRINTER
+#ifdef ENABLE_PRINTING
#include <QPrinter>
-#endif //QT_NO_PRINTER
-#endif //QT_PRINTSUPPORT_LIB
+#endif
#include <QStandardPaths>
#include <QStyle>
#include <QTimer>
@@ -403,10 +401,11 @@ void QWebEnginePagePrivate::unhandledKeyEvent(QKeyEvent *event)
QGuiApplication::sendEvent(view->parentWidget(), event);
}
-void QWebEnginePagePrivate::adoptNewWindow(QSharedPointer<WebContentsAdapter> newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &initialGeometry)
+void QWebEnginePagePrivate::adoptNewWindow(QSharedPointer<WebContentsAdapter> newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &initialGeometry, const QUrl &targetUrl)
{
Q_Q(QWebEnginePage);
Q_UNUSED(userGesture);
+ Q_UNUSED(targetUrl);
QWebEnginePage *newPage = q->createWindow(toWindowType(disposition));
if (!newPage)
@@ -585,12 +584,10 @@ void QWebEnginePagePrivate::runMouseLockPermissionRequest(const QUrl &securityOr
Q_EMIT q->featurePermissionRequested(securityOrigin, QWebEnginePage::MouseLock);
}
-#ifndef QT_NO_ACCESSIBILITY
QObject *QWebEnginePagePrivate::accessibilityParentObject()
{
return view;
}
-#endif // QT_NO_ACCESSIBILITY
void QWebEnginePagePrivate::updateAction(QWebEnginePage::WebAction action) const
{
@@ -1969,7 +1966,7 @@ QStringList QWebEnginePage::chooseFiles(FileSelectionMode mode, const QStringLis
break;
// Chromium extension, not exposed as part of the public API for now.
case FilePickerController::UploadFolder:
- str = QFileDialog::getExistingDirectory(view(), tr("Select folder to upload")) + QLatin1Char('/');
+ str = QFileDialog::getExistingDirectory(view(), tr("Select folder to upload"));
if (!str.isNull())
ret << str;
break;
@@ -2126,8 +2123,6 @@ void QWebEnginePage::printToPdf(const QWebEngineCallback<const QByteArray&> &res
#endif // if defined(ENABLE_PDF)
}
-#if defined(QT_PRINTSUPPORT_LIB)
-#ifndef QT_NO_PRINTER
/*!
\fn void QWebEnginePage::print(QPrinter *printer, FunctorOrLambda resultCallback)
Renders the current content of the page into a temporary PDF document, then prints it using \a printer.
@@ -2164,8 +2159,6 @@ void QWebEnginePage::print(QPrinter *printer, const QWebEngineCallback<bool> &re
d->m_callbacks.invokeDirectly(resultCallback, false);
#endif // if defined(ENABLE_PDF)
}
-#endif // if defined(QT_NO_PRINTER)
-#endif // if defined(QT_PRINTSUPPORT_LIB)
/*!
\since 5.7
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index 37a59e88c..74ebd0a35 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -55,11 +55,7 @@
QT_BEGIN_NAMESPACE
class QMenu;
-#if defined(QT_PRINTSUPPORT_LIB)
-#ifndef QT_NO_PRINTER
class QPrinter;
-#endif // QT_NO_PRINTER
-#endif // QT_PRINTSUPPORT_LIB
class QWebChannel;
class QWebEngineContextMenuData;
@@ -310,15 +306,11 @@ public:
void printToPdf(const QWebEngineCallback<const QByteArray&> &resultCallback, const QPageLayout &layout = QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF()));
#endif
-#if defined(QT_PRINTSUPPORT_LIB)
-#ifndef QT_NO_PRINTER
#ifdef Q_QDOC
void print(QPrinter *printer, FunctorOrLambda resultCallback);
#else
void print(QPrinter *printer, const QWebEngineCallback<bool> &resultCallback);
#endif // QDOC
-#endif // QT_NO_PRINTER
-#endif // QT_PRINTSUPPORT_LIB
const QWebEngineContextMenuData &contextMenuData() const;
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index c7b805c45..ec84f05e1 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -100,7 +100,7 @@ public:
virtual void loadFinished(bool success, const QUrl &url, bool isErrorPage = false, int errorCode = 0, const QString &errorDescription = QString()) Q_DECL_OVERRIDE;
virtual void focusContainer() Q_DECL_OVERRIDE;
virtual void unhandledKeyEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
- virtual void adoptNewWindow(QSharedPointer<QtWebEngineCore::WebContentsAdapter> newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &initialGeometry) Q_DECL_OVERRIDE;
+ virtual void adoptNewWindow(QSharedPointer<QtWebEngineCore::WebContentsAdapter> newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &initialGeometry, const QUrl &targetUrl) Q_DECL_OVERRIDE;
void adoptNewWindowImpl(QWebEnginePage *newPage,
const QSharedPointer<QtWebEngineCore::WebContentsAdapter> &newWebContents,
const QRect &initialGeometry);
@@ -126,9 +126,7 @@ public:
virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) Q_DECL_OVERRIDE;
virtual void runGeolocationPermissionRequest(const QUrl &securityOrigin) Q_DECL_OVERRIDE;
virtual void runMouseLockPermissionRequest(const QUrl &securityOrigin) Q_DECL_OVERRIDE;
-#ifndef QT_NO_ACCESSIBILITY
virtual QObject *accessibilityParentObject() Q_DECL_OVERRIDE;
-#endif // QT_NO_ACCESSIBILITY
virtual QtWebEngineCore::WebEngineSettings *webEngineSettings() const Q_DECL_OVERRIDE;
virtual void allowCertificateError(const QSharedPointer<CertificateErrorController> &controller) Q_DECL_OVERRIDE;
virtual void showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText) Q_DECL_OVERRIDE;
diff --git a/src/webenginewidgets/api/qwebenginesettings.cpp b/src/webenginewidgets/api/qwebenginesettings.cpp
index 4c8c4be33..6e24b4b51 100644
--- a/src/webenginewidgets/api/qwebenginesettings.cpp
+++ b/src/webenginewidgets/api/qwebenginesettings.cpp
@@ -124,9 +124,9 @@ QWebEngineSettings *QWebEngineSettings::globalSettings()
#endif
/*!
- Returns the default settings for the web engine page.
-
- \sa globalSettings()
+ Returns the settings for a web engine page that belongs to the default
+ profile. All web pages not specifically created with another profile belong
+ to the default profile.
*/
QWebEngineSettings *QWebEngineSettings::defaultSettings()
{
diff --git a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
index bc841849e..26f3964da 100644
--- a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
@@ -24,12 +24,9 @@
/*!
\fn static QWebEngineSettings *QWebEngineSettings::globalSettings()
- Returns the global settings object.
+ \obsolete
- Any setting changed on the default object is automatically applied to all
- QWebEnginePage instances where the particular setting is not overridden already.
-
- \sa defaultSettings()
+ Use defaultSettings() instead.
*/
/*!
@@ -40,16 +37,15 @@
\inmodule QtWebEngineWidgets
- Each QWebEnginePage object has its own QWebEngineSettings object, which configures the
- settings for that page. If a setting is not configured, then it is looked
- up in the global settings object, which can be accessed using
- globalSettings().
-
QWebEngineSettings allows configuration of browser properties, such as font sizes and
families, the location of a custom style sheet, and generic attributes, such as JavaScript
support. Individual attributes are set using the setAttribute() function. The
\l{QWebEngineSettings::WebAttribute}{WebAttribute} enum further describes each attribute.
+ Each QWebEnginePage object has its own QWebEngineSettings object, which configures the
+ settings for that page. If a setting is not configured for a web engine
+ page, it is looked up in the settings of the profile the page belongs to.
+
\sa QWebEnginePage::settings(), QWebEngineView::settings()
*/
@@ -184,10 +180,8 @@
/*!
\fn void QWebEngineSettings::resetFontSize(FontSize type)
- Resets the font size for \a type to the size specified in the global
- settings object.
-
- This function has no effect on the global QWebEngineSettings instance.
+ Resets the font size for \a type to the size specified in the profile that
+ the page belongs to.
*/
/*!
@@ -222,10 +216,8 @@
/*!
\fn void QWebEngineSettings::resetFontFamily(FontFamily which)
- Resets the actual font family specified by \a which to the one set
- in the global QWebEngineSettings instance.
-
- This function has no effect on the global QWebEngineSettings instance.
+ Resets the actual font family specified by \a which to the one specified
+ in the profile that the page belongs to.
*/
/*!
@@ -245,9 +237,5 @@
\fn void QWebEngineSettings::resetAttribute(WebAttribute attribute)
Resets the setting of \a attribute to the value specified in the
- global QWebEngineSettings instance.
-
- This function has no effect on the global QWebEngineSettings instance.
-
- \sa globalSettings()
+ profile that the page belongs to.
*/
diff --git a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
index 3b27ca146..e54c5d507 100644
--- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
@@ -141,6 +141,12 @@
\warning This function works only for HTML. For other MIME types (such as XHTML or SVG),
setContent() should be used instead.
+ \note Content larger than 2 MB cannot be displayed, because setHtml()
+ converts the provided HTML to percent-encoding and places \c data: in front
+ of it to create the URL that it navigates to. Thereby, the provided code
+ becomes a URL that exceeds the 2 MB limit set by Chromium. If the content is
+ too large, the loadFinished() signal is triggered with \c success=false.
+
\sa load(), setContent(), QWebEnginePage::toHtml(), QWebEnginePage::setContent()
*/
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 c608ba2aa..d02191b23 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -59,15 +59,6 @@
namespace QtWebEngineCore {
-static bool handleShortcutOverrideEvent(RenderWidgetHostViewQtDelegateClient *client, QKeyEvent *ke)
-{
- if (client->handleShortcutOverrideEvent(ke))
- return true;
- if (editorActionForKeyEvent(ke) != QWebEnginePage::NoWebAction)
- ke->accept();
- return true;
-}
-
class RenderWidgetHostViewQuickItem : public QQuickItem {
public:
RenderWidgetHostViewQuickItem(RenderWidgetHostViewQtDelegateClient *client) : m_client(client)
@@ -79,10 +70,8 @@ public:
protected:
bool event(QEvent *event) override
{
- if (event->type() == QEvent::ShortcutOverride) {
- handleShortcutOverrideEvent(m_client, static_cast<QKeyEvent *>(event));
- return true;
- }
+ if (event->type() == QEvent::ShortcutOverride)
+ return m_client->handleShortcutOverrideEvent(static_cast<QKeyEvent *>(event));
return QQuickItem::event(event);
}
void focusInEvent(QFocusEvent *event) override
@@ -454,10 +443,8 @@ bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event)
// We forward focus events later, once they have made it to the m_rootItem.
return QQuickWidget::event(event);
case QEvent::ShortcutOverride:
- if (event->type() == QEvent::ShortcutOverride) {
- handleShortcutOverrideEvent(m_client, static_cast<QKeyEvent *>(event));
+ if (m_client->handleShortcutOverrideEvent(static_cast<QKeyEvent *>(event)))
return true;
- }
break;
case QEvent::DragEnter:
case QEvent::DragLeave:
diff --git a/tests/auto/quick/qmltests/data/tst_download.qml b/tests/auto/quick/qmltests/data/tst_download.qml
index e4e93b993..019ebd9dc 100644
--- a/tests/auto/quick/qmltests/data/tst_download.qml
+++ b/tests/auto/quick/qmltests/data/tst_download.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -28,7 +28,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.5
TestWebEngineView {
id: webEngineView
@@ -40,6 +40,7 @@ TestWebEngineView {
property int receivedBytes: 0
property bool cancelDownload: false
property var downloadState: []
+ property var downloadInterruptReason: null
SignalSpy {
id: downLoadRequestedSpy
@@ -55,7 +56,9 @@ TestWebEngineView {
Connections {
id: downloadItemConnections
+ ignoreUnknownSignals: true
onStateChanged: downloadState.push(target.state)
+ onInterruptReasonChanged: downloadInterruptReason = target.interruptReason
}
WebEngineProfile {
@@ -88,6 +91,7 @@ TestWebEngineView {
cancelDownload = false
downloadItemConnections.target = null
downloadState = []
+ downloadInterruptReason = null
}
function test_downloadRequest() {
@@ -96,6 +100,7 @@ TestWebEngineView {
downLoadRequestedSpy.wait()
compare(downLoadRequestedSpy.count, 1)
compare(downloadState[0], WebEngineDownloadItem.DownloadRequested)
+ verify(!downloadInterruptReason)
}
function test_totalFileLength() {
@@ -104,6 +109,7 @@ TestWebEngineView {
downLoadRequestedSpy.wait()
compare(downLoadRequestedSpy.count, 1)
compare(totalBytes, 325)
+ verify(!downloadInterruptReason)
}
function test_downloadSucceeded() {
@@ -111,10 +117,12 @@ TestWebEngineView {
webEngineView.url = Qt.resolvedUrl("download.zip")
downLoadRequestedSpy.wait()
compare(downLoadRequestedSpy.count, 1)
- compare(downloadState[1], WebEngineDownloadItem.DownloadInProgress)
+ compare(downloadState[0], WebEngineDownloadItem.DownloadRequested)
+ tryCompare(downloadState, "1", WebEngineDownloadItem.DownloadInProgress)
downloadFinishedSpy.wait()
compare(totalBytes, receivedBytes)
tryCompare(downloadState, "2", WebEngineDownloadItem.DownloadCompleted)
+ verify(!downloadInterruptReason)
}
function test_downloadCancelled() {
@@ -124,7 +132,8 @@ TestWebEngineView {
downLoadRequestedSpy.wait()
compare(downLoadRequestedSpy.count, 1)
compare(downloadFinishedSpy.count, 1)
- compare(downloadState[1], WebEngineDownloadItem.DownloadCancelled)
+ tryCompare(downloadState, "1", WebEngineDownloadItem.DownloadCancelled)
+ tryCompare(webEngineView, "downloadInterruptReason", WebEngineDownloadItem.UserCanceled)
}
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_findText.qml b/tests/auto/quick/qmltests/data/tst_findText.qml
index 78359bfc2..8526012c9 100644
--- a/tests/auto/quick/qmltests/data/tst_findText.qml
+++ b/tests/auto/quick/qmltests/data/tst_findText.qml
@@ -61,6 +61,32 @@ TestWebEngineView {
return bodyInnerHTML;
}
+ function getListItemText(index) {
+ var listItemText;
+ runJavaScript("document.getElementById('list').getElementsByTagName('li')[" + index + "].innerText;", function(result) {
+ listItemText = result;
+ });
+ tryVerify(function() { return listItemText != undefined; });
+ return listItemText;
+ }
+
+ function appendListItem(text) {
+ var script =
+ "(function () {" +
+ " var list = document.getElementById('list');" +
+ " var item = document.createElement('li');" +
+ " item.appendChild(document.createTextNode('" + text + "'));" +
+ " list.appendChild(item);" +
+ " return list.getElementsByTagName('li').length - 1;" +
+ "})();";
+ var itemIndex;
+
+ runJavaScript(script, function(result) { itemIndex = result; });
+ tryVerify(function() { return itemIndex != undefined; });
+ // Make sure the DOM is up-to-date.
+ tryVerify(function() { return getListItemText(itemIndex).length == text.length; });
+ }
+
function test_findText() {
var findFlags = WebEngineView.FindCaseSensitively
webEngineView.url = Qt.resolvedUrl("test1.html")
@@ -157,5 +183,37 @@ TestWebEngineView {
tryCompare(webEngineView, "matchCount", 1)
verify(!findFailed)
}
+
+ function test_findTextInterruptedByLoad() {
+ var findFlags = 0;
+
+ var listItemText = '';
+ for (var i = 0; i < 100000; ++i)
+ listItemText += "bla ";
+ listItemText = listItemText.trim();
+
+ webEngineView.loadHtml(
+ "<html><body>" +
+ "<ol id='list' />" +
+ "</body></html>");
+ verify(webEngineView.waitForLoadSucceeded());
+
+ // Generating a huge list is a workaround to avoid timeout while loading the test page.
+ for (var i = 0; i < 10; ++i)
+ appendListItem(listItemText);
+ appendListItem("hello");
+
+ webEngineView.clear();
+ webEngineView.findText("hello", findFlags, webEngineView.findTextCallback);
+
+ // This should not crash.
+ webEngineView.url = "https://www.qt.io";
+ if (!webEngineView.waitForLoadSucceeded(12000))
+ skip("Couldn't load page from network, skipping test.");
+
+ // Can't be sure whether the findText succeeded before the new load.
+ // Thus don't check the find result just whether the callback was called.
+ tryVerify(function() { return webEngineView.matchCount != -1; });
+ }
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_loadProgress.qml b/tests/auto/quick/qmltests/data/tst_loadProgress.qml
index 32cd91418..bb85ed8e3 100644
--- a/tests/auto/quick/qmltests/data/tst_loadProgress.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadProgress.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -41,15 +41,31 @@ TestWebEngineView {
loadProgressArray.push(webEngineView.loadProgress)
}
+ SignalSpy {
+ id: spyProgress
+ target: webEngineView
+ signalName: "loadProgressChanged"
+ }
+
TestCase {
name: "WebEngineViewLoadProgress"
function test_loadProgress() {
compare(webEngineView.loadProgress, 0)
+ compare(spyProgress.count, 0)
loadProgressArray = []
webEngineView.url = Qt.resolvedUrl("test1.html")
+ // Wait for the first loadProgressChanged signal, which have to be non-negative
+ spyProgress.wait()
+ verify(loadProgressArray[0] >= 0)
+ verify(webEngineView.loadProgress >= 0)
+
+ // Wait for the last loadProgressChanged signal, which have to be 100%
verify(webEngineView.waitForLoadSucceeded())
+ spyProgress.wait()
+ compare(loadProgressArray[loadProgressArray.length - 1], 100)
+ compare(webEngineView.loadProgress, 100)
// Test whether the chromium emits progress numbers in ascending order
var loadProgressMin = 0
@@ -58,9 +74,6 @@ TestWebEngineView {
verify(loadProgressMin <= loadProgress)
loadProgressMin = loadProgress
}
-
- // The progress must be 100% at the end
- compare(loadProgressArray[loadProgressArray.length - 1], 100)
}
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_loadProgressSignal.qml b/tests/auto/quick/qmltests/data/tst_loadProgressSignal.qml
deleted file mode 100644
index f05bb1e3d..000000000
--- a/tests/auto/quick/qmltests/data/tst_loadProgressSignal.qml
+++ /dev/null
@@ -1,60 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.0
-import QtTest 1.0
-import QtWebEngine 1.2
-
-TestWebEngineView {
- id: webEngineView
- width: 400
- height: 300
-
- SignalSpy {
- id: spyProgress
- target: webEngineView
- signalName: "loadProgressChanged"
- }
-
- TestCase {
- name: "WebEngineViewLoadProgressSignal"
-
- function test_loadProgressSignal() {
- compare(spyProgress.count, 0)
- compare(webEngineView.loadProgress, 0)
- webEngineView.url = Qt.resolvedUrl("test1.html")
- spyProgress.wait()
- verify(webEngineView.loadProgress > -1 && webEngineView.loadProgress < 101)
- if (webEngineView.loadProgress > 0 && webEngineView.loadProgress < 100) {
- verify(webEngineView.waitForLoadSucceeded())
- spyProgress.wait()
- compare(webEngineView.loadProgress, 100)
- }
- }
- }
-}
diff --git a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
index 7a04d5f5b..4becbb620 100644
--- a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
+++ b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
@@ -28,7 +28,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.2
+import QtWebEngine 1.5
TestWebEngineView {
id: webEngineView
@@ -47,7 +47,8 @@ TestWebEngineView {
onNewViewRequested: {
newViewRequest = {
"destination": request.destination,
- "userInitiated": request.userInitiated
+ "userInitiated": request.userInitiated,
+ "requestedUrl": request.requestedUrl
};
dialog = Qt.createQmlObject(
@@ -81,6 +82,8 @@ TestWebEngineView {
}
function test_jsWindowOpen() {
+ var url = 'data:text/html,%3Chtml%3E%3Cbody%3ETest+Page%3C%2Fbody%3E%3C%2Fhtml%3E';
+
// Open an empty page in a new tab
webEngineView.loadHtml(
"<html><head><script>" +
@@ -95,28 +98,30 @@ TestWebEngineView {
verify(dialog.webEngineView.waitForLoadSucceeded());
compare(dialog.webEngineView.url, "");
+ compare(newViewRequest.requestedUrl, 'about:blank');
newViewRequestedSpy.clear();
dialog.destroy();
- // Open an empty page in a new dialog
+ // Open a page in a new dialog
webEngineView.loadHtml(
"<html><head><script>" +
- " function popup() { window.open('', '_blank', 'width=200,height=100'); }" +
+ " function popup() { window.open('" + url + "', '_blank', 'width=200,height=100'); }" +
"</script></head>" +
"<body onload='popup()'></body></html>");
verify(webEngineView.waitForLoadSucceeded());
tryCompare(newViewRequestedSpy, "count", 1);
compare(newViewRequest.destination, WebEngineView.NewViewInDialog);
+ compare(newViewRequest.requestedUrl, url);
verify(!newViewRequest.userInitiated);
verify(dialog.webEngineView.waitForLoadSucceeded());
newViewRequestedSpy.clear();
dialog.destroy();
- // Open an empty page in a new dialog by user
+ // Open a page in a new dialog by user
webEngineView.loadHtml(
"<html><head><script>" +
- " function popup() { window.open('', '_blank', 'width=200,height=100'); }" +
+ " function popup() { window.open('" + url + "', '_blank', 'width=200,height=100'); }" +
"</script></head>" +
"<body onload=\"document.getElementById('popupButton').focus();\">" +
" <button id='popupButton' onclick='popup()'>Pop Up!</button>" +
@@ -124,6 +129,7 @@ TestWebEngineView {
verify(webEngineView.waitForLoadSucceeded());
verifyElementHasFocus("popupButton");
keyPress(Qt.Key_Enter);
+ compare(newViewRequest.requestedUrl, url);
tryCompare(newViewRequestedSpy, "count", 1);
compare(newViewRequest.destination, WebEngineView.NewViewInDialog);
diff --git a/tests/auto/quick/qmltests/qmltests.pro b/tests/auto/quick/qmltests/qmltests.pro
index 3973ede14..d2c9245bd 100644
--- a/tests/auto/quick/qmltests/qmltests.pro
+++ b/tests/auto/quick/qmltests/qmltests.pro
@@ -58,7 +58,6 @@ OTHER_FILES += \
$$PWD/data/tst_loadFail.qml \
$$PWD/data/tst_loadHtml.qml \
$$PWD/data/tst_loadProgress.qml \
- $$PWD/data/tst_loadProgressSignal.qml \
$$PWD/data/tst_loadRecursionCrash.qml \
$$PWD/data/tst_loadUrl.qml \
$$PWD/data/tst_navigationHistory.qml \
diff --git a/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp b/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp
index dffd995c9..d9bbce173 100644
--- a/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp
+++ b/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp
@@ -37,8 +37,9 @@ public:
protected :
void loadPage(int nr)
{
+ loadFinishedSpy->clear();
page->load(QUrl("qrc:/resources/page" + QString::number(nr) + ".html"));
- loadFinishedBarrier->ensureSignalEmitted();
+ QTRY_COMPARE(loadFinishedSpy->count(), 1);
}
public Q_SLOTS:
@@ -75,7 +76,7 @@ private Q_SLOTS:
private:
QWebEnginePage* page;
QWebEngineHistory* hist;
- QScopedPointer<SignalBarrier> loadFinishedBarrier;
+ QScopedPointer<QSignalSpy> loadFinishedSpy;
int histsize;
};
@@ -94,7 +95,7 @@ void tst_QWebEngineHistory::initTestCase()
void tst_QWebEngineHistory::init()
{
page = new QWebEnginePage(this);
- loadFinishedBarrier.reset(new SignalBarrier(page, SIGNAL(loadFinished(bool))));
+ loadFinishedSpy.reset(new QSignalSpy(page, SIGNAL(loadFinished(bool))));
for (int i = 1;i < 6;i++) {
loadPage(i);
@@ -105,7 +106,7 @@ void tst_QWebEngineHistory::init()
void tst_QWebEngineHistory::cleanup()
{
- loadFinishedBarrier.reset();
+ loadFinishedSpy.reset();
delete page;
}
@@ -114,7 +115,7 @@ void tst_QWebEngineHistory::cleanup()
*/
void tst_QWebEngineHistory::title()
{
- QCOMPARE(hist->currentItem().title(), QString("page5"));
+ QTRY_COMPARE(hist->currentItem().title(), QString("page5"));
}
void tst_QWebEngineHistory::lastVisited()
@@ -128,7 +129,7 @@ void tst_QWebEngineHistory::lastVisited()
*/
void tst_QWebEngineHistory::count()
{
- QCOMPARE(hist->count(), histsize);
+ QTRY_COMPARE(hist->count(), histsize);
}
/**
@@ -136,17 +137,17 @@ void tst_QWebEngineHistory::count()
*/
void tst_QWebEngineHistory::back()
{
- SignalBarrier titleChangedBarrier(page, SIGNAL(titleChanged(const QString&)));
+ QSignalSpy titleChangedSpy(page, SIGNAL(titleChanged(const QString&)));
for (int i = histsize;i > 1;i--) {
- QCOMPARE(toPlainTextSync(page), QString("page") + QString::number(i));
+ QTRY_COMPARE(toPlainTextSync(page), QString("page") + QString::number(i));
hist->back();
- loadFinishedBarrier->ensureSignalEmitted();
- QVERIFY(titleChangedBarrier.ensureSignalEmitted());
+ QTRY_COMPARE(loadFinishedSpy->count(), histsize-i+1);
+ QTRY_COMPARE(titleChangedSpy.count(), histsize-i+1);
}
//try one more time (too many). crash test
hist->back();
- QCOMPARE(toPlainTextSync(page), QString("page1"));
+ QTRY_COMPARE(toPlainTextSync(page), QString("page1"));
}
/**
@@ -155,21 +156,23 @@ void tst_QWebEngineHistory::back()
void tst_QWebEngineHistory::forward()
{
//rewind history :-)
+ int histBackCount = 0;
while (hist->canGoBack()) {
hist->back();
- loadFinishedBarrier->ensureSignalEmitted();
+ histBackCount++;
+ QTRY_COMPARE(loadFinishedSpy->count(), histBackCount+1);
}
- SignalBarrier titleChangedBarrier(page, SIGNAL(titleChanged(const QString&)));
+ QSignalSpy titleChangedSpy(page, SIGNAL(titleChanged(const QString&)));
for (int i = 1;i < histsize;i++) {
- QCOMPARE(toPlainTextSync(page), QString("page") + QString::number(i));
+ QTRY_COMPARE(toPlainTextSync(page), QString("page") + QString::number(i));
hist->forward();
- loadFinishedBarrier->ensureSignalEmitted();
- QVERIFY(titleChangedBarrier.ensureSignalEmitted());
+ QTRY_COMPARE(loadFinishedSpy->count(), i+histBackCount);
+ QTRY_COMPARE(titleChangedSpy.count(), i);
}
//try one more time (too many). crash test
hist->forward();
- QCOMPARE(toPlainTextSync(page), QString("page") + QString::number(histsize));
+ QTRY_COMPARE(toPlainTextSync(page), QString("page") + QString::number(histsize));
}
/**
@@ -178,7 +181,7 @@ void tst_QWebEngineHistory::forward()
void tst_QWebEngineHistory::itemAt()
{
for (int i = 1;i < histsize;i++) {
- QCOMPARE(hist->itemAt(i - 1).title(), QString("page") + QString::number(i));
+ QTRY_COMPARE(hist->itemAt(i - 1).title(), QString("page") + QString::number(i));
QVERIFY(hist->itemAt(i - 1).isValid());
}
//check out of range values
@@ -192,14 +195,19 @@ void tst_QWebEngineHistory::itemAt()
void tst_QWebEngineHistory::goToItem()
{
QWebEngineHistoryItem current = hist->currentItem();
+
hist->back();
- loadFinishedBarrier->ensureSignalEmitted();
+ QTRY_COMPARE(loadFinishedSpy->count(), 2);
+
hist->back();
- loadFinishedBarrier->ensureSignalEmitted();
+ QTRY_COMPARE(loadFinishedSpy->count(), 3);
+
QVERIFY(hist->currentItem().title() != current.title());
+
hist->goToItem(current);
- loadFinishedBarrier->ensureSignalEmitted();
- QCOMPARE(hist->currentItem().title(), current.title());
+ QTRY_COMPARE(loadFinishedSpy->count(), 3);
+
+ QTRY_COMPARE(hist->currentItem().title(), current.title());
}
/**
@@ -209,25 +217,27 @@ void tst_QWebEngineHistory::items()
{
QList<QWebEngineHistoryItem> items = hist->items();
//check count
- QCOMPARE(histsize, items.count());
+ QTRY_COMPARE(histsize, items.count());
//check order
for (int i = 1;i <= histsize;i++) {
- QCOMPARE(items.at(i - 1).title(), QString("page") + QString::number(i));
+ QTRY_COMPARE(items.at(i - 1).title(), QString("page") + QString::number(i));
}
}
void tst_QWebEngineHistory::backForwardItems()
{
hist->back();
- loadFinishedBarrier->ensureSignalEmitted();
+ QTRY_COMPARE(loadFinishedSpy->count(), 2);
+
hist->back();
- loadFinishedBarrier->ensureSignalEmitted();
- QCOMPARE(hist->items().size(), 5);
- QCOMPARE(hist->backItems(100).size(), 2);
- QCOMPARE(hist->backItems(1).size(), 1);
- QCOMPARE(hist->forwardItems(100).size(), 2);
- QCOMPARE(hist->forwardItems(1).size(), 1);
+ QTRY_COMPARE(loadFinishedSpy->count(), 3);
+
+ QTRY_COMPARE(hist->items().size(), 5);
+ QTRY_COMPARE(hist->backItems(100).size(), 2);
+ QTRY_COMPARE(hist->backItems(1).size(), 1);
+ QTRY_COMPARE(hist->forwardItems(100).size(), 2);
+ QTRY_COMPARE(hist->forwardItems(1).size(), 1);
}
/**
@@ -242,20 +252,20 @@ void tst_QWebEngineHistory::serialize_1()
save << *hist;
QVERIFY(save.status() == QDataStream::Ok);
- QCOMPARE(hist->count(), histsize);
+ QTRY_COMPARE(hist->count(), histsize);
//check size of history
//load next page to find differences
loadPage(6);
- QCOMPARE(hist->count(), histsize + 1);
+ QTRY_COMPARE(hist->count(), histsize + 1);
load >> *hist;
QVERIFY(load.status() == QDataStream::Ok);
- QCOMPARE(hist->count(), histsize);
+ QTRY_COMPARE(hist->count(), histsize);
//check order of historyItems
QList<QWebEngineHistoryItem> items = hist->items();
for (int i = 1;i <= histsize;i++) {
- QCOMPARE(items.at(i - 1).title(), QString("page") + QString::number(i));
+ QTRY_COMPARE(items.at(i - 1).title(), QString("page") + QString::number(i));
}
}
@@ -271,16 +281,16 @@ void tst_QWebEngineHistory::serialize_2()
// Force a "same document" navigation.
page->load(page->url().toString() + QLatin1String("#dummyAnchor"));
- loadFinishedBarrier->ensureSignalEmitted();
+ QTRY_COMPARE(loadFinishedSpy->count(), 1);
int initialCurrentIndex = hist->currentItemIndex();
hist->back();
- loadFinishedBarrier->ensureSignalEmitted();
+ QTRY_COMPARE(loadFinishedSpy->count(), 2);
hist->back();
- loadFinishedBarrier->ensureSignalEmitted();
+ QTRY_COMPARE(loadFinishedSpy->count(), 3);
hist->back();
- loadFinishedBarrier->ensureSignalEmitted();
+ QTRY_COMPARE(loadFinishedSpy->count(), 4);
//check if current index was changed (make sure that it is not last item)
QVERIFY(hist->currentItemIndex() != initialCurrentIndex);
//save current index
@@ -291,18 +301,18 @@ void tst_QWebEngineHistory::serialize_2()
load >> *hist;
QVERIFY(load.status() == QDataStream::Ok);
// Restoring the history will trigger a load.
- loadFinishedBarrier->ensureSignalEmitted();
+ QTRY_COMPARE(loadFinishedSpy->count(), 5);
//check current index
- QCOMPARE(hist->currentItemIndex(), oldCurrentIndex);
+ QTRY_COMPARE(hist->currentItemIndex(), oldCurrentIndex);
hist->forward();
- loadFinishedBarrier->ensureSignalEmitted();
+ QTRY_COMPARE(loadFinishedSpy->count(), 6);
hist->forward();
- loadFinishedBarrier->ensureSignalEmitted();
+ QTRY_COMPARE(loadFinishedSpy->count(), 7);
hist->forward();
- loadFinishedBarrier->ensureSignalEmitted();
- QCOMPARE(hist->currentItemIndex(), initialCurrentIndex);
+ QTRY_COMPARE(loadFinishedSpy->count(), 8);
+ QTRY_COMPARE(hist->currentItemIndex(), initialCurrentIndex);
}
/**
@@ -334,10 +344,10 @@ void tst_QWebEngineHistory::serialize_3()
QWebEngineHistoryItem b = hist->currentItem();
//check properties AFTER serialization
- QCOMPARE(b.title(), title);
- QCOMPARE(b.lastVisited(), lastVisited);
- QCOMPARE(b.originalUrl(), originalUrl);
- QCOMPARE(b.url(), url);
+ QTRY_COMPARE(b.title(), title);
+ QTRY_COMPARE(b.lastVisited(), lastVisited);
+ QTRY_COMPARE(b.originalUrl(), originalUrl);
+ QTRY_COMPARE(b.url(), url);
//Check if all data was read
QVERIFY(load.atEnd());
@@ -398,27 +408,16 @@ void tst_QWebEngineHistory::saveAndRestore_crash_3()
void tst_QWebEngineHistory::saveAndRestore_crash_4()
{
-#if !defined(QWEBENGINESETTINGS)
- QSKIP("QWEBENGINESETTINGS");
-#else
QByteArray buffer;
saveHistory(hist, &buffer);
QScopedPointer<QWebEnginePage> page2(new QWebEnginePage(this));
- // The initial crash was in PageCache.
- page2->settings()->setMaximumPagesInCache(3);
// Load the history in a new page, waiting for the load to finish.
- QEventLoop waitForLoadFinished;
- QObject::connect(page2.data(), SIGNAL(loadFinished(bool)), &waitForLoadFinished, SLOT(quit()), Qt::QueuedConnection);
+ QSignalSpy loadFinishedSpy2(page2.data(), SIGNAL(loadFinished(bool)));
QDataStream load(&buffer, QIODevice::ReadOnly);
load >> *page2->history();
- waitForLoadFinished.exec();
-
- page2.reset();
- // Give some time for the PageCache cleanup 0-timer to fire.
- QTest::qWait(50);
-#endif
+ QTRY_COMPARE(loadFinishedSpy2.count(), 1);
}
void tst_QWebEngineHistory::popPushState_data()
@@ -469,10 +468,10 @@ void tst_QWebEngineHistory::historyItemFromDeletedPage()
foreach (QWebEngineHistoryItem item, items) {
QVERIFY(!item.isValid());
- QCOMPARE(item.originalUrl(), QUrl());
- QCOMPARE(item.url(), QUrl());
- QCOMPARE(item.title(), QString());
- QCOMPARE(item.lastVisited(), QDateTime());
+ QTRY_COMPARE(item.originalUrl(), QUrl());
+ QTRY_COMPARE(item.url(), QUrl());
+ QTRY_COMPARE(item.title(), QString());
+ QTRY_COMPARE(item.lastVisited(), QDateTime());
}
}
diff --git a/tests/auto/widgets/qwebengineview/BLACKLIST b/tests/auto/widgets/qwebengineview/BLACKLIST
index 7121f7561..b3f393af4 100644
--- a/tests/auto/widgets/qwebengineview/BLACKLIST
+++ b/tests/auto/widgets/qwebengineview/BLACKLIST
@@ -3,3 +3,6 @@ windows
[imeComposition]
osx
+
+[inputFieldOverridesShortcuts]
+osx
diff --git a/tests/auto/widgets/qwebengineview/resources/input_types.html b/tests/auto/widgets/qwebengineview/resources/input_types.html
index 2e893afae..5ba1a6069 100644
--- a/tests/auto/widgets/qwebengineview/resources/input_types.html
+++ b/tests/auto/widgets/qwebengineview/resources/input_types.html
@@ -1,9 +1,9 @@
<html><body>
-<input type='text' maxlength='20' style='position: absolute; left: 10px; top: 0px; height: 50px; width: 100px;'/><br>
-<input type='password' style='position: absolute; left: 10px; top: 50px; height: 50px; width: 100px;'/><br>
-<input type='tel' style='position: absolute; left: 10px; top: 100px; height: 50px; width: 100px;'/><br>
-<input type='number' style='position: absolute; left: 10px; top: 150px; height: 50px; width: 100px;'/><br>
-<input type='email' style='position: absolute; left: 10px; top: 200px; height: 50px; width: 100px;'/><br>
-<input type='url' style='position: absolute; left: 10px; top: 250px; height: 50px; width: 100px;'/><br>
-<textarea style='position: absolute; left: 10px; top: 310px; height: 50px; width: 100px;' rows="2" cols="20">blah blah blah blah</textarea><br>
+<input type='text' id='textInput' maxlength='20' style='position: absolute; left: 10px; top: 0px; height: 50px; width: 100px;'/><br>
+<input type='password' id='passwordInput' style='position: absolute; left: 10px; top: 50px; height: 50px; width: 100px;'/><br>
+<input type='tel' id='telInput' style='position: absolute; left: 10px; top: 100px; height: 50px; width: 100px;'/><br>
+<input type='number' id='numberInput' style='position: absolute; left: 10px; top: 150px; height: 50px; width: 100px;'/><br>
+<input type='email' id='emailInput' style='position: absolute; left: 10px; top: 200px; height: 50px; width: 100px;'/><br>
+<input type='url' id='urlInput' style='position: absolute; left: 10px; top: 250px; height: 50px; width: 100px;'/><br>
+<textarea id='textArea' style='position: absolute; left: 10px; top: 310px; height: 50px; width: 100px;' rows="2" cols="20">blah blah blah blah</textarea><br>
</body></html>
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 37c7ae881..8509e9a2d 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -55,6 +55,43 @@ do { \
QCOMPARE((__expr), __expected); \
} while (0)
+static QPoint elementCenter(QWebEnginePage *page, const QString &id)
+{
+ const QString jsCode(
+ "(function(){"
+ " var elem = document.getElementById('" + id + "');"
+ " var rect = elem.getBoundingClientRect();"
+ " return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2];"
+ "})()");
+ QVariantList rectList = evaluateJavaScriptSync(page, jsCode).toList();
+
+ if (rectList.count() != 2) {
+ qWarning("elementCenter failed.");
+ return QPoint();
+ }
+
+ return QPoint(rectList.at(0).toInt(), rectList.at(1).toInt());
+}
+
+static QRect elementGeometry(QWebEnginePage *page, const QString &id)
+{
+ const QString jsCode(
+ "(function() {"
+ " var elem = document.getElementById('" + id + "');"
+ " var rect = elem.getBoundingClientRect();"
+ " return [rect.left, rect.top, rect.right, rect.bottom];"
+ "})()");
+ QVariantList coords = evaluateJavaScriptSync(page, jsCode).toList();
+
+ if (coords.count() != 4) {
+ qWarning("elementGeometry faield.");
+ return QRect();
+ }
+
+ return QRect(coords[0].toInt(), coords[1].toInt(), coords[2].toInt(), coords[3].toInt());
+}
+
+
class tst_QWebEngineView : public QObject
{
Q_OBJECT
@@ -263,113 +300,111 @@ void tst_QWebEngineView::crashTests()
void tst_QWebEngineView::microFocusCoordinates()
{
-#if !defined(QWEBENGINEPAGE_INPUTMETHODQUERY)
- QSKIP("QWEBENGINEPAGE_INPUTMETHODQUERY");
-#else
- QWebEnginePage* page = new QWebEnginePage;
- QWebEngineView* webView = new QWebEngineView;
- webView->setPage( page );
-
- page->setHtml("<html><body>" \
- "<input type='text' id='input1' style='font--family: serif' value='' maxlength='20'/><br>" \
- "<canvas id='canvas1' width='500' height='500'></canvas>" \
- "<input type='password'/><br>" \
- "<canvas id='canvas2' width='500' height='500'></canvas>" \
- "</body></html>");
-
-#if defined(QWEBENGINEFRAME)
- page->mainFrame()->setFocus();
-#endif
+ QWebEngineView webView;
+ webView.show();
+ QTest::qWaitForWindowExposed(&webView);
+
+ QSignalSpy scrollSpy(webView.page(), SIGNAL(scrollPositionChanged(QPointF)));
+ QSignalSpy loadFinishedSpy(&webView, SIGNAL(loadFinished(bool)));
+ webView.page()->setHtml("<html><body>"
+ "<input type='text' id='input1' value='' maxlength='20'/><br>"
+ "<canvas id='canvas1' width='500' height='500'></canvas>"
+ "<input type='password'/><br>"
+ "<canvas id='canvas2' width='500' height='500'></canvas>"
+ "</body></html>");
+ QVERIFY(loadFinishedSpy.wait());
- QVariant initialMicroFocus = page->inputMethodQuery(Qt::ImMicroFocus);
- QVERIFY(initialMicroFocus.isValid());
+ evaluateJavaScriptSync(webView.page(), "document.getElementById('input1').focus()");
+ QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
- page->scroll(0,50);
+ QTRY_VERIFY(webView.focusProxy()->inputMethodQuery(Qt::ImMicroFocus).isValid());
+ QVariant initialMicroFocus = webView.focusProxy()->inputMethodQuery(Qt::ImMicroFocus);
- QVariant currentMicroFocus = page->inputMethodQuery(Qt::ImMicroFocus);
- QVERIFY(currentMicroFocus.isValid());
+ evaluateJavaScriptSync(webView.page(), "window.scrollBy(0, 50)");
+ QVERIFY(scrollSpy.wait());
+
+ QTRY_VERIFY(webView.focusProxy()->inputMethodQuery(Qt::ImMicroFocus).isValid());
+ QVariant currentMicroFocus = webView.focusProxy()->inputMethodQuery(Qt::ImMicroFocus);
QCOMPARE(initialMicroFocus.toRect().translated(QPoint(0,-50)), currentMicroFocus.toRect());
-#endif
}
void tst_QWebEngineView::focusInputTypes()
{
-#if !defined(QWEBENGINEELEMENT)
- QSKIP("QWEBENGINEELEMENT");
-#else
QWebEngineView webView;
webView.show();
QTest::qWaitForWindowExposed(&webView);
- QUrl url("qrc:///resources/input_types.html");
- QWebEngineFrame* const mainFrame = webView.page()->mainFrame();
- webView.load(url);
- mainFrame->setFocus();
-
- QSignalSpy spyFinished(webView, &QWebEngineView::loadFinished);
- QVERIFY(spyFinished.wait());
+ QSignalSpy loadFinishedSpy(&webView, SIGNAL(loadFinished(bool)));
+ webView.load(QUrl("qrc:///resources/input_types.html"));
+ QVERIFY(loadFinishedSpy.wait());
- // 'text' type
- QWebEngineElement inputElement = mainFrame->documentElement().findFirst(QLatin1String("input[type=text]"));
- QTest::mouseClick(&webView, Qt::LeftButton, 0, inputElement.geometry().center());
- QVERIFY(webView.inputMethodHints() == Qt::ImhNone);
- QVERIFY(webView.testAttribute(Qt::WA_InputMethodEnabled));
+ // 'text' field
+ QPoint textInputCenter = elementCenter(webView.page(), "textInput");
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("textInput"));
+ VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), Qt::ImhPreferLowercase);
+ QVERIFY(webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
// 'password' field
- inputElement = mainFrame->documentElement().findFirst(QLatin1String("input[type=password]"));
- QTest::mouseClick(&webView, Qt::LeftButton, 0, inputElement.geometry().center());
- VERIFY_INPUTMETHOD_HINTS(webView.inputMethodHints(), Qt::ImhHiddenText);
- QVERIFY(webView.testAttribute(Qt::WA_InputMethodEnabled));
+ QPoint passwordInputCenter = elementCenter(webView.page(), "passwordInput");
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, passwordInputCenter);
+ QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("passwordInput"));
+ VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), (Qt::ImhSensitiveData | Qt::ImhNoPredictiveText | Qt::ImhNoAutoUppercase | Qt::ImhHiddenText));
+ QVERIFY(webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
// 'tel' field
- inputElement = mainFrame->documentElement().findFirst(QLatin1String("input[type=tel]"));
- QTest::mouseClick(&webView, Qt::LeftButton, 0, inputElement.geometry().center());
- VERIFY_INPUTMETHOD_HINTS(webView.inputMethodHints(), Qt::ImhDialableCharactersOnly);
- QVERIFY(webView.testAttribute(Qt::WA_InputMethodEnabled));
+ QPoint telInputCenter = elementCenter(webView.page(), "telInput");
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, telInputCenter);
+ QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("telInput"));
+ VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), Qt::ImhDialableCharactersOnly);
+ QVERIFY(webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
// 'number' field
- inputElement = mainFrame->documentElement().findFirst(QLatin1String("input[type=number]"));
- QTest::mouseClick(&webView, Qt::LeftButton, 0, inputElement.geometry().center());
- VERIFY_INPUTMETHOD_HINTS(webView.inputMethodHints(), Qt::ImhDigitsOnly);
- QVERIFY(webView.testAttribute(Qt::WA_InputMethodEnabled));
+ QPoint numberInputCenter = elementCenter(webView.page(), "numberInput");
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, numberInputCenter);
+ QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("numberInput"));
+ VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), Qt::ImhFormattedNumbersOnly);
+ QVERIFY(webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
// 'email' field
- inputElement = mainFrame->documentElement().findFirst(QLatin1String("input[type=email]"));
- QTest::mouseClick(&webView, Qt::LeftButton, 0, inputElement.geometry().center());
- VERIFY_INPUTMETHOD_HINTS(webView.inputMethodHints(), Qt::ImhEmailCharactersOnly);
- QVERIFY(webView.testAttribute(Qt::WA_InputMethodEnabled));
+ QPoint emailInputCenter = elementCenter(webView.page(), "emailInput");
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, emailInputCenter);
+ QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("emailInput"));
+ VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), Qt::ImhEmailCharactersOnly);
+ QVERIFY(webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
// 'url' field
- inputElement = mainFrame->documentElement().findFirst(QLatin1String("input[type=url]"));
- QTest::mouseClick(&webView, Qt::LeftButton, 0, inputElement.geometry().center());
- VERIFY_INPUTMETHOD_HINTS(webView.inputMethodHints(), Qt::ImhUrlCharactersOnly);
- QVERIFY(webView.testAttribute(Qt::WA_InputMethodEnabled));
+ QPoint urlInputCenter = elementCenter(webView.page(), "urlInput");
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, urlInputCenter);
+ QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("urlInput"));
+ VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), (Qt::ImhUrlCharactersOnly | Qt::ImhNoPredictiveText | Qt::ImhNoAutoUppercase));
+ QVERIFY(webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
// 'password' field
- inputElement = mainFrame->documentElement().findFirst(QLatin1String("input[type=password]"));
- QTest::mouseClick(&webView, Qt::LeftButton, 0, inputElement.geometry().center());
- VERIFY_INPUTMETHOD_HINTS(webView.inputMethodHints(), Qt::ImhHiddenText);
- QVERIFY(webView.testAttribute(Qt::WA_InputMethodEnabled));
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, passwordInputCenter);
+ QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("passwordInput"));
+ VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), (Qt::ImhSensitiveData | Qt::ImhNoPredictiveText | Qt::ImhNoAutoUppercase | Qt::ImhHiddenText));
+ QVERIFY(webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
// 'text' type
- inputElement = mainFrame->documentElement().findFirst(QLatin1String("input[type=text]"));
- QTest::mouseClick(&webView, Qt::LeftButton, 0, inputElement.geometry().center());
- QVERIFY(webView.inputMethodHints() == Qt::ImhNone);
- QVERIFY(webView.testAttribute(Qt::WA_InputMethodEnabled));
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("textInput"));
+ VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), Qt::ImhPreferLowercase);
+ QVERIFY(webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
// 'password' field
- inputElement = mainFrame->documentElement().findFirst(QLatin1String("input[type=password]"));
- QTest::mouseClick(&webView, Qt::LeftButton, 0, inputElement.geometry().center());
- VERIFY_INPUTMETHOD_HINTS(webView.inputMethodHints(), Qt::ImhHiddenText);
- QVERIFY(webView.testAttribute(Qt::WA_InputMethodEnabled));
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, passwordInputCenter);
+ QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("passwordInput"));
+ VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), (Qt::ImhSensitiveData | Qt::ImhNoPredictiveText | Qt::ImhNoAutoUppercase | Qt::ImhHiddenText));
+ QVERIFY(webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
// 'text area' field
- inputElement = mainFrame->documentElement().findFirst(QLatin1String("textarea"));
- QTest::mouseClick(&webView, Qt::LeftButton, 0, inputElement.geometry().center());
- QVERIFY(webView.inputMethodHints() == Qt::ImhNone);
- QVERIFY(webView.testAttribute(Qt::WA_InputMethodEnabled));
-#endif
+ QPoint textAreaCenter = elementCenter(webView.page(), "textArea");
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, textAreaCenter);
+ QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("textArea"));
+ VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), (Qt::ImhMultiLine | Qt::ImhPreferLowercase));
+ QVERIFY(webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
}
class KeyEventRecordingWidget : public QWidget {
@@ -1309,7 +1344,6 @@ void tst_QWebEngineView::inputFieldOverridesShortcuts()
{
bool actionTriggered = false;
QAction *action = new QAction;
- action->setShortcut(Qt::Key_X);
connect(action, &QAction::triggered, [&actionTriggered] () { actionTriggered = true; });
QWebEngineView view;
@@ -1317,7 +1351,7 @@ void tst_QWebEngineView::inputFieldOverridesShortcuts()
QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
view.setHtml(QString("<html><body onload=\"input1=document.getElementById('input1')\">"
- "<input id=\"dummy\" type=\"text\">"
+ "<button id=\"btn1\" type=\"button\">push it real good</button>"
"<input id=\"input1\" type=\"text\" value=\"x\">"
"</body></html>"));
QVERIFY(loadFinishedSpy.wait());
@@ -1330,7 +1364,15 @@ void tst_QWebEngineView::inputFieldOverridesShortcuts()
"input1.value").toString();
};
+ // The input form is not focused. The action is triggered on pressing Shift+Delete.
+ action->setShortcut(Qt::SHIFT + Qt::Key_Delete);
+ QTest::keyClick(view.windowHandle(), Qt::Key_Delete, Qt::ShiftModifier);
+ QTRY_VERIFY(actionTriggered);
+ QCOMPARE(inputFieldValue(), QString("x"));
+
// The input form is not focused. The action is triggered on pressing X.
+ action->setShortcut(Qt::Key_X);
+ actionTriggered = false;
QTest::keyClick(view.windowHandle(), Qt::Key_X);
QTRY_VERIFY(actionTriggered);
QCOMPARE(inputFieldValue(), QString("x"));
@@ -1349,16 +1391,12 @@ void tst_QWebEngineView::inputFieldOverridesShortcuts()
QTRY_VERIFY(actionTriggered);
QCOMPARE(inputFieldValue(), QString("yx"));
- // Remove focus from the input field. A QKeySequence::Copy action still must not be triggered.
- evaluateJavaScriptSync(view.page(), "input1.blur();");
+ // Remove focus from the input field. A QKeySequence::Copy action must be triggerable.
+ evaluateJavaScriptSync(view.page(), "document.getElementById('btn1').focus();");
action->setShortcut(QKeySequence::Copy);
actionTriggered = false;
QTest::keyClick(view.windowHandle(), Qt::Key_C, Qt::ControlModifier);
- // Add some text in the input field to ensure that the key event went through.
- evaluateJavaScriptSync(view.page(), "input1.focus();");
- QTest::keyClick(view.windowHandle(), Qt::Key_U);
- QTRY_COMPARE(inputFieldValue(), QString("yux"));
- QVERIFY(!actionTriggered);
+ QTRY_VERIFY(actionTriggered);
}
class TestInputContext : public QPlatformInputContext
@@ -1393,42 +1431,6 @@ public:
bool m_visible;
};
-static QPoint elementCenter(QWebEnginePage *page, const QString &id)
-{
- const QString jsCode(
- "(function(){"
- " var elem = document.getElementById('" + id + "');"
- " var rect = elem.getBoundingClientRect();"
- " return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2];"
- "})()");
- QVariantList rectList = evaluateJavaScriptSync(page, jsCode).toList();
-
- if (rectList.count() != 2) {
- qWarning("elementCenter failed.");
- return QPoint();
- }
-
- return QPoint(rectList.at(0).toInt(), rectList.at(1).toInt());
-}
-
-static QRect elementGeometry(QWebEnginePage *page, const QString &id)
-{
- const QString jsCode(
- "(function() {"
- " var elem = document.getElementById('" + id + "');"
- " var rect = elem.getBoundingClientRect();"
- " return [rect.left, rect.top, rect.right, rect.bottom];"
- "})()");
- QVariantList coords = evaluateJavaScriptSync(page, jsCode).toList();
-
- if (coords.count() != 4) {
- qWarning("elementGeometry faield.");
- return QRect();
- }
-
- return QRect(coords[0].toInt(), coords[1].toInt(), coords[2].toInt(), coords[3].toInt());
-}
-
void tst_QWebEngineView::softwareInputPanel()
{
TestInputContext testContext;
@@ -1798,12 +1800,36 @@ void tst_QWebEngineView::emptyInputMethodEvent()
QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue);
QCOMPARE(selectionChangedSpy.count(), 1);
- // Send empty QInputMethodEvent
+ // 1. Empty input method event does not clear text
QInputMethodEvent emptyEvent;
QApplication::sendEvent(view.focusProxy(), &emptyEvent);
QString inputValue = evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString();
- QCOMPARE(inputValue, QString("QtWebEngine"));
+ QCOMPARE(inputValue, QStringLiteral("QtWebEngine"));
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QStringLiteral("QtWebEngine"));
+
+ // Reset: clear input field
+ evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1').value = ''");
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString().isEmpty());
+ QTRY_VERIFY(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString().isEmpty());
+
+ // 2. Cancel IME composition with empty input method event
+ // Start IME composition
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent eventComposition("a", attributes);
+ QApplication::sendEvent(view.focusProxy(), &eventComposition);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), QStringLiteral("a"));
+ QVERIFY(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString().isEmpty());
+
+ // Cancel IME composition
+ QApplication::sendEvent(view.focusProxy(), &emptyEvent);
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString().isEmpty());
+ QVERIFY(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString().isEmpty());
+
+ // Try key press after cancelled IME composition
+ QTest::keyClick(view.focusProxy(), Qt::Key_B);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), QStringLiteral("b"));
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QStringLiteral("b"));
}
void tst_QWebEngineView::imeComposition()