summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2016-02-04 13:50:57 +0100
committerAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2016-02-04 14:13:39 +0100
commit6722bbbf4ea2ddcdd9194f26a883029ec3afc39a (patch)
treec3290b82fac21c4990be8472ae6cb4ca043205cf
parent41d69eb0fa2375f0da6ba9b35136f5598be4b3a4 (diff)
parent82f4d13a13b40d9cb7710f6dd4190175a272a394 (diff)
Merge branch '5.6' into dev
-rw-r--r--dist/changes-5.6.02
-rw-r--r--examples/examples.pro1
-rw-r--r--examples/webenginewidgets/contentmanipulation/doc/images/contentmanipulation-example.pngbin98031 -> 30363 bytes
-rw-r--r--examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc153
-rw-r--r--examples/webenginewidgets/contentmanipulation/mainwindow.cpp26
-rw-r--r--examples/webenginewidgets/contentmanipulation/mainwindow.h2
-rw-r--r--examples/webenginewidgets/cookiebrowser/cookiebrowser.pro19
-rw-r--r--examples/webenginewidgets/cookiebrowser/cookiebrowser.qrc5
-rw-r--r--examples/webenginewidgets/cookiebrowser/cookiedialog.ui189
-rw-r--r--examples/webenginewidgets/cookiebrowser/cookiewidget.ui92
-rw-r--r--examples/webenginewidgets/cookiebrowser/doc/images/cookiebrowser.pngbin0 -> 31643 bytes
-rw-r--r--examples/webenginewidgets/cookiebrowser/doc/src/cookiebrowser.qdoc41
-rw-r--r--examples/webenginewidgets/cookiebrowser/main.cpp52
-rw-r--r--examples/webenginewidgets/cookiebrowser/mainwindow.cpp192
-rw-r--r--examples/webenginewidgets/cookiebrowser/mainwindow.h96
-rw-r--r--examples/webenginewidgets/cookiebrowser/mainwindow.ui200
-rw-r--r--examples/webenginewidgets/cookiebrowser/view-refresh.pngbin0 -> 1364 bytes
m---------src/3rdparty0
-rw-r--r--src/core/api/qwebenginecookiestore.cpp32
-rw-r--r--src/core/api/qwebengineurlrequestinfo.cpp4
-rw-r--r--src/core/api/qwebengineurlrequestjob.h4
-rw-r--r--src/core/browser_context_adapter.cpp2
-rw-r--r--src/core/config/common.pri10
-rw-r--r--src/core/config/embedded_qnx.pri2
-rw-r--r--src/core/config/linux.pri3
-rw-r--r--src/core/config/mac_osx.pri2
-rw-r--r--src/core/config/windows.pri2
-rw-r--r--src/core/content_client_qt.cpp7
-rw-r--r--src/core/core_module.pro25
-rw-r--r--src/core/render_widget_host_view_qt.cpp4
-rw-r--r--src/core/url_request_context_getter_qt.cpp15
-rw-r--r--src/core/url_request_context_getter_qt.h3
-rw-r--r--src/core/url_request_custom_job.cpp234
-rw-r--r--src/core/url_request_custom_job.h41
-rw-r--r--src/core/url_request_custom_job_delegate.cpp19
-rw-r--r--src/core/url_request_custom_job_delegate.h8
-rw-r--r--src/core/web_contents_adapter_client.h2
-rw-r--r--src/core/web_contents_delegate_qt.cpp11
-rw-r--r--src/core/web_contents_delegate_qt.h2
-rw-r--r--src/core/web_engine_library_info.cpp4
-rw-r--r--src/webengine/api/qquickwebenginehistory.cpp2
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h1
-rw-r--r--src/webengine/doc/src/qtwebengine-platform-notes.qdoc2
-rw-r--r--src/webengine/doc/src/webengineview.qdoc19
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp26
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h3
-rw-r--r--src/webenginewidgets/api/qwebenginescriptcollection.cpp12
-rw-r--r--src/webenginewidgets/api/qwebenginescriptcollection_p.h2
-rw-r--r--src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc7
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc14
-rw-r--r--src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc4
-rw-r--r--tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp32
-rw-r--r--tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp7
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp36
-rw-r--r--tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp105
-rwxr-xr-xtools/buildscripts/gyp_qtwebengine5
-rw-r--r--tools/qmake/mkspecs/features/configure.prf2
-rw-r--r--tools/qmake/mkspecs/features/functions.prf50
58 files changed, 1551 insertions, 284 deletions
diff --git a/dist/changes-5.6.0 b/dist/changes-5.6.0
index f60338bfd..f6495942a 100644
--- a/dist/changes-5.6.0
+++ b/dist/changes-5.6.0
@@ -21,7 +21,7 @@ information about a particular change.
- Chromium Snapshot:
* The Chromium version has been updated to 45.0.2554.101.
- * In addition security fixes from Chromium 46 and 47 have been merged.
+ * In addition security fixes from Chromium 46, 47 and 48 have been merged.
- General:
* The WebEngineCore module now contains shared C++ API.
diff --git a/examples/examples.pro b/examples/examples.pro
index fdd25664f..867ce4cc6 100644
--- a/examples/examples.pro
+++ b/examples/examples.pro
@@ -7,6 +7,7 @@ qtHaveModule(webengine) {
qtHaveModule(webenginewidgets) {
SUBDIRS += \
webenginewidgets/contentmanipulation \
+ webenginewidgets/cookiebrowser \
webenginewidgets/demobrowser \
webenginewidgets/markdowneditor
}
diff --git a/examples/webenginewidgets/contentmanipulation/doc/images/contentmanipulation-example.png b/examples/webenginewidgets/contentmanipulation/doc/images/contentmanipulation-example.png
index 717ac9ddc..ecdbc4c64 100644
--- a/examples/webenginewidgets/contentmanipulation/doc/images/contentmanipulation-example.png
+++ b/examples/webenginewidgets/contentmanipulation/doc/images/contentmanipulation-example.png
Binary files differ
diff --git a/examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc b/examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc
index ab5dd06c6..aa94b17da 100644
--- a/examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc
+++ b/examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc
@@ -29,114 +29,143 @@
\example webenginewidgets/contentmanipulation
\title WebEngine Content Manipulation Example
\ingroup webengine-widgetexamples
- \brief Demonstrates how to use browse web and manipulate content
-
- \brief The Content Manipulation example shows how to use JQuery with QtWebEngine to
- create a web browser with special effects and content
- manipulation.
+ \brief Demonstrates how to load and manipulate web content.
\image contentmanipulation-example.png
- The application makes use of QWebEnginePage::evaluateJavaScript to
- evaluate the jQuery JavaScript code. A QMainWindow with a QWebEngineView
- as central widget builds up the browser itself.
+ \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
+ execute jQuery JavaScript code. We implement a QMainWindow with a QWebEngineView
+ as a central widget to build up the browser itself.
\include examples-run.qdocinc
\section1 MainWindow Class Definition
The \c MainWindow class inherits QMainWindow. It implements a number of
- slots to perform actions on both the application and on the web content.
+ slots to perform actions on both the application and on the web content:
- \snippet webenginewidgets/contentmanipulation/mainwindow.h 1
+ \quotefromfile webenginewidgets/contentmanipulation/mainwindow.h
+ \skipto class MainWindow :
+ \printuntil /^\}/
- We also declare a QString that contains the jQuery, a QWebView
+ We also declare a QString that contains the jQuery, a QWebEngineView
that displays the web content, and a QLineEdit that acts as the
address bar.
\section1 MainWindow Class Implementation
- We start by implementing the constructor.
-
- \snippet webenginewidgets/contentmanipulation/mainwindow.cpp 1
+ We start by implementing the constructor. The first part of the constructor sets the value of
+ \c progress to 0. This value will be used later in the code to visualize the loading of a
+ web page:
- The first part of the constructor sets the value of \c progress to
- 0. This value will be used later in the code to visualize the
- loading of a webpage.
+ \quotefromfile webenginewidgets/contentmanipulation/mainwindow.cpp
+ \skipto MainWindow::MainWindow
+ \printuntil progress
- Next, the jQuery library is loaded using a QFile and reading the file
+ Next, the jQuery library is loaded by using a QFile and reading the file
content. The jQuery library is a JavaScript library that provides different
- functions for manipulating HTML.
+ functions for manipulating HTML:
+
+ \printuntil file.close()
+
+ The second part of the constructor creates a QWebEngineView and connects
+ slots to the view's signals:
+
+ \printuntil SLOT(finishLoading
+
+ Furthermore, we create a QLineEdit as the browser's address bar. We then set the horizontal
+ 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():
+
+ \printuntil addWidget(locationEdit)
+
+ The third part of the constructor implements two QMenu widgets and assigns
+ a set of actions to them:
+
+ \printuntil removeEmbeddedElements
- \snippet webenginewidgets/contentmanipulation/mainwindow.cpp 2
+ The last line sets the QWebEngineView as the central widget in the QMainWindow:
- The second part of the constructor creates a QWebView and connects
- slots to the views signals. Furthermore, we create a QLineEdit as
- the browsers address bar. We then set the horizontal 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 QWebView::pageAction.
+ \printuntil }
- \snippet webenginewidgets/contentmanipulation/mainwindow.cpp 3
+ When the page is loaded, \c adjustLocation() is triggered by the \c loadFinished() signal in
+ QWebEngineView to update the address bar:
- The third and last part of the constructor implements two QMenus and assigns
- a set of actions to them. The last line sets the QWebView as the central
- widget in the QMainWindow.
+ \skipto adjustLocation()
+ \printuntil }
- \snippet webenginewidgets/contentmanipulation/mainwindow.cpp 4
+ In \c changeLocation(), we create a QUrl object, and then use it to load the page into the
+ QWebEngineView. When the new web page has finished loading, \c adjustLocation() will be
+ run once more to update the address bar:
- When the page is loaded, \c adjustLocation() updates the address
- bar; \c adjustLocation() is triggered by the \c loadFinished()
- signal in QWebView. In \c changeLocation() we create a QUrl
- object, and then use it to load the page into the QWebView. When
- the new web page has finished loading, \c adjustLocation() will be
- run once more to update the address bar.
+ \printuntil }
- \snippet webenginewidgets/contentmanipulation/mainwindow.cpp 5
+ The \c adjustTitle() method sets the window title and displays the loading progress:
- \c adjustTitle() sets the window title and displays the loading
- progress. This slot is triggered by the \c titleChanged() signal
- in QWebView.
+ \printuntil }
+ \printuntil }
- \snippet webenginewidgets/contentmanipulation/mainwindow.cpp 6
+ This slot is triggered by the \c titleChanged() signal in QWebEngineView.
- When a web page has loaded, \c finishLoading() is triggered by the
- \c loadFinished() signal in QWebView. \c finishLoading() then updates the
- progress in the title bar and calls \c evaluateJavaScript()
- to evaluate the jQuery library. This evaluates the JavaScript against the
- current web page. What that means is that the JavaScript can be viewed as
- part of the content loaded into the QWebView, and therefore needs to be
+ When a web page has loaded, the \c finishLoading() method is triggered by the
+ \c loadFinished() signal in QWebEngineView. The method then updates the
+ progress in the title bar and calls \c runJavaScript()
+ to evaluate the jQuery library against the current web page:
+
+ \printuntil }
+
+ This means that the JavaScript can be viewed as a
+ part of the content loaded into the QWebEngineView, and therefore needs to be
loaded every time a new page is loaded. Once the jQuery library is loaded,
we can start executing the different jQuery functions in the browser.
- The rotateImages() function is then called explicitely to make sure
+ The \c rotateImages() function is then called explicitly to make sure
that the images of the newly loaded page respect the state of the toggle
action.
- \snippet webenginewidgets/contentmanipulation/mainwindow.cpp 7
-
The first jQuery-based function, \c highlightAllLinks(), is designed to
highlight all links in the current webpage. The JavaScript code looks
for web elements named \e {a}, which is the tag for a hyperlink.
For each such element, the background color is set to be yellow by
- using CSS.
+ using CSS:
- \snippet webenginewidgets/contentmanipulation/mainwindow.cpp 8
+ \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 and
+ web page. This JavaScript code relies on CSS transforms. It
looks up all \e {img} elements and rotates the images 180 degrees
- and then back again.
+ and then back again:
- \snippet webenginewidgets/contentmanipulation/mainwindow.cpp 9
+ \printuntil runJavaScript(code);
+ \printuntil }
- The remaining four methods remove different elements from the current web
- page. \c removeGifImages() removes all GIF images on the page by looking up
+ The remaining methods remove different elements from the current web
+ page. The \c removeGifImages() removes all GIF images on the page by looking up
the \e {src} attribute of all the elements on the web page. Any element with
- a \e {gif} file as its source is removed. \c removeInlineFrames() removes all
- \e {iframe} or inline elements. \c removeObjectElements() removes all
- \e {object} elements, and \c removeEmbeddedElements() removes any elements
- such as plugins embedded on the page using the \e {embed} tag.
+ a \e {gif} file as its source is removed:
+
+ \printuntil }
+
+ The \c removeInlineFrames() method removes all \e {iframe} or inline elements:
+
+ \printuntil }
+
+ The \c removeObjectElements() method removes all \e {object} elements:
+
+ \printuntil }
+
+ The \c removeEmbeddedElements() method removes any elements using the \e {embed} tag, such as
+ plugins embedded on the page:
+ \printuntil }
*/
diff --git a/examples/webenginewidgets/contentmanipulation/mainwindow.cpp b/examples/webenginewidgets/contentmanipulation/mainwindow.cpp
index 545d2c45a..3198f0908 100644
--- a/examples/webenginewidgets/contentmanipulation/mainwindow.cpp
+++ b/examples/webenginewidgets/contentmanipulation/mainwindow.cpp
@@ -68,8 +68,6 @@ InvokeWrapper<Arg, R, C> invoke(R *receiver, void (C::*memberFun)(Arg))
return wrapper;
}
-//! [1]
-
MainWindow::MainWindow(const QUrl& url)
{
progress = 0;
@@ -80,9 +78,7 @@ MainWindow::MainWindow(const QUrl& url)
jQuery = file.readAll();
jQuery.append("\nvar qt = { 'jQuery': jQuery.noConflict(true) };");
file.close();
-//! [1]
-//! [2]
view = new QWebEngineView(this);
view->load(url);
connect(view, SIGNAL(loadFinished(bool)), SLOT(adjustLocation()));
@@ -100,14 +96,12 @@ MainWindow::MainWindow(const QUrl& url)
toolBar->addAction(view->pageAction(QWebEnginePage::Reload));
toolBar->addAction(view->pageAction(QWebEnginePage::Stop));
toolBar->addWidget(locationEdit);
-//! [2]
QMenu *viewMenu = menuBar()->addMenu(tr("&View"));
QAction* viewSourceAction = new QAction("Page Source", this);
connect(viewSourceAction, SIGNAL(triggered()), SLOT(viewSource()));
viewMenu->addAction(viewSourceAction);
-//! [3]
QMenu *effectMenu = menuBar()->addMenu(tr("&Effect"));
effectMenu->addAction("Highlight all links", this, SLOT(highlightAllLinks()));
@@ -126,7 +120,6 @@ MainWindow::MainWindow(const QUrl& url)
setCentralWidget(view);
}
-//! [3]
void MainWindow::viewSource()
{
@@ -139,7 +132,6 @@ void MainWindow::viewSource()
view->page()->toHtml(invoke(textEdit, &QTextEdit::setPlainText));
}
-//! [4]
void MainWindow::adjustLocation()
{
locationEdit->setText(view->url().toString());
@@ -151,9 +143,7 @@ void MainWindow::changeLocation()
view->load(url);
view->setFocus();
}
-//! [4]
-//! [5]
void MainWindow::adjustTitle()
{
if (progress <= 0 || progress >= 100)
@@ -167,9 +157,7 @@ void MainWindow::setProgress(int p)
progress = p;
adjustTitle();
}
-//! [5]
-//! [6]
void MainWindow::finishLoading(bool)
{
progress = 100;
@@ -178,36 +166,24 @@ void MainWindow::finishLoading(bool)
rotateImages(rotateAction->isChecked());
}
-//! [6]
-//! [7]
void MainWindow::highlightAllLinks()
{
- // We append '; undefined' after the jQuery call here 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 QVariants.
QString code = "qt.jQuery('a').each( function () { qt.jQuery(this).css('background-color', 'yellow') } ); undefined";
view->page()->runJavaScript(code);
}
-//! [7]
-//! [8]
void MainWindow::rotateImages(bool invert)
{
QString code;
- // We append '; undefined' after each of the jQuery calls here 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 QVariants.
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";
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";
view->page()->runJavaScript(code);
}
-//! [8]
-//! [9]
void MainWindow::removeGifImages()
{
QString code = "qt.jQuery('[src*=gif]').remove()";
@@ -231,5 +207,3 @@ void MainWindow::removeEmbeddedElements()
QString code = "qt.jQuery('embed').remove()";
view->page()->runJavaScript(code);
}
-//! [9]
-
diff --git a/examples/webenginewidgets/contentmanipulation/mainwindow.h b/examples/webenginewidgets/contentmanipulation/mainwindow.h
index 65a6cc6c2..66512f969 100644
--- a/examples/webenginewidgets/contentmanipulation/mainwindow.h
+++ b/examples/webenginewidgets/contentmanipulation/mainwindow.h
@@ -55,7 +55,6 @@ class QWebEngineView;
class QLineEdit;
QT_END_NAMESPACE
-//! [1]
class MainWindow : public QMainWindow
{
Q_OBJECT
@@ -86,5 +85,4 @@ private:
QLineEdit *locationEdit;
QAction *rotateAction;
int progress;
-//! [1]
};
diff --git a/examples/webenginewidgets/cookiebrowser/cookiebrowser.pro b/examples/webenginewidgets/cookiebrowser/cookiebrowser.pro
new file mode 100644
index 000000000..66ea064ef
--- /dev/null
+++ b/examples/webenginewidgets/cookiebrowser/cookiebrowser.pro
@@ -0,0 +1,19 @@
+QT += core gui webenginewidgets
+TARGET = cookiebrowser
+TEMPLATE = app
+CONFIG += c++11
+
+SOURCES += \
+ main.cpp\
+ mainwindow.cpp
+
+HEADERS += \
+ mainwindow.h
+
+FORMS += \
+ mainwindow.ui \
+ cookiedialog.ui \
+ cookiewidget.ui
+
+RESOURCES += \
+ cookiebrowser.qrc
diff --git a/examples/webenginewidgets/cookiebrowser/cookiebrowser.qrc b/examples/webenginewidgets/cookiebrowser/cookiebrowser.qrc
new file mode 100644
index 000000000..8805f2c53
--- /dev/null
+++ b/examples/webenginewidgets/cookiebrowser/cookiebrowser.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>view-refresh.png</file>
+ </qresource>
+</RCC>
diff --git a/examples/webenginewidgets/cookiebrowser/cookiedialog.ui b/examples/webenginewidgets/cookiebrowser/cookiedialog.ui
new file mode 100644
index 000000000..ad6e5cab1
--- /dev/null
+++ b/examples/webenginewidgets/cookiebrowser/cookiedialog.ui
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CookieDialog</class>
+ <widget class="QDialog" name="CookieDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>245</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Cookie</string>
+ </property>
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="m_nameLineEdit">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Domain</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="m_domainLineEdit">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Path</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QLineEdit" name="m_pathLineEdit">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>isHttpOnly</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QComboBox" name="m_isHttpOnlyComboBox"/>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>isSecure</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="m_addButton">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="m_cancelButton">
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="7" column="1">
+ <widget class="QComboBox" name="m_isSecureComboBox"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Value</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="m_valueLineEdit">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QDateEdit" name="m_dateEdit">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>Expires</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>m_nameLineEdit</tabstop>
+ <tabstop>m_domainLineEdit</tabstop>
+ <tabstop>m_valueLineEdit</tabstop>
+ <tabstop>m_dateEdit</tabstop>
+ <tabstop>m_pathLineEdit</tabstop>
+ <tabstop>m_isHttpOnlyComboBox</tabstop>
+ <tabstop>m_isSecureComboBox</tabstop>
+ <tabstop>m_addButton</tabstop>
+ <tabstop>m_cancelButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>m_cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>CookieDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>350</x>
+ <y>103</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>199</x>
+ <y>63</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>m_addButton</sender>
+ <signal>clicked()</signal>
+ <receiver>CookieDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>265</x>
+ <y>112</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>199</x>
+ <y>63</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/examples/webenginewidgets/cookiebrowser/cookiewidget.ui b/examples/webenginewidgets/cookiebrowser/cookiewidget.ui
new file mode 100644
index 000000000..816d7473e
--- /dev/null
+++ b/examples/webenginewidgets/cookiebrowser/cookiewidget.ui
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CookieWidget</class>
+ <widget class="QWidget" name="CookieWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>300</width>
+ <height>71</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>310</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout" stretch="3,1">
+ <item>
+ <layout class="QFormLayout" name="formLayout">
+ <property name="formAlignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="m_nameLabel">
+ <property name="text">
+ <string>Empty</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Domain:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="m_domainLabel">
+ <property name="text">
+ <string>Emtpy</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QPushButton" name="m_viewButton">
+ <property name="text">
+ <string>View</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="m_deleteButton">
+ <property name="text">
+ <string>Delete</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/webenginewidgets/cookiebrowser/doc/images/cookiebrowser.png b/examples/webenginewidgets/cookiebrowser/doc/images/cookiebrowser.png
new file mode 100644
index 000000000..4e76ba6d9
--- /dev/null
+++ b/examples/webenginewidgets/cookiebrowser/doc/images/cookiebrowser.png
Binary files differ
diff --git a/examples/webenginewidgets/cookiebrowser/doc/src/cookiebrowser.qdoc b/examples/webenginewidgets/cookiebrowser/doc/src/cookiebrowser.qdoc
new file mode 100644
index 000000000..259de0724
--- /dev/null
+++ b/examples/webenginewidgets/cookiebrowser/doc/src/cookiebrowser.qdoc
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example webenginewidgets/cookiebrowser
+ \title WebEngine Cookie Browser Example
+ \ingroup webengine-widgetexamples
+ \brief A cookie browser based on Qt WebEngine Widgets
+
+ \image cookiebrowser.png
+
+ \e {Cookie Browser} demonstrates how to use the \l{Qt WebEngine Widgets C++ Classes}
+ {Qt WebEngine C++ classes} to manage cookies. The browser can be used to view cookie content as
+ well as delete cookies and add new cookies.
+
+ \include examples-run.qdocinc
+*/
diff --git a/examples/webenginewidgets/cookiebrowser/main.cpp b/examples/webenginewidgets/cookiebrowser/main.cpp
new file mode 100644
index 000000000..c122eb7c3
--- /dev/null
+++ b/examples/webenginewidgets/cookiebrowser/main.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+#include <QApplication>
+#include <QUrl>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ MainWindow window(QUrl("http://qt.io"));
+ window.show();
+ return app.exec();
+}
diff --git a/examples/webenginewidgets/cookiebrowser/mainwindow.cpp b/examples/webenginewidgets/cookiebrowser/mainwindow.cpp
new file mode 100644
index 000000000..4139153c9
--- /dev/null
+++ b/examples/webenginewidgets/cookiebrowser/mainwindow.cpp
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+#include <QWebEngineCookieStore>
+#include <QWebEngineProfile>
+
+CookieDialog::CookieDialog(const QNetworkCookie &cookie, QWidget *parent): QDialog(parent)
+{
+ setupUi(this);
+ m_nameLineEdit->setText(cookie.name());
+ m_domainLineEdit->setText(cookie.domain());
+ m_valueLineEdit->setText(cookie.value());
+ m_pathLineEdit->setText(cookie.path());
+ m_dateEdit->setDate(cookie.expirationDate().date());
+ m_isSecureComboBox->addItem(cookie.isSecure() ? tr("yes") : tr("no"));
+ m_isHttpOnlyComboBox->addItem(cookie.isHttpOnly() ? tr("yes") : tr("no"));
+ m_addButton->setVisible(false);
+ m_cancelButton->setText(tr("Close"));
+}
+
+CookieDialog::CookieDialog(QWidget *parent): QDialog(parent)
+{
+ setupUi(this);
+ m_nameLineEdit->setReadOnly(false);
+ m_domainLineEdit->setReadOnly(false);
+ m_valueLineEdit->setReadOnly(false);
+ m_pathLineEdit->setReadOnly(false);
+ m_dateEdit->setReadOnly(false);
+ m_dateEdit->setDate(QDateTime::currentDateTime().addYears(1).date());
+ m_isSecureComboBox->addItem(tr("no"));
+ m_isSecureComboBox->addItem(tr("yes"));
+ m_isHttpOnlyComboBox->addItem(tr("no"));
+ m_isHttpOnlyComboBox->addItem(tr("yes"));
+}
+
+QNetworkCookie CookieDialog::cookie()
+{
+ QNetworkCookie cookie;
+ cookie.setDomain(m_domainLineEdit->text());
+ cookie.setName(m_nameLineEdit->text().toLatin1());
+ cookie.setValue(m_valueLineEdit->text().toLatin1());
+ cookie.setExpirationDate(QDateTime(m_dateEdit->date()));
+ cookie.setPath(m_pathLineEdit->text());
+ cookie.setSecure(m_isSecureComboBox->currentText() == tr("yes"));
+ cookie.setHttpOnly(m_isHttpOnlyComboBox->currentText() == tr("yes"));
+ return cookie;
+}
+
+CookieWidget::CookieWidget(const QNetworkCookie &cookie, QWidget *parent): QWidget(parent)
+{
+ setupUi(this);
+ setAutoFillBackground(true);
+ m_nameLabel->setText(cookie.name());
+ m_domainLabel->setText(cookie.domain());
+ connect(m_viewButton, &QPushButton::clicked, this, &CookieWidget::viewClicked);
+ connect(m_deleteButton, &QPushButton::clicked, this, &CookieWidget::deleteClicked);
+}
+
+void CookieWidget::setHighlighted(bool enabled)
+{
+ QPalette p = palette();
+ p.setColor(backgroundRole(), enabled ? QColor(0xF0, 0xF8, 0xFF) : Qt::white);
+ setPalette(p);
+}
+
+MainWindow::MainWindow(const QUrl &url) :
+ QMainWindow(),
+ m_store(nullptr),
+ m_layout(new QVBoxLayout)
+{
+ setupUi(this);
+ m_urlLineEdit->setText(url.toString());
+
+ m_layout->addItem(new QSpacerItem(0,0, QSizePolicy::Minimum, QSizePolicy::Expanding));
+ m_layout->setContentsMargins(0, 0, 0, 0);
+ m_layout->setSpacing(0);
+
+ QWidget *w = new QWidget();
+ QPalette p = w->palette();
+ p.setColor(widget->backgroundRole(), Qt::white);
+ w->setPalette(p);
+ w->setLayout(m_layout);
+
+ m_scrollArea->setWidget(w);
+ m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+
+ connect(m_urlButton, &QPushButton::clicked, this, &MainWindow::handleUrlClicked);
+ connect(m_deleteAllButton, &QPushButton::clicked, this, &MainWindow::handleDeleteAllClicked);
+ connect(m_newButton, &QPushButton::clicked, this, &MainWindow::handleNewClicked);
+
+ m_store = m_webview->page()->profile()->cookieStore();
+ connect(m_store, &QWebEngineCookieStore::cookieAdded, this, &MainWindow::handleCookieAdded);
+ m_store->loadAllCookies();
+ m_webview->load(url);
+}
+
+bool MainWindow::containsCookie(const QNetworkCookie &cookie)
+{
+ for (auto c: m_cookies) {
+ if (c.hasSameIdentifier(cookie))
+ return true;
+ }
+ return false;
+}
+
+void MainWindow::handleCookieAdded(const QNetworkCookie &cookie)
+{
+ // only new cookies
+ if (containsCookie(cookie))
+ return;
+
+ CookieWidget *widget = new CookieWidget(cookie);
+ widget->setHighlighted(m_cookies.count() % 2);
+ m_cookies.append(cookie);
+ m_layout->insertWidget(0,widget);
+
+ connect(widget, &CookieWidget::deleteClicked, [this, cookie, widget]() {
+ m_store->deleteCookie(cookie);
+ delete widget;
+ m_cookies.removeOne(cookie);
+ for (int i = 0; i < m_layout->count() - 1; i++) {
+ // fix background colors
+ auto widget = qobject_cast<CookieWidget*>(m_layout->itemAt(i)->widget());
+ widget->setHighlighted(i % 2);
+ }
+ });
+
+ connect(widget, &CookieWidget::viewClicked, [cookie]() {
+ CookieDialog dialog(cookie);
+ dialog.exec();
+ });
+}
+
+void MainWindow::handleDeleteAllClicked()
+{
+ m_store->deleteAllCookies();
+ for (int i = m_layout->count() - 1; i >= 0; i--)
+ delete m_layout->itemAt(i)->widget();
+ m_cookies.clear();
+}
+
+void MainWindow::handleNewClicked()
+{
+ CookieDialog dialog;
+ if (dialog.exec() == QDialog::Accepted)
+ m_store->setCookie(dialog.cookie());
+}
+
+void MainWindow::handleUrlClicked()
+{
+ m_webview->load(QUrl(m_urlLineEdit->text()));
+}
diff --git a/examples/webenginewidgets/cookiebrowser/mainwindow.h b/examples/webenginewidgets/cookiebrowser/mainwindow.h
new file mode 100644
index 000000000..93d0a5a31
--- /dev/null
+++ b/examples/webenginewidgets/cookiebrowser/mainwindow.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include "ui_mainwindow.h"
+#include "ui_cookiewidget.h"
+#include "ui_cookiedialog.h"
+#include <QNetworkCookie>
+#include <QMainWindow>
+
+QT_BEGIN_NAMESPACE
+class QWebEngineCookieStore;
+QT_END_NAMESPACE
+
+class CookieDialog : public QDialog, public Ui_CookieDialog
+{
+ Q_OBJECT
+public:
+ CookieDialog(const QNetworkCookie &cookie, QWidget *parent = nullptr);
+ CookieDialog(QWidget *parent = 0);
+ QNetworkCookie cookie();
+};
+
+class CookieWidget : public QWidget, public Ui_CookieWidget
+{
+ Q_OBJECT
+public:
+ CookieWidget(const QNetworkCookie &cookie, QWidget *parent = nullptr);
+ void setHighlighted(bool enabled);
+signals:
+ void deleteClicked();
+ void viewClicked();
+};
+
+class MainWindow : public QMainWindow, public Ui_MainWindow
+{
+ Q_OBJECT
+public:
+ explicit MainWindow(const QUrl &url);
+
+private:
+ bool containsCookie(const QNetworkCookie &cookie);
+
+private slots:
+ void handleCookieAdded(const QNetworkCookie &cookie);
+ void handleDeleteAllClicked();
+ void handleNewClicked();
+ void handleUrlClicked();
+
+private:
+ QWebEngineCookieStore *m_store;
+ QVector<QNetworkCookie> m_cookies;
+ QVBoxLayout *m_layout;
+};
+
+#endif // MAINWINDOW_H
diff --git a/examples/webenginewidgets/cookiebrowser/mainwindow.ui b/examples/webenginewidgets/cookiebrowser/mainwindow.ui
new file mode 100644
index 000000000..78d451396
--- /dev/null
+++ b/examples/webenginewidgets/cookiebrowser/mainwindow.ui
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1400</width>
+ <height>650</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Cookie Manager</string>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QFrame" name="frame">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QWidget" name="widget" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="m_urlLineEdit"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="m_urlButton">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="cookiebrowser.qrc">
+ <normaloff>:/view-refresh.png</normaloff>:/view-refresh.png</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWebEngineView" name="m_webview" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="frame_2">
+ <property name="maximumSize">
+ <size>
+ <width>336</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QWidget" name="widget_2" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Cookies:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>87</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="m_newButton">
+ <property name="text">
+ <string>New</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="m_deleteAllButton">
+ <property name="text">
+ <string>Delete All</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QScrollArea" name="m_scrollArea">
+ <property name="minimumSize">
+ <size>
+ <width>320</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>320</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <customwidgets>
+ <customwidget>
+ <class>QWebEngineView</class>
+ <extends>QWidget</extends>
+ <header>qwebengineview.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources>
+ <include location="cookiebrowser.qrc"/>
+ </resources>
+ <connections>
+ <connection>
+ <sender>m_urlLineEdit</sender>
+ <signal>returnPressed()</signal>
+ <receiver>m_urlButton</receiver>
+ <slot>click()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>509</x>
+ <y>28</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>1024</x>
+ <y>27</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/examples/webenginewidgets/cookiebrowser/view-refresh.png b/examples/webenginewidgets/cookiebrowser/view-refresh.png
new file mode 100644
index 000000000..cab4d02c7
--- /dev/null
+++ b/examples/webenginewidgets/cookiebrowser/view-refresh.png
Binary files differ
diff --git a/src/3rdparty b/src/3rdparty
-Subproject 1334c7619425f44b0473c1c808ed1005fdb3e2a
+Subproject f8c56902fad36d8b43902d81ddc585e543c31b4
diff --git a/src/core/api/qwebenginecookiestore.cpp b/src/core/api/qwebenginecookiestore.cpp
index 136fef9d2..06912ce92 100644
--- a/src/core/api/qwebenginecookiestore.cpp
+++ b/src/core/api/qwebenginecookiestore.cpp
@@ -194,38 +194,6 @@ void QWebEngineCookieStorePrivate::onCookieChanged(const QNetworkCookie &cookie,
*/
/*!
- \class QWebEngineCookieStore::FilterRequest
- \inmodule QtWebEngineCore
- \since 5.6
- \brief The FilterRequest class specifies the properties of a cookie.
-
- The class specifies the properties of a cookie and determines whether the cookie should be
- accepted. The class is used as an argument to a filter installed via setCookieFilter().
-*/
-
-/*!
- \variable QWebEngineCookieStore::FilterRequest::accepted
- \brief Whether the cookie shall be accepted.
-
- The default is \c true.
-*/
-
-/*!
- \variable QWebEngineCookieStore::FilterRequest::firstPartyUrl
- \brief The URL of the page that triggered the setting of the cookie.
-*/
-
-/*!
- \variable QWebEngineCookieStore::FilterRequest::cookieLine
- \brief The content of the cookie.
-*/
-
-/*!
- \variable QWebEngineCookieStore::FilterRequest::cookieSource
- \brief The URL of the site that sets the cookie.
-*/
-
-/*!
\fn void QWebEngineCookieStore::cookieAdded(const QNetworkCookie &cookie)
This signal is emitted whenever a new \a cookie is added to the cookie store.
diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp
index c286cb709..7325b131e 100644
--- a/src/core/api/qwebengineurlrequestinfo.cpp
+++ b/src/core/api/qwebengineurlrequestinfo.cpp
@@ -104,13 +104,11 @@ ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::OtherNavigation, Q
*/
/*!
- \fn bool QWebEngineUrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info)
+ \fn void QWebEngineUrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info)
Reimplementing this virtual function and setting the interceptor on a profile makes
it possible to intercept URL requests. This function is executed on the IO thread,
and therefore running long tasks here will block networking.
- If this function is only used for inspection, it should return \c false, in which
- case any modification to \a info will be ignored.
\sa QWebEngineProfile::setRequestInterceptor
*/
diff --git a/src/core/api/qwebengineurlrequestjob.h b/src/core/api/qwebengineurlrequestjob.h
index 8801e6bc0..afa542d7e 100644
--- a/src/core/api/qwebengineurlrequestjob.h
+++ b/src/core/api/qwebengineurlrequestjob.h
@@ -47,8 +47,8 @@
#include <QtCore/qurl.h>
namespace QtWebEngineCore {
-class URLRequestCustomJob;
class URLRequestCustomJobDelegate;
+class URLRequestCustomJobShared;
} // namespace
QT_BEGIN_NAMESPACE
@@ -79,7 +79,7 @@ public:
private:
QWebEngineUrlRequestJob(QtWebEngineCore::URLRequestCustomJobDelegate *);
- friend class QtWebEngineCore::URLRequestCustomJob;
+ friend class QtWebEngineCore::URLRequestCustomJobShared;
QtWebEngineCore::URLRequestCustomJobDelegate* d_ptr;
};
diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp
index 94770f0bb..dea845e68 100644
--- a/src/core/browser_context_adapter.cpp
+++ b/src/core/browser_context_adapter.cpp
@@ -357,7 +357,7 @@ QHash<QByteArray, QWebEngineUrlSchemeHandler *> &BrowserContextAdapter::customUr
void BrowserContextAdapter::updateCustomUrlSchemeHandlers()
{
if (m_browserContext->url_request_getter_.get())
- m_browserContext->url_request_getter_->updateStorageSettings();
+ m_browserContext->url_request_getter_->updateJobFactory();
}
bool BrowserContextAdapter::removeCustomUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler)
diff --git a/src/core/config/common.pri b/src/core/config/common.pri
new file mode 100644
index 000000000..c5921a573
--- /dev/null
+++ b/src/core/config/common.pri
@@ -0,0 +1,10 @@
+# Shared configuration for all our supported platforms
+
+# Trigger Qt-specific build conditions.
+GYP_CONFIG += use_qt=1
+# We do not want to ship more external binary blobs, so let v8 embed its startup data.
+GYP_CONFIG += v8_use_external_startup_data=0
+# Disable printing since we don't support it yet
+GYP_CONFIG += enable_basic_printing=0 enable_print_preview=0
+# WebSpeech requires Google API keys and adds dependencies on speex and flac.
+GYP_CONFIG += enable_web_speech=0
diff --git a/src/core/config/embedded_qnx.pri b/src/core/config/embedded_qnx.pri
index 7fd35c976..34470d2d8 100644
--- a/src/core/config/embedded_qnx.pri
+++ b/src/core/config/embedded_qnx.pri
@@ -1,5 +1,7 @@
GYP_ARGS += "-D qt_os=\"embedded_qnx\" -I config/embedded_qnx.gypi"
+include(common.pri)
+
GYP_CONFIG += \
disable_nacl=1 \
enable_plugins=0 \
diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri
index f2883bc32..2fa6aa5c6 100644
--- a/src/core/config/linux.pri
+++ b/src/core/config/linux.pri
@@ -1,3 +1,5 @@
+include(common.pri)
+
# linux_use_bundled_gold currently relies on a hardcoded relative path from chromium/src/out/(Release|Debug)
# Disable it along with the -Wl,--threads flag just in case gold isn't installed on the system.
GYP_CONFIG += \
@@ -37,7 +39,6 @@ use?(system_libevent): GYP_CONFIG += use_system_libevent=1
use?(system_libwebp): GYP_CONFIG += use_system_libwebp=1
use?(system_libsrtp): GYP_CONFIG += use_system_libsrtp=1
use?(system_libxslt): GYP_CONFIG += use_system_libxml=1
-use?(system_flac): GYP_CONFIG += use_system_flac=1
use?(system_jsoncpp): GYP_CONFIG += use_system_jsoncpp=1
use?(system_opus): GYP_CONFIG += use_system_opus=1
use?(system_snappy): GYP_CONFIG += use_system_snappy=1
diff --git a/src/core/config/mac_osx.pri b/src/core/config/mac_osx.pri
index f11dba1b7..dd2affca9 100644
--- a/src/core/config/mac_osx.pri
+++ b/src/core/config/mac_osx.pri
@@ -1,3 +1,5 @@
+include(common.pri)
+
QMAKE_CLANG_DIR = "/usr"
QMAKE_CLANG_PATH = $$eval(QMAKE_MAC_SDK.macx-clang.$${QMAKE_MAC_SDK}.QMAKE_CXX)
!isEmpty(QMAKE_CLANG_PATH) {
diff --git a/src/core/config/windows.pri b/src/core/config/windows.pri
index 153a4fe72..ab4037d1f 100644
--- a/src/core/config/windows.pri
+++ b/src/core/config/windows.pri
@@ -1,5 +1,7 @@
GYP_ARGS += "-D qt_os=\"win32\" -I config/windows.gypi"
+include(common.pri)
+
GYP_CONFIG += \
disable_nacl=1 \
remoting=0 \
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index 83b9b7a41..d14e13137 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -150,13 +150,14 @@ void AddPepperFlashFromSystem(std::vector<content::PepperPluginInfo>* plugins)
pluginPaths << ppapiPluginsPath() + QStringLiteral("/PepperFlashPlayer.plugin");
#endif
#if defined(Q_OS_LINUX)
- pluginPaths << "/usr/lib/pepperflashplugin-nonfree/libpepflashplayer.so" // Ubuntu
+ pluginPaths << "/opt/google/chrome/PepperFlash/libpepflashplayer.so" // Google Chrome
+ << "/usr/lib/pepperflashplugin-nonfree/libpepflashplayer.so" // Ubuntu
<< "/usr/lib/PepperFlash/libpepflashplayer.so" // Arch
<< "/usr/lib64/chromium/PepperFlash/libpepflashplayer.so"; // OpenSuSE
pluginPaths << ppapiPluginsPath() + QStringLiteral("/libpepflashplayer.so");
#endif
for (auto it = pluginPaths.constBegin(); it != pluginPaths.constEnd(); ++it) {
- if (!QFile(*it).exists())
+ if (!QFile::exists(*it))
continue;
plugins->push_back(CreatePepperFlashInfo(QtWebEngineCore::toFilePath(*it), std::string()));
}
@@ -165,7 +166,7 @@ void AddPepperFlashFromSystem(std::vector<content::PepperPluginInfo>* plugins)
void AddPepperFlashFromCommandLine(std::vector<content::PepperPluginInfo>* plugins)
{
const base::CommandLine::StringType flash_path = base::CommandLine::ForCurrentProcess()->GetSwitchValueNative(switches::kPpapiFlashPath);
- if (flash_path.empty() || !QFile(QtWebEngineCore::toQt(flash_path)).exists())
+ if (flash_path.empty() || !QFile::exists(QtWebEngineCore::toQt(flash_path)))
return;
// Read pepper flash plugin version from command-line. (e.g. 16.0.0.235)
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index ef6921dd5..f30af83fc 100644
--- a/src/core/core_module.pro
+++ b/src/core/core_module.pro
@@ -78,13 +78,22 @@ icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat
}
!contains(QT_CONFIG, qt_framework): contains(QT_CONFIG, private_tests) {
- ICU_TARGET = $$shell_path($$[QT_INSTALL_DATA/get]/resources/icudtl.dat)
- ICU_FILE = $$shell_path($$OUT_PWD/$$getConfigDir()/icudtl.dat)
- icu_rule.target = $$ICU_TARGET
- unix: icu_rule.commands = if [ -e $$ICU_FILE ] ; then $$QMAKE_COPY $$ICU_FILE $$ICU_TARGET ; fi
- win32: icu_rule.commands = if exist $$ICU_FILE ( $$QMAKE_COPY $$ICU_FILE $$ICU_TARGET )
-
- QMAKE_EXTRA_TARGETS += icu_rule
- PRE_TARGETDEPS += $$ICU_TARGET
+ #
+ # Copy essential files to the qtbase build directory (for non-installed developer builds)
+ #
+
+ icudt2build.input = icu.files
+ icudt2build.output = $$[QT_INSTALL_DATA/get]/resources/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
+ icudt2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
+ icudt2build.name = COPY ${QMAKE_FILE_IN}
+ icudt2build.CONFIG = no_link no_clean target_predeps
+
+ resources2build.input = resources.files
+ resources2build.output = $$[QT_INSTALL_DATA/get]/resources/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
+ resources2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
+ resources2build.name = COPY ${QMAKE_FILE_IN}
+ resources2build.CONFIG = no_link no_clean target_predeps
+
+ QMAKE_EXTRA_COMPILERS += icudt2build resources2build
}
}
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 3a5a8aa6b..308a99fd3 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -826,7 +826,9 @@ void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEve
if (!m_gestureProvider.OnTouchEvent(motionEvent).succeeded)
return;
- blink::WebTouchEvent touchEvent = ui::CreateWebTouchEventFromMotionEvent(motionEvent, false);
+ bool causesScrollingIfUncancelled = true;
+ blink::WebTouchEvent touchEvent = ui::CreateWebTouchEventFromMotionEvent(motionEvent,
+ causesScrollingIfUncancelled);
m_host->ForwardTouchEventWithLatencyInfo(touchEvent, CreateLatencyInfo(touchEvent));
}
diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp
index afb3c231e..bcbc5f4ef 100644
--- a/src/core/url_request_context_getter_qt.cpp
+++ b/src/core/url_request_context_getter_qt.cpp
@@ -131,8 +131,9 @@ void URLRequestContextGetterQt::updateStorageSettings()
content::BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
content::BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)
));
- if (m_storage)
+ if (m_storage) {
content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateStorage, this));
+ }
}
}
@@ -287,7 +288,7 @@ void URLRequestContextGetterQt::generateUserAgent()
Q_ASSERT(m_urlRequestContext);
Q_ASSERT(m_storage);
- m_storage->set_http_user_agent_settings(scoped_ptr<net::HttpUserAgentSettings>(new HttpUserAgentSettingsQt(m_browserContext)));
+ m_storage->set_http_user_agent_settings(scoped_ptr<net::HttpUserAgentSettings>(new HttpUserAgentSettingsQt(m_browserContext.constData())));
}
void URLRequestContextGetterQt::updateHttpCache()
@@ -298,6 +299,13 @@ void URLRequestContextGetterQt::updateHttpCache()
}
}
+void URLRequestContextGetterQt::updateJobFactory()
+{
+ Q_ASSERT(m_jobFactory);
+
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateJobFactory, this));
+}
+
static bool doNetworkSessionParamsMatch(const net::HttpNetworkSession::Params &first, const net::HttpNetworkSession::Params &second)
{
if (first.transport_security_state != second.transport_security_state)
@@ -413,8 +421,8 @@ void URLRequestContextGetterQt::clearCurrentCacheBackend()
void URLRequestContextGetterQt::generateJobFactory()
{
Q_ASSERT(m_urlRequestContext);
- Q_ASSERT(!m_jobFactory);
+ m_jobFactory.reset();
scoped_ptr<net::URLRequestJobFactoryImpl> jobFactory(new net::URLRequestJobFactoryImpl());
{
@@ -422,7 +430,6 @@ void URLRequestContextGetterQt::generateJobFactory()
content::ProtocolHandlerMap::iterator it = m_protocolHandlers.find(url::kBlobScheme);
Q_ASSERT(it != m_protocolHandlers.end());
jobFactory->SetProtocolHandler(it->first, scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(it->second.release()));
- m_protocolHandlers.clear();
}
jobFactory->SetProtocolHandler(url::kDataScheme, scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(new net::DataProtocolHandler()));
diff --git a/src/core/url_request_context_getter_qt.h b/src/core/url_request_context_getter_qt.h
index 4adbefef7..8d911e4d4 100644
--- a/src/core/url_request_context_getter_qt.h
+++ b/src/core/url_request_context_getter_qt.h
@@ -81,6 +81,7 @@ public:
void updateCookieStore();
void updateHttpCache();
void clearHttpCache();
+ void updateJobFactory();
private:
virtual ~URLRequestContextGetterQt();
@@ -98,7 +99,7 @@ private:
bool m_ignoreCertificateErrors;
QAtomicInt m_updateCookieStore;
QAtomicInt m_updateHttpCache;
- BrowserContextAdapter *m_browserContext;
+ QExplicitlySharedDataPointer<BrowserContextAdapter> m_browserContext;
content::ProtocolHandlerMap m_protocolHandlers;
QAtomicPointer<net::ProxyConfigService> m_proxyConfigService;
diff --git a/src/core/url_request_custom_job.cpp b/src/core/url_request_custom_job.cpp
index 5bb29bcc3..f8a47b2b1 100644
--- a/src/core/url_request_custom_job.cpp
+++ b/src/core/url_request_custom_job.cpp
@@ -59,46 +59,33 @@ namespace QtWebEngineCore {
URLRequestCustomJob::URLRequestCustomJob(URLRequest *request, NetworkDelegate *networkDelegate, QWebEngineUrlSchemeHandler *schemeHandler)
: URLRequestJob(request, networkDelegate)
- , m_device(0)
, m_schemeHandler(schemeHandler)
- , m_error(0)
- , m_started(false)
- , m_weakFactoryIO(this)
- , m_weakFactoryUI(this)
+ , m_shared(new URLRequestCustomJobShared(this))
{
}
URLRequestCustomJob::~URLRequestCustomJob()
{
- QMutexLocker lock(&m_mutex);
- if (m_delegate) {
- m_delegate->m_job = 0;
- m_delegate->deleteLater();
- }
- if (m_device && m_device->isOpen())
- m_device->close();
+ if (m_shared)
+ m_shared->killJob();
+}
+
+static void startAsync(URLRequestCustomJobShared *shared)
+{
+ shared->startAsync();
}
void URLRequestCustomJob::Start()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, base::Bind(&URLRequestCustomJob::startAsync, m_weakFactoryIO.GetWeakPtr()));
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, base::Bind(&startAsync, m_shared));
}
void URLRequestCustomJob::Kill()
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- QMutexLocker lock(&m_mutex);
- if (m_delegate) {
- m_delegate->m_job = 0;
- m_delegate->deleteLater();
- }
- m_delegate = 0;
- if (m_device && m_device->isOpen())
- m_device->close();
- m_device = 0;
- m_weakFactoryIO.InvalidateWeakPtrs();
- m_weakFactoryUI.InvalidateWeakPtrs();
+ if (m_shared)
+ m_shared->killJob();
+ m_shared = 0;
URLRequestJob::Kill();
}
@@ -106,8 +93,11 @@ void URLRequestCustomJob::Kill()
bool URLRequestCustomJob::GetMimeType(std::string *mimeType) const
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (m_mimeType.size() > 0) {
- *mimeType = m_mimeType;
+ if (!m_shared)
+ return false;
+ QMutexLocker lock(&m_shared->m_mutex);
+ if (m_shared->m_mimeType.size() > 0) {
+ *mimeType = m_shared->m_mimeType;
return true;
}
return false;
@@ -116,8 +106,11 @@ bool URLRequestCustomJob::GetMimeType(std::string *mimeType) const
bool URLRequestCustomJob::GetCharset(std::string* charset)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (m_charset.size() > 0) {
- *charset = m_charset;
+ if (!m_shared)
+ return false;
+ QMutexLocker lock(&m_shared->m_mutex);
+ if (m_shared->m_charset.size() > 0) {
+ *charset = m_shared->m_charset;
return true;
}
return false;
@@ -126,124 +119,223 @@ bool URLRequestCustomJob::GetCharset(std::string* charset)
bool URLRequestCustomJob::IsRedirectResponse(GURL* location, int* http_status_code)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- QMutexLocker lock(&m_mutex);
- if (m_redirect.is_valid()) {
- *location = m_redirect;
+ if (!m_shared)
+ return false;
+ QMutexLocker lock(&m_shared->m_mutex);
+ if (m_shared->m_redirect.is_valid()) {
+ *location = m_shared->m_redirect;
*http_status_code = 303;
return true;
}
return false;
}
-void URLRequestCustomJob::setReplyMimeType(const std::string &mimeType)
+bool URLRequestCustomJob::ReadRawData(IOBuffer *buf, int bufSize, int *bytesRead)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ Q_ASSERT(bytesRead);
+ Q_ASSERT(m_shared);
+ QMutexLocker lock(&m_shared->m_mutex);
+ qint64 rv = m_shared->m_device ? m_shared->m_device->read(buf->data(), bufSize) : -1;
+ if (rv >= 0) {
+ *bytesRead = static_cast<int>(rv);
+ return true;
+ } else {
+ NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, ERR_FAILED));
+ }
+ return false;
+}
+
+URLRequestCustomJobShared::URLRequestCustomJobShared(URLRequestCustomJob *job)
+ : m_mutex(QMutex::Recursive)
+ , m_job(job)
+ , m_delegate(0)
+ , m_error(0)
+ , m_started(false)
+ , m_asyncInitialized(false)
+ , m_weakFactory(this)
+{
+}
+
+URLRequestCustomJobShared::~URLRequestCustomJobShared()
+{
+ Q_ASSERT(!m_job);
+ Q_ASSERT(!m_delegate);
+}
+
+void URLRequestCustomJobShared::killJob()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ QMutexLocker lock(&m_mutex);
+ m_job = 0;
+ bool doDelete = false;
+ if (m_delegate) {
+ m_delegate->deleteLater();
+ } else {
+ // Do not delete yet if startAsync has not yet run.
+ doDelete = m_asyncInitialized;
+ }
+ if (m_device && m_device->isOpen())
+ m_device->close();
+ m_device = 0;
+ m_weakFactory.InvalidateWeakPtrs();
+ lock.unlock();
+ if (doDelete)
+ delete this;
+}
+
+void URLRequestCustomJobShared::unsetJobDelegate()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ QMutexLocker lock(&m_mutex);
+ m_delegate = 0;
+ bool doDelete = false;
+ if (m_job)
+ abort();
+ else
+ doDelete = true;
+ lock.unlock();
+ if (doDelete)
+ delete this;
+}
+
+void URLRequestCustomJobShared::setReplyMimeType(const std::string &mimeType)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ QMutexLocker lock(&m_mutex);
m_mimeType = mimeType;
}
-void URLRequestCustomJob::setReplyCharset(const std::string &charset)
+void URLRequestCustomJobShared::setReplyCharset(const std::string &charset)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ QMutexLocker lock(&m_mutex);
m_charset = charset;
}
-void URLRequestCustomJob::setReplyDevice(QIODevice *device)
+void URLRequestCustomJobShared::setReplyDevice(QIODevice *device)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
QMutexLocker lock(&m_mutex);
+ if (!m_job)
+ return;
m_device = device;
if (m_device && !m_device->isReadable())
m_device->open(QIODevice::ReadOnly);
if (m_device && m_device->isReadable())
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJob::notifyStarted, m_weakFactoryUI.GetWeakPtr()));
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyStarted, m_weakFactory.GetWeakPtr()));
else
fail(ERR_INVALID_URL);
}
-bool URLRequestCustomJob::ReadRawData(IOBuffer *buf, int bufSize, int *bytesRead)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- Q_ASSERT(bytesRead);
- QMutexLocker lock(&m_mutex);
- qint64 rv = m_device ? m_device->read(buf->data(), bufSize) : -1;
- if (rv >= 0) {
- *bytesRead = static_cast<int>(rv);
- return true;
- } else {
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, ERR_FAILED));
- }
- return false;
-}
-
-void URLRequestCustomJob::redirect(const GURL &url)
+void URLRequestCustomJobShared::redirect(const GURL &url)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- if (m_device || m_error)
- return;
QMutexLocker lock(&m_mutex);
+ if (m_device || m_error)
+ return;
+ if (!m_job)
+ return;
m_redirect = url;
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJob::notifyStarted, m_weakFactoryUI.GetWeakPtr()));
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyStarted, m_weakFactory.GetWeakPtr()));
}
-void URLRequestCustomJob::abort()
+void URLRequestCustomJobShared::abort()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
QMutexLocker lock(&m_mutex);
if (m_device && m_device->isOpen())
m_device->close();
m_device = 0;
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJob::notifyCanceled, m_weakFactoryUI.GetWeakPtr()));
+ if (!m_job)
+ return;
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyCanceled, m_weakFactory.GetWeakPtr()));
}
-void URLRequestCustomJob::notifyCanceled()
+void URLRequestCustomJobShared::notifyCanceled()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ QMutexLocker lock(&m_mutex);
+ if (!m_job)
+ return;
if (m_started)
- NotifyDone(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED));
+ m_job->NotifyDone(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED));
else
- NotifyStartError(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED));
+ m_job->NotifyStartError(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED));
}
-void URLRequestCustomJob::notifyStarted()
+void URLRequestCustomJobShared::notifyStarted()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ QMutexLocker lock(&m_mutex);
+ if (!m_job)
+ return;
Q_ASSERT(!m_started);
m_started = true;
- NotifyHeadersComplete();
+ m_job->NotifyHeadersComplete();
}
-void URLRequestCustomJob::fail(int error)
+void URLRequestCustomJobShared::fail(int error)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
QMutexLocker lock(&m_mutex);
m_error = error;
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJob::notifyFailure, m_weakFactoryUI.GetWeakPtr()));
+ if (!m_job)
+ return;
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyFailure, m_weakFactory.GetWeakPtr()));
}
-void URLRequestCustomJob::notifyFailure()
+void URLRequestCustomJobShared::notifyFailure()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
QMutexLocker lock(&m_mutex);
+ if (!m_job)
+ return;
if (m_device)
m_device->close();
- if (m_started)
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, m_error));
+ const URLRequestStatus status(URLRequestStatus::FAILED, m_error);
+ const bool started = m_started;
+
+ if (started)
+ m_job->NotifyDone(status);
else
- NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, m_error));
+ m_job->NotifyStartError(status);
}
-void URLRequestCustomJob::startAsync()
+GURL URLRequestCustomJobShared::requestUrl()
+{
+ QMutexLocker lock(&m_mutex);
+ if (!m_job)
+ return GURL();
+ return m_job->request()->url();
+}
+
+std::string URLRequestCustomJobShared::requestMethod()
+{
+ QMutexLocker lock(&m_mutex);
+ if (!m_job)
+ return std::string();
+ return m_job->request()->method();
+}
+
+void URLRequestCustomJobShared::startAsync()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
Q_ASSERT(!m_started);
Q_ASSERT(!m_delegate);
QMutexLocker lock(&m_mutex);
+ if (!m_job) {
+ lock.unlock();
+ delete this;
+ return;
+ }
m_delegate = new URLRequestCustomJobDelegate(this);
- lock.unlock();
+ m_asyncInitialized = true;
QWebEngineUrlRequestJob *requestJob = new QWebEngineUrlRequestJob(m_delegate);
- m_schemeHandler->requestStarted(requestJob);
+ if (m_job)
+ m_job->m_schemeHandler->requestStarted(requestJob);
}
} // namespace
diff --git a/src/core/url_request_custom_job.h b/src/core/url_request_custom_job.h
index e6063f485..98e2478c4 100644
--- a/src/core/url_request_custom_job.h
+++ b/src/core/url_request_custom_job.h
@@ -53,6 +53,7 @@ QT_FORWARD_DECLARE_CLASS(QWebEngineUrlSchemeHandler)
namespace QtWebEngineCore {
class URLRequestCustomJobDelegate;
+class URLRequestCustomJobShared;
// A request job that handles reading custom URL schemes
class URLRequestCustomJob : public net::URLRequestJob {
@@ -65,6 +66,25 @@ public:
virtual bool GetCharset(std::string *charset) Q_DECL_OVERRIDE;
virtual bool IsRedirectResponse(GURL* location, int* http_status_code) Q_DECL_OVERRIDE;
+protected:
+ virtual ~URLRequestCustomJob();
+
+private:
+ QWebEngineUrlSchemeHandler *m_schemeHandler;
+ URLRequestCustomJobShared *m_shared;
+
+ friend class URLRequestCustomJobShared;
+
+ DISALLOW_COPY_AND_ASSIGN(URLRequestCustomJob);
+};
+
+// A shared state between URLRequestCustomJob living on the IO thread
+// and URLRequestCustomJobDelegate living on the UI thread.
+class URLRequestCustomJobShared {
+public:
+ URLRequestCustomJobShared(URLRequestCustomJob *job);
+ ~URLRequestCustomJobShared();
+
void setReplyMimeType(const std::string &);
void setReplyCharset(const std::string &);
void setReplyDevice(QIODevice *);
@@ -73,29 +93,28 @@ public:
void fail(int);
void abort();
-protected:
- virtual ~URLRequestCustomJob();
+ void killJob();
+ void unsetJobDelegate();
+
void startAsync();
void notifyStarted();
void notifyFailure();
void notifyCanceled();
-private:
+ GURL requestUrl();
+ std::string requestMethod();
+
QMutex m_mutex;
QPointer<QIODevice> m_device;
- QPointer<URLRequestCustomJobDelegate> m_delegate;
- QWebEngineUrlSchemeHandler *m_schemeHandler;
+ URLRequestCustomJob *m_job;
+ URLRequestCustomJobDelegate *m_delegate;
std::string m_mimeType;
std::string m_charset;
int m_error;
GURL m_redirect;
bool m_started;
- base::WeakPtrFactory<URLRequestCustomJob> m_weakFactoryIO;
- base::WeakPtrFactory<URLRequestCustomJob> m_weakFactoryUI;
-
- friend class URLRequestCustomJobDelegate;
-
- DISALLOW_COPY_AND_ASSIGN(URLRequestCustomJob);
+ bool m_asyncInitialized;
+ base::WeakPtrFactory<URLRequestCustomJobShared> m_weakFactory;
};
} // namespace QtWebEngineCore
diff --git a/src/core/url_request_custom_job_delegate.cpp b/src/core/url_request_custom_job_delegate.cpp
index f0026bef3..7e806a4e0 100644
--- a/src/core/url_request_custom_job_delegate.cpp
+++ b/src/core/url_request_custom_job_delegate.cpp
@@ -47,39 +47,40 @@
namespace QtWebEngineCore {
-URLRequestCustomJobDelegate::URLRequestCustomJobDelegate(URLRequestCustomJob *job)
- : m_job(job)
+URLRequestCustomJobDelegate::URLRequestCustomJobDelegate(URLRequestCustomJobShared *shared)
+ : m_shared(shared)
{
}
URLRequestCustomJobDelegate::~URLRequestCustomJobDelegate()
{
+ m_shared->unsetJobDelegate();
}
QUrl URLRequestCustomJobDelegate::url() const
{
- return toQt(m_job->request()->url());
+ return toQt(m_shared->requestUrl());
}
QByteArray URLRequestCustomJobDelegate::method() const
{
- return QByteArray::fromStdString(m_job->request()->method());
+ return QByteArray::fromStdString(m_shared->requestMethod());
}
void URLRequestCustomJobDelegate::setReply(const QByteArray &contentType, QIODevice *device)
{
- m_job->setReplyMimeType(contentType.toStdString());
- m_job->setReplyDevice(device);
+ m_shared->setReplyMimeType(contentType.toStdString());
+ m_shared->setReplyDevice(device);
}
void URLRequestCustomJobDelegate::abort()
{
- m_job->abort();
+ m_shared->abort();
}
void URLRequestCustomJobDelegate::redirect(const QUrl &url)
{
- m_job->redirect(toGurl(url));
+ m_shared->redirect(toGurl(url));
}
void URLRequestCustomJobDelegate::fail(Error error)
@@ -105,7 +106,7 @@ void URLRequestCustomJobDelegate::fail(Error error)
break;
}
if (net_error)
- m_job->fail(net_error);
+ m_shared->fail(net_error);
}
} // namespace
diff --git a/src/core/url_request_custom_job_delegate.h b/src/core/url_request_custom_job_delegate.h
index 3a3931660..7752d979e 100644
--- a/src/core/url_request_custom_job_delegate.h
+++ b/src/core/url_request_custom_job_delegate.h
@@ -49,7 +49,7 @@ QT_FORWARD_DECLARE_CLASS(QIODevice)
namespace QtWebEngineCore {
-class URLRequestCustomJob;
+class URLRequestCustomJobShared;
class QWEBENGINE_EXPORT URLRequestCustomJobDelegate : public QObject {
Q_OBJECT
@@ -75,10 +75,10 @@ public:
void fail(Error);
private:
- URLRequestCustomJobDelegate(URLRequestCustomJob *job);
+ URLRequestCustomJobDelegate(URLRequestCustomJobShared *shared);
- friend class URLRequestCustomJob;
- URLRequestCustomJob *m_job;
+ friend class URLRequestCustomJobShared;
+ URLRequestCustomJobShared *m_shared;
};
} // namespace
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 5e6335584..a5c7a756b 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -254,7 +254,7 @@ public:
virtual void moveValidationMessage(const QRect &anchor) = 0;
RenderProcessTerminationStatus renderProcessExitStatus(int);
virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) = 0;
-
+ virtual void requestGeometryChange(const QRect &geometry) = 0;
virtual void allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController) = 0;
virtual void updateScrollPosition(const QPointF &position) = 0;
virtual void updateContentsSize(const QSizeF &size) = 0;
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index a3d2d816e..43ecbdf7f 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -336,6 +336,17 @@ void WebContentsDelegateQt::RequestMediaAccessPermission(content::WebContents *w
MediaCaptureDevicesDispatcher::GetInstance()->processMediaAccessRequest(m_viewClient, web_contents, request, callback);
}
+void WebContentsDelegateQt::MoveContents(content::WebContents *source, const gfx::Rect &pos)
+{
+ Q_UNUSED(source)
+ m_viewClient->requestGeometryChange(toQt(pos));
+}
+
+bool WebContentsDelegateQt::IsPopupOrPanel(const content::WebContents *source) const
+{
+ return source->HasOpener();
+}
+
void WebContentsDelegateQt::UpdateTargetURL(content::WebContents* source, const GURL& url)
{
Q_UNUSED(source)
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index afa4030d0..cc00f1f44 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -96,6 +96,8 @@ public:
virtual bool AddMessageToConsole(content::WebContents* source, int32 level, const base::string16& message, int32 line_no, const base::string16& source_id) Q_DECL_OVERRIDE;
virtual void FindReply(content::WebContents *source, int request_id, int number_of_matches, const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update) Q_DECL_OVERRIDE;
virtual void RequestMediaAccessPermission(content::WebContents* web_contents, const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback) Q_DECL_OVERRIDE;
+ virtual void MoveContents(content::WebContents *source, const gfx::Rect &pos) Q_DECL_OVERRIDE;
+ virtual bool IsPopupOrPanel(const content::WebContents *source) const Q_DECL_OVERRIDE;
virtual void UpdateTargetURL(content::WebContents* source, const GURL& url) Q_DECL_OVERRIDE;
virtual void RequestToLockMouse(content::WebContents *web_contents, bool user_gesture, bool last_unlocked_by_target) Q_DECL_OVERRIDE;
virtual void ShowValidationMessage(content::WebContents *web_contents, const gfx::Rect &anchor_in_root_view, const base::string16 &main_text, const base::string16 &sub_text) Q_DECL_OVERRIDE;
diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index ee8174af7..a67bce94c 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -140,7 +140,7 @@ QString subProcessPath()
}
Q_FOREACH (const QString &candidate, candidatePaths) {
- if (QFileInfo(candidate).exists()) {
+ if (QFileInfo::exists(candidate)) {
processPath = candidate;
break;
}
@@ -167,7 +167,7 @@ QString pluginsPath()
const QStringList directories = QCoreApplication::libraryPaths();
Q_FOREACH (const QString &dir, directories) {
const QString candidate = dir % "/" % QLatin1String("qtwebengine");
- if (QFileInfo(candidate).exists()) {
+ if (QFileInfo::exists(candidate)) {
pluginsPath = candidate;
break;
}
diff --git a/src/webengine/api/qquickwebenginehistory.cpp b/src/webengine/api/qquickwebenginehistory.cpp
index ad943dfe8..96a4415e0 100644
--- a/src/webengine/api/qquickwebenginehistory.cpp
+++ b/src/webengine/api/qquickwebenginehistory.cpp
@@ -261,7 +261,7 @@ QQuickWebEngineHistoryPrivate::~QQuickWebEngineHistoryPrivate()
The data models can also be used to create a menu, as illustrated by the following code
snippet:
- \quotefromfile webengine/quicknanobrowser/browserwindow.qml
+ \quotefromfile webengine/quicknanobrowser/BrowserWindow.qml
\skipto ToolBar
\printuntil onObjectRemoved
\printuntil }
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index 060dd4e49..e4313a4bd 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -176,6 +176,7 @@ public:
virtual void moveValidationMessage(const QRect &anchor) Q_DECL_OVERRIDE;
virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus,
int exitCode) Q_DECL_OVERRIDE;
+ virtual void requestGeometryChange(const QRect &geometry) Q_DECL_OVERRIDE { Q_UNUSED(geometry); }
virtual void updateScrollPosition(const QPointF &position) Q_DECL_OVERRIDE;
virtual void updateContentsSize(const QSizeF &size) Q_DECL_OVERRIDE;
void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions,
diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
index 55f6c5504..29b8db42e 100644
--- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
+++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
@@ -47,7 +47,7 @@
\list
\li Windows: Visual Studio 2013 or Visual Studio 2015
\li Linux: Clang or GCC version 4.7 or later
- \li OS X: Xcode version 5.1 or later
+ \li OS X: Xcode version 5.1 or later on OS X 10.9 or later
\endlist
\section1 Pepper Plugin API Support
diff --git a/src/webengine/doc/src/webengineview.qdoc b/src/webengine/doc/src/webengineview.qdoc
index 39441228d..a242acffc 100644
--- a/src/webengine/doc/src/webengineview.qdoc
+++ b/src/webengine/doc/src/webengineview.qdoc
@@ -29,6 +29,22 @@
\inqmlmodule QtWebEngine
\since QtWebEngine 1.0
\brief A WebEngineView renders web content within a QML application.
+
+ The WebEngineView type enables QML applications to render regions of dynamic web content. It
+ may share the screen with other QML types, such as a TabView, or fill the screen, as specified
+ within the QML application.
+
+ \section1 Rendering to OpenGL Surface
+
+ When using a QQuickRenderControl to render a Qt Quick user interface to an OpenGL surface, the
+ WebEngineView type is not rendered correctly. The web engine view attempts to use a global
+ OpenGL context created by \l QtWebEngine::initialize(), but there is no public API for accessing
+ that context in order to share it with the \c QQuickRenderControl context.
+
+ To have the web engine view rendered correctly, it is possible to manually create a new
+ offscreen context that is shared with the \c QQuickRenderControl and to call the non-public
+ function \c qt_gl_set_global_share_context(), rather than calling \c initialize().
+ If \c initialize() is called after setting a global context, it will do nothing.
*/
/*!
@@ -251,6 +267,9 @@
The script will run in the same \e world as other scripts that are
part of the loaded site.
+ \warning Do not execute lengthy routines in the callback function, because it might block the
+ rendering of the web content.
+
See WebEngineView::userScripts for an alternative API to inject scripts.
*/
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 62c1adee6..2b448664f 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -112,6 +112,8 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
, m_isBeingAdopted(false)
, m_backgroundColor(Qt::white)
, fullscreenMode(false)
+ , webChannel(nullptr)
+ , webChannelWorldId(QWebEngineScript::MainWorld)
{
memset(actions, 0, sizeof(actions));
}
@@ -238,6 +240,8 @@ void QWebEnginePagePrivate::adoptNewWindow(WebContentsAdapter *newWebContents, W
Q_UNUSED(userGesture);
QWebEnginePage *newPage = q->createWindow(toWindowType(disposition));
+ if (!newPage)
+ return;
// Mark the new page as being in the process of being adopted, so that a second mouse move event
// sent by newWebContents->initialize() gets filtered in RenderWidgetHostViewQt::forwardEvent.
@@ -251,7 +255,7 @@ void QWebEnginePagePrivate::adoptNewWindow(WebContentsAdapter *newWebContents, W
newPage->d_func()->m_isBeingAdopted = true;
// Overwrite the new page's WebContents with ours.
- if (newPage && newPage->d_func() != this) {
+ if (newPage->d_func() != this) {
newPage->d_func()->adapter = newWebContents;
newWebContents->initialize(newPage->d_func());
if (!initialGeometry.isEmpty())
@@ -430,8 +434,14 @@ void QWebEnginePagePrivate::recreateFromSerializedHistory(QDataStream &input)
{
QExplicitlySharedDataPointer<WebContentsAdapter> newWebContents = WebContentsAdapter::createFromSerializedNavigationHistory(input, this);
if (newWebContents) {
+ // Keep the old adapter referenced so the user-scripts are not
+ // unregistered immediately.
+ QExplicitlySharedDataPointer<WebContentsAdapter> oldWebContents = adapter;
adapter = newWebContents.data();
adapter->initialize(this);
+ if (webChannel)
+ adapter->setWebChannel(webChannel, webChannelWorldId);
+ scriptCollection.d->rebindToContents(adapter.data());
}
}
@@ -593,7 +603,7 @@ QWebEngineSettings *QWebEnginePage::settings() const
QWebChannel *QWebEnginePage::webChannel() const
{
Q_D(const QWebEnginePage);
- return d->adapter->webChannel();
+ return d->webChannel;
}
/*!
@@ -631,7 +641,11 @@ void QWebEnginePage::setWebChannel(QWebChannel *channel)
void QWebEnginePage::setWebChannel(QWebChannel *channel, uint worldId)
{
Q_D(QWebEnginePage);
- d->adapter->setWebChannel(channel, worldId);
+ if (d->webChannel != channel || d->webChannelWorldId != worldId) {
+ d->webChannel = channel;
+ d->webChannelWorldId = worldId;
+ d->adapter->setWebChannel(channel, worldId);
+ }
}
/*!
@@ -1197,6 +1211,12 @@ void QWebEnginePagePrivate::renderProcessTerminated(RenderProcessTerminationStat
terminationStatus), exitCode);
}
+void QWebEnginePagePrivate::requestGeometryChange(const QRect &geometry)
+{
+ Q_Q(QWebEnginePage);
+ Q_EMIT q->geometryChangeRequested(geometry);
+}
+
void QWebEnginePagePrivate::startDragging(const content::DropData &dropData,
Qt::DropActions allowedActions, const QPixmap &pixmap,
const QPoint &offset)
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 2e55bd7c2..ce769169e 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -128,6 +128,7 @@ public:
virtual void moveValidationMessage(const QRect &anchor) Q_DECL_OVERRIDE;
virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus,
int exitCode) Q_DECL_OVERRIDE;
+ virtual void requestGeometryChange(const QRect &geometry) Q_DECL_OVERRIDE;
virtual void updateScrollPosition(const QPointF &position) Q_DECL_OVERRIDE;
virtual void updateContentsSize(const QSizeF &size) Q_DECL_OVERRIDE;
void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions,
@@ -160,6 +161,8 @@ public:
bool m_isBeingAdopted;
QColor m_backgroundColor;
bool fullscreenMode;
+ QWebChannel *webChannel;
+ unsigned int webChannelWorldId;
mutable QtWebEngineCore::CallbackDirectory m_callbacks;
mutable QAction *actions[QWebEnginePage::WebActionCount];
diff --git a/src/webenginewidgets/api/qwebenginescriptcollection.cpp b/src/webenginewidgets/api/qwebenginescriptcollection.cpp
index c17d05ce4..c53172261 100644
--- a/src/webenginewidgets/api/qwebenginescriptcollection.cpp
+++ b/src/webenginewidgets/api/qwebenginescriptcollection.cpp
@@ -223,3 +223,15 @@ void QWebEngineScriptCollectionPrivate::reserve(int capacity)
{
m_scriptController->reserve(m_contents, capacity);
}
+
+void QWebEngineScriptCollectionPrivate::rebindToContents(QtWebEngineCore::WebContentsAdapter *page)
+{
+ Q_ASSERT(m_contents);
+ Q_ASSERT(page);
+ Q_ASSERT(m_contents != page);
+
+ Q_FOREACH (const UserScript &script, m_scriptController->registeredScripts(m_contents)) {
+ m_scriptController->addUserScript(script, page);
+ }
+ m_contents = page;
+}
diff --git a/src/webenginewidgets/api/qwebenginescriptcollection_p.h b/src/webenginewidgets/api/qwebenginescriptcollection_p.h
index ebb0d1f00..185b590c4 100644
--- a/src/webenginewidgets/api/qwebenginescriptcollection_p.h
+++ b/src/webenginewidgets/api/qwebenginescriptcollection_p.h
@@ -72,6 +72,8 @@ public:
QList<QWebEngineScript> toList(const QString &scriptName = QString()) const;
QWebEngineScript find(const QString & name) const;
+ void rebindToContents(QtWebEngineCore::WebContentsAdapter *contents);
+
void insert(const QWebEngineScript &);
bool remove(const QWebEngineScript &);
void clear();
diff --git a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
index 7b87ff7d9..99723c105 100644
--- a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
+++ b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
@@ -279,5 +279,12 @@
\li In the latest HTML standard, any document element can be made editable through the
\c contentEditable attribute. So \c runJavaScript is all that is needed:
\c{page->runJavascript("document.documentElement.contentEditable = true")}
+ \row
+ \li QWebPage::setLinkDelegationPolicy
+ \li There is no way to connect a signal to run C++ code when a link is clicked. However,
+ link clicks can be delegated to the Qt application instead of having the HTML handler
+ engine process them by overloading the QWebEnginePage::acceptNavigationRequest()
+ function. This is necessary when an HTML document is used as part of the user interface,
+ and not to display external data, for example, when displaying a list of results.
\endtable
*/
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index 3b25bac76..a65d6011f 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -283,8 +283,17 @@
the specified navigation type \a type. \a isMainFrame indicates whether the request corresponds
to the main frame or a sub frame. If the function returns \c true, the navigation request is
accepted and \c url is loaded. The default implementation accepts all navigation requests.
-*/
+ This function is called for absolute URLs that are prefixed with \c {http://} or \c {https://}
+ and for unrecognized schemes, such as \c {mailto:}, which will be handled by QDesktopServices
+ if accepted. To have this function called also upon receiving navigation requests to local URLs,
+ prefix the URLs with \c {http://}.
+
+ Navigation requests can be delegated to the Qt application instead of having the HTML handler
+ engine process them by overloading this function. This is necessary when an HTML document is
+ used as part of the user interface, and not to display external data, for example, when
+ displaying a list of results.
+*/
/*!
\fn void QWebEnginePage::javaScriptAlert(const QUrl &securityOrigin, const QString& msg)
@@ -634,6 +643,9 @@
page.runJavaScript("document.title", [](const QVariant &v) { qDebug() << v.toString(); });
\endcode
+ \warning Do not execute lengthy routines in the callback function, because it might block the
+ rendering of the web engine page.
+
See scripts() for an alternative API to inject scripts.
*/
diff --git a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
index 9d03527e1..397b9f51b 100644
--- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
@@ -75,9 +75,9 @@
If you want to provide support for web sites that allow the user to open
new windows, such as pop-up windows, you can subclass QWebEngineView and
reimplement the createWindow() function.
+
+ \sa {WebEngine Demo Browser Example}, {WebEngine Content Manipulation Example}, {Markdown Editor Example}
*/
-// FIXME: reintroduce the following when we have proper names for the examples.
-// \sa {WebEngine Tab Browser Example}, {WebEngine Fancy Browser Example}
/*!
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index cb566c254..a1900a77d 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -21,10 +21,13 @@
#include "util.h"
#include <QScopedPointer>
+#include <QtCore/qelapsedtimer.h>
#include <QtQml/QQmlEngine>
#include <QtTest/QtTest>
#include <private/qquickwebengineview_p.h>
+#include <functional>
+
class tst_QQuickWebEngineView : public QObject {
Q_OBJECT
public:
@@ -313,6 +316,21 @@ void tst_QQuickWebEngineView::multipleWebEngineViews()
QTest::qWait(200);
}
+QImage tryToGrabWindowUntil(QQuickWindow *window, std::function<bool(const QImage &)> checkImage,
+ int timeout = 5000)
+{
+ QImage grabbed;
+ QElapsedTimer t;
+ t.start();
+ do {
+ QTest::qWait(200);
+ grabbed = window->grabWindow();
+ if (checkImage(grabbed))
+ break;
+ } while (!t.hasExpired(timeout));
+ return grabbed;
+}
+
void tst_QQuickWebEngineView::basicRenderingSanity()
{
showWebEngineView();
@@ -322,9 +340,12 @@ void tst_QQuickWebEngineView::basicRenderingSanity()
// This should not crash.
webEngineView()->setVisible(true);
- QTest::qWait(200);
- QImage grabbedWindow = m_window->grabWindow();
+
QRgb testColor = qRgba(0, 0xff, 0, 0xff);
+ const QImage grabbedWindow = tryToGrabWindowUntil(m_window.data(),
+ [testColor] (const QImage &image) {
+ return image.pixel(10, 10) == testColor;
+ });
QVERIFY(grabbedWindow.pixel(10, 10) == testColor);
QVERIFY(grabbedWindow.pixel(100, 10) == testColor);
QVERIFY(grabbedWindow.pixel(10, 100) == testColor);
@@ -370,12 +391,11 @@ void tst_QQuickWebEngineView::transparentWebEngineViews()
webEngineView2->setSize(QSizeF(300, 400));
webEngineView2->setUrl(urlFromTestPath("/html/basic_page.html"));
QVERIFY(waitForLoadSucceeded(webEngineView2.data()));
- webEngineView2->setVisible(true);
-
- QTest::qWait(200);
// Result image: black text on red background.
- QImage grabbedWindow = m_window->grabWindow();
+ const QImage grabbedWindow = tryToGrabWindowUntil(m_window.data(), [] (const QImage &image) {
+ return image.pixelColor(0, 0) == QColor(Qt::red);
+ });
QSet<int> redComponents;
for (int i = 0, width = grabbedWindow.width(); i < width; i++) {
diff --git a/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp b/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
index 2e85ab802..cd1d1ac44 100644
--- a/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
+++ b/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
@@ -178,13 +178,14 @@ void tst_QQuickWebEngineViewGraphics::reparentToOtherWindow()
void tst_QQuickWebEngineViewGraphics::setHtml(const QString &html)
{
QString htmlData = QUrl::toPercentEncoding(html);
- QString qmlData = QUrl::toPercentEncoding(QStringLiteral("import QtQuick 2.0; import QtWebEngine 1.2; WebEngineView { width: 150; height: 150; url: loadUrl }"));
- m_view->rootContext()->setContextProperty("loadUrl", QUrl(QStringLiteral("data:text/html,%1").arg(htmlData)));
+ QString qmlData = QUrl::toPercentEncoding(QStringLiteral("import QtQuick 2.0; import QtWebEngine 1.2; WebEngineView { width: 150; height: 150 }"));
m_view->setSource(QUrl(QStringLiteral("data:text/plain,%1").arg(qmlData)));
m_view->create();
QQuickWebEngineView *webEngineView = static_cast<QQuickWebEngineView *>(m_view->rootObject());
- QVERIFY(waitForSignal(reinterpret_cast<QObject *>(webEngineView->experimental()), SIGNAL(loadVisuallyCommitted())));
+ QSignalSpy spy(reinterpret_cast<QObject *>(webEngineView->experimental()), SIGNAL(loadVisuallyCommitted()));
+ webEngineView->setProperty("url", QUrl(QStringLiteral("data:text/html,%1").arg(htmlData)));
+ QVERIFY(!spy.isEmpty() || spy.wait());
QCOMPARE(m_view->rootObject()->property("loading"), QVariant(false));
}
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 8fd71c701..690cf70e4 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -33,6 +33,7 @@
#include <QStyle>
#include <QtTest/QtTest>
#include <QTextCharFormat>
+#include <QWebChannel>
#include <private/qinputmethod_p.h>
#include <qnetworkcookiejar.h>
#include <qnetworkreply.h>
@@ -42,6 +43,8 @@
#include <qwebenginehistory.h>
#include <qwebenginepage.h>
#include <qwebengineprofile.h>
+#include <qwebenginescript.h>
+#include <qwebenginescriptcollection.h>
#include <qwebenginesettings.h>
#include <qwebengineview.h>
#include <qimagewriter.h>
@@ -237,6 +240,8 @@ private Q_SLOTS:
void loadInSignalHandlers_data();
void loadInSignalHandlers();
+ void restoreHistory();
+
private:
QWebEngineView* m_view;
QWebEnginePage* m_page;
@@ -5079,5 +5084,36 @@ void tst_QWebEnginePage::loadInSignalHandlers()
QCOMPARE(m_page->url(), urlForSetter);
}
+void tst_QWebEnginePage::restoreHistory()
+{
+ QWebChannel *channel = new QWebChannel;
+ QWebEnginePage *page = new QWebEnginePage;
+ page->setWebChannel(channel);
+
+ QWebEngineScript script;
+ script.setName(QStringLiteral("script"));
+ page->scripts().insert(script);
+
+ QSignalSpy spy(page, SIGNAL(loadFinished(bool)));
+ page->load(QUrl(QStringLiteral("qrc:/resources/test1.html")));
+ QTRY_COMPARE(spy.count(), 1);
+
+ QCOMPARE(page->webChannel(), channel);
+ QVERIFY(page->scripts().contains(script));
+
+ QByteArray data;
+ QDataStream out(&data, QIODevice::ReadWrite);
+ out << *page->history();
+ QDataStream in(&data, QIODevice::ReadOnly);
+ in >> *page->history();
+ QTRY_COMPARE(spy.count(), 2);
+
+ QCOMPARE(page->webChannel(), channel);
+ QVERIFY(page->scripts().contains(script));
+
+ delete page;
+ delete channel;
+}
+
QTEST_MAIN(tst_QWebEnginePage)
#include "tst_qwebenginepage.moc"
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index dfc1d39df..8c23af7ee 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -27,7 +27,11 @@
****************************************************************************/
#include "../util.h"
+#include <QtCore/qbuffer.h>
#include <QtTest/QtTest>
+#include <QtWebEngineCore/qwebengineurlrequestjob.h>
+#include <QtWebEngineCore/qwebengineurlschemehandler.h>
+#include <QtWebEngineWidgets/qwebengineview.h>
#include <qwebengineprofile.h>
#include <qwebenginepage.h>
@@ -40,6 +44,8 @@ private Q_SLOTS:
void profileConstructors();
void clearDataFromCache();
void disableCache();
+ void urlSchemeHandlers();
+ void urlSchemeHandlerFailRequest();
};
void tst_QWebEngineProfile::defaultProfile()
@@ -137,5 +143,104 @@ void tst_QWebEngineProfile::disableCache()
cacheDir.removeRecursively();
}
+class RedirectingUrlSchemeHandler : public QWebEngineUrlSchemeHandler
+{
+public:
+ void requestStarted(QWebEngineUrlRequestJob *job)
+ {
+ job->redirect(QUrl(QStringLiteral("data:text/plain;charset=utf-8,")
+ + job->requestUrl().fileName()));
+ }
+};
+
+class ReplyingUrlSchemeHandler : public QWebEngineUrlSchemeHandler
+{
+ QBuffer m_buffer;
+ QByteArray m_bufferData;
+public:
+ ReplyingUrlSchemeHandler(QObject *parent = nullptr)
+ : QWebEngineUrlSchemeHandler(parent)
+ {
+ m_buffer.setBuffer(&m_bufferData);
+ }
+
+ void requestStarted(QWebEngineUrlRequestJob *job)
+ {
+ m_bufferData = job->requestUrl().toString().toUtf8();
+ job->reply("text/plain;charset=utf-8", &m_buffer);
+ }
+};
+
+void tst_QWebEngineProfile::urlSchemeHandlers()
+{
+ RedirectingUrlSchemeHandler mailtoHandler;
+ QWebEngineProfile profile(QStringLiteral("urlSchemeHandlers"));
+ profile.installUrlSchemeHandler("mailto", &mailtoHandler);
+ QWebEngineView view;
+ QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
+ view.setPage(new QWebEnginePage(&profile, &view));
+ QString emailAddress = QStringLiteral("egon@olsen-banden.dk");
+ view.load(QUrl(QStringLiteral("mailto:") + emailAddress));
+ QVERIFY(loadFinishedSpy.wait());
+ QCOMPARE(toPlainTextSync(view.page()), emailAddress);
+
+ // Install a gopher handler after the view has been fully initialized.
+ ReplyingUrlSchemeHandler gopherHandler;
+ profile.installUrlSchemeHandler("gopher", &gopherHandler);
+ QUrl url = QUrl(QStringLiteral("gopher://olsen-banden.dk/benny"));
+ view.load(url);
+ QVERIFY(loadFinishedSpy.wait());
+ QCOMPARE(toPlainTextSync(view.page()), url.toString());
+
+ // Remove the mailto scheme, and check whether it is not handled anymore.
+ profile.removeUrlScheme("mailto");
+ emailAddress = QStringLiteral("kjeld@olsen-banden.dk");
+ view.load(QUrl(QStringLiteral("mailto:") + emailAddress));
+ QVERIFY(loadFinishedSpy.wait());
+ QVERIFY(toPlainTextSync(view.page()) != emailAddress);
+
+ // Check if gopher is still working after removing mailto.
+ url = QUrl(QStringLiteral("gopher://olsen-banden.dk/yvonne"));
+ view.load(url);
+ QVERIFY(loadFinishedSpy.wait());
+ QCOMPARE(toPlainTextSync(view.page()), url.toString());
+
+ // Does removeAll work?
+ profile.removeAllUrlSchemeHandlers();
+ url = QUrl(QStringLiteral("gopher://olsen-banden.dk/harry"));
+ view.load(url);
+ QVERIFY(loadFinishedSpy.wait());
+ QVERIFY(toPlainTextSync(view.page()) != url.toString());
+
+ // Install a handler that is owned by the view. Make sure this doesn't crash on shutdown.
+ profile.installUrlSchemeHandler("aviancarrier", new ReplyingUrlSchemeHandler(&view));
+ url = QUrl(QStringLiteral("aviancarrier:inspector.mortensen@politistyrke.dk"));
+ view.load(url);
+ QVERIFY(loadFinishedSpy.wait());
+ QCOMPARE(toPlainTextSync(view.page()), url.toString());
+}
+
+class FailingUrlSchemeHandler : public QWebEngineUrlSchemeHandler
+{
+public:
+ void requestStarted(QWebEngineUrlRequestJob *job) override
+ {
+ job->fail(QWebEngineUrlRequestJob::RequestFailed);
+ }
+};
+
+void tst_QWebEngineProfile::urlSchemeHandlerFailRequest()
+{
+ FailingUrlSchemeHandler handler;
+ QWebEngineProfile profile;
+ profile.installUrlSchemeHandler("foo", &handler);
+ QWebEngineView view;
+ QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
+ view.setPage(new QWebEnginePage(&profile, &view));
+ view.load(QUrl(QStringLiteral("foo://bar")));
+ QVERIFY(loadFinishedSpy.wait());
+ QVERIFY(toPlainTextSync(view.page()).isEmpty());
+}
+
QTEST_MAIN(tst_QWebEngineProfile)
#include "tst_qwebengineprofile.moc"
diff --git a/tools/buildscripts/gyp_qtwebengine b/tools/buildscripts/gyp_qtwebengine
index ec24caeb1..d896364ed 100755
--- a/tools/buildscripts/gyp_qtwebengine
+++ b/tools/buildscripts/gyp_qtwebengine
@@ -152,11 +152,6 @@ if __name__ == '__main__':
args.extend(['-D', 'qtwebengine_root=' + purifyGypVarPath(qtwebengine_root)])
args.extend(['-D', 'chromium_src_dir=' + purifyGypVarPath(chrome_src)])
- args.extend(['-D', 'clang_use_chrome_plugins=0'])
- # We do not want to ship more external binary blobs, so let v8 embed its startup data.
- args.extend(['-D', 'v8_use_external_startup_data=0'])
- # Trigger Qt-specific build conditions.
- args.extend(['-D', 'use_qt=1'])
# Tweak the output location and format (hardcode ninja for now if not set)
args.extend(['--generator-output', '.'])
args.extend(['-Goutput_dir='+ os.path.relpath(output_dir, qtwebengine_root)])
diff --git a/tools/qmake/mkspecs/features/configure.prf b/tools/qmake/mkspecs/features/configure.prf
index 07fd56d5d..5674ea3a5 100644
--- a/tools/qmake/mkspecs/features/configure.prf
+++ b/tools/qmake/mkspecs/features/configure.prf
@@ -41,7 +41,7 @@ defineTest(runConfigure) {
else: log("System libwebp or libwebpdemux not found. Using Chromium's copies.$${EOL}")
packagesExist(libxml-2.0,libxslt): WEBENGINE_CONFIG += use_system_libxslt
else: log("System libxml2 or libxslt not found. Using Chromium's copies.$${EOL}")
- for(package, $$list("libevent flac jsoncpp opus")) {
+ for(package, $$list("libevent jsoncpp opus")) {
packagesExist($$package): WEBENGINE_CONFIG += use_system_$$package
else: log("System $$package not found. Using Chromium's copy.$${EOL}")
}
diff --git a/tools/qmake/mkspecs/features/functions.prf b/tools/qmake/mkspecs/features/functions.prf
index 2447d8372..2df689bca 100644
--- a/tools/qmake/mkspecs/features/functions.prf
+++ b/tools/qmake/mkspecs/features/functions.prf
@@ -1,30 +1,48 @@
defineTest(isPlatformSupported) {
- !linux-g++*:!linux-clang:!win32-msvc2013*:!win32-msvc2015*:!macx-clang*:!boot2qt {
- skipBuild("Qt WebEngine can currently only be built for Linux (GCC/clang), Windows (MSVC 2013 or 2015), OS X (10.9/XCode 5.1+) or Qt for Device Creation.")
- return(false)
- }
- !contains(QT_CONFIG, c++11) {
- skipBuild("C++11 support is required in order to build chromium.")
- return(false)
- }
- static {
- skipBuild("Static builds of QtWebEngine aren't supported.")
- return(false)
- }
- osx {
+ linux {
+ !gcc:!clang {
+ skipBuild("Qt WebEngine on Linux requires clang or GCC.")
+ return(false)
+ }
+ gcc:!clang:!isGCCVersionSupported(): return(false)
+ } else:win32 {
+ winrt {
+ skipBuild("WinRT is not supported.")
+ return(false)
+ }
+ msvc {
+ !equals(MSVC_VER, "12.0"):!equals(MSVC_VER, "14.0") {
+ skipBuild("Qt WebEngine on Windows requires MSVC 2013 or MSVC 2015.")
+ return(false)
+ }
+ } else {
+ skipBuild("Qt WebEngine on Windows requires MSVC 2013 or MSVC 2015.")
+ return(false)
+ }
+ } else:osx {
lessThan(QMAKE_XCODE_VERSION, 5.1) {
- skipBuild("Using xcode version $$QMAKE_XCODE_VERSION, but at least version 5.1 is required to build Qt WebEngine.")
+ skipBuild("Using XCode version $$QMAKE_XCODE_VERSION, but at least version 5.1 is required to build Qt WebEngine.")
return(false)
}
# We require OS X 10.9 (darwin version 13.0.0) or newer
darwin_major_version = $$section(QMAKE_HOST.version, ., 0, 0)
lessThan(darwin_major_version, 13) {
- skipBuild("OS X version 10.9 or newer is required to build Qt WebEngine.")
+ skipBuild("Qt WebEngine requires OS X version 10.9 or newer.")
return(false)
}
+ } else {
+ skipBuild("Unknown platform. Qt WebEngine only supports Linux, Windows, and OS X.")
+ return(false)
}
- linux-g++*:!isGCCVersionSupported(): return(false)
+ !contains(QT_CONFIG, c++11) {
+ skipBuild("C++11 support is required in order to build chromium.")
+ return(false)
+ }
+ static {
+ skipBuild("Static builds of QtWebEngine aren't supported.")
+ return(false)
+ }
!isPythonVersionSupported(): return(false)
return(true)
}