summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--examples/webengine/quicknanobrowser/quickwindow.qml12
-rw-r--r--examples/webengine/quicknanobrowser/util.h2
-rw-r--r--examples/webenginewidgets/browser/browserapplication.cpp11
-rw-r--r--examples/webenginewidgets/browser/featurepermissionbar.cpp24
-rw-r--r--examples/webenginewidgets/browser/featurepermissionbar.h1
-rw-r--r--examples/webenginewidgets/browser/settings.cpp84
-rw-r--r--examples/webenginewidgets/browser/settings.ui480
-rw-r--r--examples/webenginewidgets/browser/webview.cpp34
-rw-r--r--examples/webenginewidgets/browser/webview.h4
-rw-r--r--qtwebengine.pro6
-rw-r--r--src/core/access_token_store_qt.cpp34
-rw-r--r--src/core/access_token_store_qt.h23
-rw-r--r--src/core/browser_context_adapter.cpp316
-rw-r--r--src/core/browser_context_adapter.h140
-rw-r--r--src/core/browser_context_adapter_client.h63
-rw-r--r--src/core/browser_context_qt.cpp40
-rw-r--r--src/core/browser_context_qt.h13
-rw-r--r--src/core/content_browser_client_qt.cpp67
-rw-r--r--src/core/content_browser_client_qt.h24
-rw-r--r--src/core/content_main_delegate_qt.cpp4
-rw-r--r--src/core/core_gyp_generator.pro13
-rw-r--r--src/core/core_module.pro3
-rw-r--r--src/core/delegated_frame_node.cpp407
-rw-r--r--src/core/delegated_frame_node.h37
-rw-r--r--src/core/dev_tools_http_handler_delegate_qt.cpp87
-rw-r--r--src/core/download_manager_delegate_qt.cpp216
-rw-r--r--src/core/download_manager_delegate_qt.h46
-rw-r--r--src/core/location_provider_qt.cpp248
-rw-r--r--src/core/location_provider_qt.h76
-rw-r--r--src/core/render_widget_host_view_qt.cpp34
-rw-r--r--src/core/render_widget_host_view_qt.h3
-rw-r--r--src/core/render_widget_host_view_qt_delegate.h8
-rw-r--r--src/core/resources/devtools_discovery_page.html85
-rw-r--r--src/core/type_conversion.h9
-rw-r--r--src/core/url_request_context_getter_qt.cpp274
-rw-r--r--src/core/url_request_context_getter_qt.h25
-rw-r--r--src/core/web_contents_adapter.cpp82
-rw-r--r--src/core/web_contents_adapter.h5
-rw-r--r--src/core/web_contents_adapter_client.h5
-rw-r--r--src/core/web_contents_adapter_p.h4
-rw-r--r--src/core/web_contents_delegate_qt.cpp21
-rw-r--r--src/core/web_contents_delegate_qt.h5
-rw-r--r--src/core/web_engine_context.cpp81
-rw-r--r--src/core/web_engine_context.h10
-rw-r--r--src/core/web_engine_library_info.cpp10
-rw-r--r--src/core/web_engine_visited_links_manager.cpp16
-rw-r--r--src/core/web_engine_visited_links_manager.h5
-rw-r--r--src/webengine/api/qquickwebenginedownloaditem.cpp134
-rw-r--r--src/webengine/api/qquickwebenginedownloaditem_p.h91
-rw-r--r--src/webengine/api/qquickwebenginedownloaditem_p_p.h67
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp293
-rw-r--r--src/webengine/api/qquickwebengineprofile_p.h127
-rw-r--r--src/webengine/api/qquickwebengineprofile_p_p.h77
-rw-r--r--src/webengine/api/qquickwebenginesettings.cpp47
-rw-r--r--src/webengine/api/qquickwebenginesettings_p.h26
-rw-r--r--src/webengine/api/qquickwebenginesettings_p_p.h1
-rw-r--r--src/webengine/api/qquickwebenginesingleton.cpp6
-rw-r--r--src/webengine/api/qquickwebenginesingleton_p.h4
-rw-r--r--src/webengine/api/qquickwebengineview.cpp168
-rw-r--r--src/webengine/api/qquickwebengineview_p.h19
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h14
-rw-r--r--src/webengine/plugin/experimental/plugin.cpp3
-rw-r--r--src/webengine/plugin/plugin.cpp2
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.cpp29
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.h5
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp15
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.h5
-rw-r--r--src/webengine/webengine.pro8
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp79
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h20
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h10
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp352
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.h109
-rw-r--r--src/webenginewidgets/api/qwebengineprofile_p.h60
-rw-r--r--src/webenginewidgets/api/qwebenginesettings.cpp34
-rw-r--r--src/webenginewidgets/api/qwebenginesettings.h2
-rw-r--r--src/webenginewidgets/api/qwebenginesettings_p.h1
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc24
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp30
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h5
-rw-r--r--src/webenginewidgets/webenginewidgets.pro7
-rw-r--r--tests/auto/quick/publicapi/tst_publicapi.cpp28
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml90
-rw-r--r--tests/auto/quick/qmltests/qmltests.pro1
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp166
-rw-r--r--tests/quicktestbrowser/DownloadView.qml165
-rw-r--r--tests/quicktestbrowser/FeaturePermissionBar.qml8
-rw-r--r--tests/quicktestbrowser/ZoomController.qml102
-rw-r--r--tests/quicktestbrowser/quicktestbrowser.pro1
-rw-r--r--tests/quicktestbrowser/quickwindow.qml69
-rw-r--r--tests/quicktestbrowser/resources.qrc2
-rw-r--r--tests/quicktestbrowser/util.h2
-rw-r--r--tools/qmake/mkspecs/features/functions.prf8
-rwxr-xr-xtools/scripts/take_snapshot.py21
95 files changed, 4516 insertions, 1220 deletions
diff --git a/.qmake.conf b/.qmake.conf
index c60de80a6..0a6b62d97 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -2,4 +2,4 @@ QMAKEPATH += $$PWD/tools/qmake
load(qt_build_config)
CONFIG += qt_example_installs
-MODULE_VERSION = 5.4.1
+MODULE_VERSION = 5.5.0
diff --git a/examples/webengine/quicknanobrowser/quickwindow.qml b/examples/webengine/quicknanobrowser/quickwindow.qml
index 610144dca..b954629fb 100644
--- a/examples/webengine/quicknanobrowser/quickwindow.qml
+++ b/examples/webengine/quicknanobrowser/quickwindow.qml
@@ -93,6 +93,18 @@ ApplicationWindow {
tabs.removeTab(tabs.currentIndex)
}
}
+ Action {
+ shortcut: "Ctrl+0"
+ onTriggered: currentWebView.zoomFactor = 1.0;
+ }
+ Action {
+ shortcut: "Ctrl+-"
+ onTriggered: currentWebView.zoomFactor -= 0.1;
+ }
+ Action {
+ shortcut: "Ctrl+="
+ onTriggered: currentWebView.zoomFactor += 0.1;
+ }
toolBar: ToolBar {
id: navigationBar
diff --git a/examples/webengine/quicknanobrowser/util.h b/examples/webengine/quicknanobrowser/util.h
index bc1cf8beb..ca0f5f1d5 100644
--- a/examples/webengine/quicknanobrowser/util.h
+++ b/examples/webengine/quicknanobrowser/util.h
@@ -50,7 +50,7 @@ QUrl urlFromUserInput(const QString& userInput)
{
QFileInfo fileInfo(userInput);
if (fileInfo.exists())
- return QUrl(fileInfo.absoluteFilePath());
+ return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
return QUrl::fromUserInput(userInput);
}
diff --git a/examples/webenginewidgets/browser/browserapplication.cpp b/examples/webenginewidgets/browser/browserapplication.cpp
index 44713901d..ddcebfb8e 100644
--- a/examples/webenginewidgets/browser/browserapplication.cpp
+++ b/examples/webenginewidgets/browser/browserapplication.cpp
@@ -66,6 +66,7 @@
#include <QtNetwork/QNetworkProxy>
#include <QtNetwork/QSslSocket>
+#include <QWebEngineProfile>
#include <QWebEngineSettings>
#include <QtCore/QDebug>
@@ -230,6 +231,8 @@ void BrowserApplication::loadSettings()
settings.beginGroup(QLatin1String("websettings"));
QWebEngineSettings *defaultSettings = QWebEngineSettings::globalSettings();
+ QWebEngineProfile *defaultProfile = QWebEngineProfile::defaultProfile();
+
QString standardFontFamily = defaultSettings->fontFamily(QWebEngineSettings::StandardFont);
int standardFontSize = defaultSettings->fontSize(QWebEngineSettings::DefaultFontSize);
QFont standardFont = QFont(standardFontFamily, standardFontSize);
@@ -255,6 +258,14 @@ void BrowserApplication::loadSettings()
QUrl url = settings.value(QLatin1String("userStyleSheet")).toUrl();
defaultSettings->setUserStyleSheetUrl(url);
#endif
+ defaultProfile->setHttpUserAgent(settings.value(QLatin1String("httpUserAgent")).toString());
+ settings.endGroup();
+ settings.beginGroup(QLatin1String("cookies"));
+
+ QWebEngineProfile::PersistentCookiesPolicy persistentCookiesPolicy = QWebEngineProfile::PersistentCookiesPolicy(settings.value(QLatin1String("persistentCookiesPolicy")).toInt());
+ defaultProfile->setPersistentCookiesPolicy(persistentCookiesPolicy);
+ QString pdataPath = settings.value(QLatin1String("persistentDataPath")).toString();
+ defaultProfile->setPersistentStoragePath(pdataPath);
settings.endGroup();
}
diff --git a/examples/webenginewidgets/browser/featurepermissionbar.cpp b/examples/webenginewidgets/browser/featurepermissionbar.cpp
index 98f19ad1f..1b6d446cd 100644
--- a/examples/webenginewidgets/browser/featurepermissionbar.cpp
+++ b/examples/webenginewidgets/browser/featurepermissionbar.cpp
@@ -53,15 +53,17 @@ static QString textForPermissionType(QWebEnginePage::Feature type)
{
switch (type) {
case QWebEnginePage::Notifications:
- return QObject::tr("desktop notifications");
+ return QObject::tr("use desktop notifications");
case QWebEnginePage::Geolocation:
- return QObject::tr("your position");
+ return QObject::tr("use your position");
case QWebEnginePage::MediaAudioCapture:
- return QObject::tr("your microphone");
+ return QObject::tr("use your microphone");
case QWebEnginePage::MediaVideoCapture:
- return QObject::tr("your camera");
+ return QObject::tr("use your camera");
case QWebEnginePage::MediaAudioVideoCapture:
- return QObject::tr("your camera and microphone");
+ return QObject::tr("use your camera and microphone");
+ case QWebEnginePage::MouseLock:
+ return QObject::tr("lock your mouse");
default:
Q_UNREACHABLE();
}
@@ -80,12 +82,13 @@ FeaturePermissionBar::FeaturePermissionBar(QWidget *view)
l->addStretch();
QPushButton *allowButton = new QPushButton(tr("Allow"), this);
QPushButton *denyButton = new QPushButton(tr("Deny"), this);
+ QPushButton *discardButton = new QPushButton(QIcon(QStringLiteral(":closetab.png")), QString(), this);
connect(allowButton, &QPushButton::clicked, this, &FeaturePermissionBar::permissionGranted);
connect(denyButton, &QPushButton::clicked, this, &FeaturePermissionBar::permissionDenied);
- QPushButton *discardButton = new QPushButton(QIcon(QStringLiteral(":closetab.png")), QString(), this);
- connect(discardButton, &QPushButton::clicked, this, &QObject::deleteLater);
+ connect(discardButton, &QPushButton::clicked, this, &FeaturePermissionBar::permissionUnknown);
connect(allowButton, &QPushButton::clicked, this, &QObject::deleteLater);
connect(denyButton, &QPushButton::clicked, this, &QObject::deleteLater);
+ connect(discardButton, &QPushButton::clicked, this, &QObject::deleteLater);
l->addWidget(denyButton);
l->addWidget(allowButton);
l->addWidget(discardButton);
@@ -96,7 +99,7 @@ void FeaturePermissionBar::requestPermission(const QUrl &securityOrigin, QWebEng
{
m_securityOrigin = securityOrigin;
m_feature = feature;
- m_messageLabel->setText(tr("%1 wants to use %2.").arg(securityOrigin.host()).arg(textForPermissionType(feature)));
+ m_messageLabel->setText(tr("%1 wants to %2.").arg(securityOrigin.host()).arg(textForPermissionType(feature)));
show();
// Ease in
QPropertyAnimation *animation = new QPropertyAnimation(this);
@@ -118,3 +121,8 @@ void FeaturePermissionBar::permissionGranted()
{
emit featurePermissionProvided(m_securityOrigin, m_feature, QWebEnginePage::PermissionGrantedByUser);
}
+
+void FeaturePermissionBar::permissionUnknown()
+{
+ emit featurePermissionProvided(m_securityOrigin, m_feature, QWebEnginePage::PermissionUnknown);
+}
diff --git a/examples/webenginewidgets/browser/featurepermissionbar.h b/examples/webenginewidgets/browser/featurepermissionbar.h
index 92ca04773..cee5a25b0 100644
--- a/examples/webenginewidgets/browser/featurepermissionbar.h
+++ b/examples/webenginewidgets/browser/featurepermissionbar.h
@@ -63,6 +63,7 @@ signals:
private slots:
void permissionDenied();
void permissionGranted();
+ void permissionUnknown();
private:
QWebEnginePage::Feature m_feature;
diff --git a/examples/webenginewidgets/browser/settings.cpp b/examples/webenginewidgets/browser/settings.cpp
index 835e7a9b5..753ef033d 100644
--- a/examples/webenginewidgets/browser/settings.cpp
+++ b/examples/webenginewidgets/browser/settings.cpp
@@ -58,9 +58,7 @@ SettingsDialog::SettingsDialog(QWidget *parent)
: QDialog(parent)
{
setupUi(this);
- connect(exceptionsButton, SIGNAL(clicked()), this, SLOT(showExceptions()));
connect(setHomeToCurrentPageButton, SIGNAL(clicked()), this, SLOT(setHomeToCurrentPage()));
- connect(cookiesButton, SIGNAL(clicked()), this, SLOT(showCookies()));
connect(standardFontButton, SIGNAL(clicked()), this, SLOT(chooseFont()));
connect(fixedFontButton, SIGNAL(clicked()), this, SLOT(chooseFixedFont()));
@@ -89,6 +87,10 @@ void SettingsDialog::loadDefaults()
#endif
enableScrollAnimator->setChecked(defaultSettings->testAttribute(QWebEngineSettings::ScrollAnimatorEnabled));
+
+ persistentDataPath->setText(QWebEngineProfile::defaultProfile()->persistentStoragePath());
+ sessionCookiesCombo->setCurrentIndex(QWebEngineProfile::defaultProfile()->persistentCookiesPolicy());
+ httpUserAgent->setText(QWebEngineProfile::defaultProfile()->httpUserAgent());
}
void SettingsDialog::loadFromSettings()
@@ -137,47 +139,19 @@ void SettingsDialog::loadFromSettings()
enablePlugins->setChecked(settings.value(QLatin1String("enablePlugins"), enablePlugins->isChecked()).toBool());
userStyleSheet->setText(settings.value(QLatin1String("userStyleSheet")).toUrl().toString());
enableScrollAnimator->setChecked(settings.value(QLatin1String("enableScrollAnimator"), enableScrollAnimator->isChecked()).toBool());
+ httpUserAgent->setText(settings.value(QLatin1String("httpUserAgent"), httpUserAgent->text()).toString());
settings.endGroup();
-#if defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
// Privacy
settings.beginGroup(QLatin1String("cookies"));
- QByteArray value = settings.value(QLatin1String("acceptCookies"), QLatin1String("AcceptOnlyFromSitesNavigatedTo")).toByteArray();
- QMetaEnum acceptPolicyEnum = CookieJar::staticMetaObject.enumerator(CookieJar::staticMetaObject.indexOfEnumerator("AcceptPolicy"));
- CookieJar::AcceptPolicy acceptCookies = acceptPolicyEnum.keyToValue(value) == -1 ?
- CookieJar::AcceptOnlyFromSitesNavigatedTo :
- static_cast<CookieJar::AcceptPolicy>(acceptPolicyEnum.keyToValue(value));
- switch (acceptCookies) {
- case CookieJar::AcceptAlways:
- acceptCombo->setCurrentIndex(0);
- break;
- case CookieJar::AcceptNever:
- acceptCombo->setCurrentIndex(1);
- break;
- case CookieJar::AcceptOnlyFromSitesNavigatedTo:
- acceptCombo->setCurrentIndex(2);
- break;
- }
+ int persistentCookiesPolicy = settings.value(QLatin1String("persistentCookiesPolicy"), sessionCookiesCombo->currentIndex()).toInt();
+ sessionCookiesCombo->setCurrentIndex(persistentCookiesPolicy);
+
+ QString pdataPath = settings.value(QLatin1String("persistentDataPath"), persistentDataPath->text()).toString();
+ persistentDataPath->setText(pdataPath);
- value = settings.value(QLatin1String("keepCookiesUntil"), QLatin1String("Expire")).toByteArray();
- QMetaEnum keepPolicyEnum = CookieJar::staticMetaObject.enumerator(CookieJar::staticMetaObject.indexOfEnumerator("KeepPolicy"));
- CookieJar::KeepPolicy keepCookies = keepPolicyEnum.keyToValue(value) == -1 ?
- CookieJar::KeepUntilExpire :
- static_cast<CookieJar::KeepPolicy>(keepPolicyEnum.keyToValue(value));
- switch (keepCookies) {
- case CookieJar::KeepUntilExpire:
- keepUntilCombo->setCurrentIndex(0);
- break;
- case CookieJar::KeepUntilExit:
- keepUntilCombo->setCurrentIndex(1);
- break;
- case CookieJar::KeepUntilTimeLimit:
- keepUntilCombo->setCurrentIndex(2);
- break;
- }
settings.endGroup();
-#endif
// Proxy
settings.beginGroup(QLatin1String("proxy"));
@@ -227,47 +201,19 @@ void SettingsDialog::saveToSettings()
settings.setValue(QLatin1String("userStyleSheet"), QUrl::fromLocalFile(userStyleSheetString));
else
settings.setValue(QLatin1String("userStyleSheet"), QUrl(userStyleSheetString));
+ settings.setValue(QLatin1String("httpUserAgent"), httpUserAgent->text());
settings.endGroup();
-#if defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
//Privacy
settings.beginGroup(QLatin1String("cookies"));
- CookieJar::KeepPolicy keepCookies;
- switch (acceptCombo->currentIndex()) {
- default:
- case 0:
- keepCookies = CookieJar::KeepUntilExpire;
- break;
- case 1:
- keepCookies = CookieJar::KeepUntilExit;
- break;
- case 2:
- keepCookies = CookieJar::KeepUntilTimeLimit;
- break;
- }
- QMetaEnum acceptPolicyEnum = CookieJar::staticMetaObject.enumerator(CookieJar::staticMetaObject.indexOfEnumerator("AcceptPolicy"));
- settings.setValue(QLatin1String("acceptCookies"), QLatin1String(acceptPolicyEnum.valueToKey(keepCookies)));
-
- CookieJar::KeepPolicy keepPolicy;
- switch (keepUntilCombo->currentIndex()) {
- default:
- case 0:
- keepPolicy = CookieJar::KeepUntilExpire;
- break;
- case 1:
- keepPolicy = CookieJar::KeepUntilExit;
- break;
- case 2:
- keepPolicy = CookieJar::KeepUntilTimeLimit;
- break;
- }
+ int persistentCookiesPolicy = sessionCookiesCombo->currentIndex();
+ settings.setValue(QLatin1String("persistentCookiesPolicy"), persistentCookiesPolicy);
- QMetaEnum keepPolicyEnum = CookieJar::staticMetaObject.enumerator(CookieJar::staticMetaObject.indexOfEnumerator("KeepPolicy"));
- settings.setValue(QLatin1String("keepCookiesUntil"), QLatin1String(keepPolicyEnum.valueToKey(keepPolicy)));
+ QString pdataPath = persistentDataPath->text();
+ settings.setValue(QLatin1String("persistentDataPath"), pdataPath);
settings.endGroup();
-#endif
// proxy
settings.beginGroup(QLatin1String("proxy"));
diff --git a/examples/webenginewidgets/browser/settings.ui b/examples/webenginewidgets/browser/settings.ui
index 08374ca7a..7cafdae4b 100644
--- a/examples/webenginewidgets/browser/settings.ui
+++ b/examples/webenginewidgets/browser/settings.ui
@@ -1,7 +1,8 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
<class>Settings</class>
- <widget class="QDialog" name="Settings" >
- <property name="geometry" >
+ <widget class="QDialog" name="Settings">
+ <property name="geometry">
<rect>
<x>0</x>
<y>0</y>
@@ -9,64 +10,56 @@
<height>322</height>
</rect>
</property>
- <property name="windowTitle" >
+ <property name="windowTitle">
<string>Settings</string>
</property>
- <layout class="QGridLayout" name="gridLayout" >
- <item row="2" column="0" >
- <widget class="QDialogButtonBox" name="buttonBox" >
- <property name="orientation" >
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="2" column="0">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="standardButtons" >
+ <property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
- <item row="1" column="0" >
- <widget class="QTabWidget" name="tabWidget" >
- <property name="currentIndex" >
- <number>0</number>
+ <item row="1" column="0">
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>4</number>
</property>
- <widget class="QWidget" name="tab" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>627</width>
- <height>243</height>
- </rect>
- </property>
- <attribute name="title" >
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
<string>General</string>
</attribute>
- <layout class="QGridLayout" name="gridLayout_4" >
- <item row="0" column="0" >
- <widget class="QLabel" name="label_3" >
- <property name="text" >
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
<string>Home:</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
- <item row="0" column="1" colspan="2" >
- <widget class="QLineEdit" name="homeLineEdit" />
+ <item row="0" column="1" colspan="2">
+ <widget class="QLineEdit" name="homeLineEdit"/>
</item>
- <item row="1" column="1" >
- <widget class="QPushButton" name="setHomeToCurrentPageButton" >
- <property name="text" >
+ <item row="1" column="1">
+ <widget class="QPushButton" name="setHomeToCurrentPageButton">
+ <property name="text">
<string>Set to current page</string>
</property>
</widget>
</item>
- <item row="1" column="2" >
- <spacer name="horizontalSpacer" >
- <property name="orientation" >
+ <item row="1" column="2">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="sizeHint" stdset="0" >
+ <property name="sizeHint" stdset="0">
<size>
<width>280</width>
<height>18</height>
@@ -74,103 +67,103 @@
</property>
</spacer>
</item>
- <item row="2" column="0" >
- <widget class="QLabel" name="label_4" >
- <property name="text" >
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
<string>Remove history items:</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
- <item row="2" column="1" colspan="2" >
- <widget class="QComboBox" name="expireHistory" >
+ <item row="2" column="1" colspan="2">
+ <widget class="QComboBox" name="expireHistory">
<item>
- <property name="text" >
+ <property name="text">
<string>After one day</string>
</property>
</item>
<item>
- <property name="text" >
+ <property name="text">
<string>After one week</string>
</property>
</item>
<item>
- <property name="text" >
+ <property name="text">
<string>After two weeks</string>
</property>
</item>
<item>
- <property name="text" >
+ <property name="text">
<string>After one month</string>
</property>
</item>
<item>
- <property name="text" >
+ <property name="text">
<string>After one year</string>
</property>
</item>
<item>
- <property name="text" >
+ <property name="text">
<string>Manually</string>
</property>
</item>
</widget>
</item>
- <item row="3" column="0" >
- <widget class="QLabel" name="label_7" >
- <property name="text" >
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
<string>Save downloads to:</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
- <item row="3" column="1" colspan="2" >
- <widget class="QLineEdit" name="downloadsLocation" />
+ <item row="3" column="1" colspan="2">
+ <widget class="QLineEdit" name="downloadsLocation"/>
</item>
- <item row="4" column="0" >
- <widget class="QLabel" name="label_8" >
- <property name="text" >
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_8">
+ <property name="text">
<string>Open links from applications:</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
- <item row="4" column="1" colspan="2" >
- <widget class="QComboBox" name="openLinksIn" >
+ <item row="4" column="1" colspan="2">
+ <widget class="QComboBox" name="openLinksIn">
<item>
- <property name="text" >
+ <property name="text">
<string>In a tab in the current window</string>
</property>
</item>
<item>
- <property name="text" >
+ <property name="text">
<string>In a new window</string>
</property>
</item>
</widget>
</item>
<item row="5" column="1" colspan="2">
- <widget class="QCheckBox" name="enableScrollAnimator" >
- <property name="text" >
- <string>Enable Scroll Animator</string>
+ <widget class="QCheckBox" name="enableScrollAnimator">
+ <property name="text">
+ <string>Enable Scroll Animator</string>
</property>
- <property name="checked" >
- <bool>true</bool>
+ <property name="checked">
+ <bool>true</bool>
</property>
</widget>
</item>
- <item row="6" column="1" colspan="2" >
+ <item row="6" column="1" colspan="2">
<spacer>
- <property name="orientation" >
+ <property name="orientation">
<enum>Qt::Vertical</enum>
</property>
- <property name="sizeHint" stdset="0" >
+ <property name="sizeHint" stdset="0">
<size>
<width>391</width>
<height>262</height>
@@ -180,91 +173,83 @@
</item>
</layout>
</widget>
- <widget class="QWidget" name="tab_3" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>627</width>
- <height>243</height>
- </rect>
- </property>
- <attribute name="title" >
+ <widget class="QWidget" name="tab_3">
+ <attribute name="title">
<string>Appearance</string>
</attribute>
- <layout class="QGridLayout" name="gridLayout_3" >
- <item row="0" column="0" >
- <widget class="QLabel" name="label_5" >
- <property name="text" >
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
<string>Standard font:</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
- <item row="0" column="1" >
- <widget class="QLabel" name="standardLabel" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+ <item row="0" column="1">
+ <widget class="QLabel" name="standardLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="frameShape" >
+ <property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
- <property name="text" >
+ <property name="text">
<string>Times 16</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
- <item row="0" column="2" >
- <widget class="QPushButton" name="standardFontButton" >
- <property name="text" >
+ <item row="0" column="2">
+ <widget class="QPushButton" name="standardFontButton">
+ <property name="text">
<string>Select...</string>
</property>
</widget>
</item>
- <item row="1" column="0" >
- <widget class="QLabel" name="label_6" >
- <property name="text" >
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
<string>Fixed-width font:</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
- <item row="1" column="1" >
- <widget class="QLabel" name="fixedLabel" >
- <property name="frameShape" >
+ <item row="1" column="1">
+ <widget class="QLabel" name="fixedLabel">
+ <property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
- <property name="text" >
+ <property name="text">
<string>Courier 13</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
- <item row="1" column="2" >
- <widget class="QPushButton" name="fixedFontButton" >
- <property name="text" >
+ <item row="1" column="2">
+ <widget class="QPushButton" name="fixedFontButton">
+ <property name="text">
<string>Select...</string>
</property>
</widget>
</item>
- <item row="2" column="1" >
- <spacer name="verticalSpacer" >
- <property name="orientation" >
+ <item row="2" column="1">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
<enum>Qt::Vertical</enum>
</property>
- <property name="sizeHint" stdset="0" >
+ <property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>93</height>
@@ -274,41 +259,33 @@
</item>
</layout>
</widget>
- <widget class="QWidget" name="tab_2" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>627</width>
- <height>243</height>
- </rect>
- </property>
- <attribute name="title" >
+ <widget class="QWidget" name="tab_2">
+ <attribute name="title">
<string>Privacy</string>
</attribute>
- <layout class="QVBoxLayout" name="verticalLayout_3" >
+ <layout class="QVBoxLayout" name="verticalLayout_3">
<item>
- <widget class="QGroupBox" name="groupBox" >
- <property name="title" >
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
<string>Web Content</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_2" >
+ <layout class="QVBoxLayout" name="verticalLayout_2">
<item>
- <widget class="QCheckBox" name="enablePlugins" >
- <property name="text" >
+ <widget class="QCheckBox" name="enablePlugins">
+ <property name="text">
<string>Enable Plugins</string>
</property>
- <property name="checked" >
+ <property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
- <widget class="QCheckBox" name="enableJavascript" >
- <property name="text" >
+ <widget class="QCheckBox" name="enableJavascript">
+ <property name="text">
<string>Enable Javascript</string>
</property>
- <property name="checked" >
+ <property name="checked">
<bool>true</bool>
</property>
</widget>
@@ -317,186 +294,151 @@
</widget>
</item>
<item>
- <widget class="QGroupBox" name="cookiesGroupBox" >
- <property name="title" >
+ <widget class="QGroupBox" name="cookiesGroupBox">
+ <property name="title">
<string>Cookies</string>
</property>
- <layout class="QGridLayout" >
- <item row="0" column="0" >
- <widget class="QLabel" name="label_2" >
- <property name="text" >
- <string>Accept Cookies:</string>
+ <layout class="QGridLayout">
+ <property name="leftMargin">
+ <number>9</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Persistent Cookie Policy</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
- <item row="0" column="1" >
- <widget class="QComboBox" name="acceptCombo" >
+ <item row="0" column="1">
+ <widget class="QComboBox" name="sessionCookiesCombo">
<item>
- <property name="text" >
- <string>Always</string>
+ <property name="text">
+ <string>Treat all cookies as session cookies</string>
</property>
</item>
<item>
- <property name="text" >
- <string>Never</string>
+ <property name="text">
+ <string>Allow persistent cookies</string>
</property>
</item>
<item>
- <property name="text" >
- <string>Only from sites you navigate to</string>
+ <property name="text">
+ <string>Treat all cookies as persistent cookies</string>
</property>
</item>
</widget>
</item>
- <item row="0" column="2" >
- <widget class="QPushButton" name="exceptionsButton" >
- <property name="text" >
- <string>Exceptions...</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" >
- <widget class="QLabel" name="label" >
- <property name="text" >
- <string>Keep until:</string>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Persistent Data Path:</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
- <item row="1" column="1" >
- <widget class="QComboBox" name="keepUntilCombo" >
- <item>
- <property name="text" >
- <string>They expire</string>
- </property>
- </item>
- <item>
- <property name="text" >
- <string>I exit the application</string>
- </property>
- </item>
- <item>
- <property name="text" >
- <string>At most 90 days</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="1" column="2" >
- <widget class="QPushButton" name="cookiesButton" >
- <property name="text" >
- <string>Cookies...</string>
- </property>
- </widget>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="persistentDataPath"/>
</item>
</layout>
</widget>
</item>
<item>
- <spacer>
- <property name="orientation" >
+ <spacer name="verticalSpacer_4">
+ <property name="orientation">
<enum>Qt::Vertical</enum>
</property>
- <property name="sizeHint" stdset="0" >
+ <property name="sizeHint" stdset="0">
<size>
- <width>371</width>
- <height>177</height>
+ <width>20</width>
+ <height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
- <widget class="QWidget" name="tab_4" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>627</width>
- <height>243</height>
- </rect>
- </property>
- <attribute name="title" >
+ <widget class="QWidget" name="tab_4">
+ <attribute name="title">
<string>Proxy</string>
</attribute>
- <layout class="QVBoxLayout" name="verticalLayout" >
+ <layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="QGroupBox" name="proxySupport" >
- <property name="title" >
+ <widget class="QGroupBox" name="proxySupport">
+ <property name="title">
<string>Enable proxy</string>
</property>
- <property name="checkable" >
+ <property name="checkable">
<bool>true</bool>
</property>
- <layout class="QGridLayout" name="gridLayout_6" >
- <item row="0" column="0" >
- <widget class="QLabel" name="label_9" >
- <property name="text" >
+ <layout class="QGridLayout" name="gridLayout_6">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_9">
+ <property name="text">
<string>Type:</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
- <item row="0" column="1" colspan="2" >
- <widget class="QComboBox" name="proxyType" >
+ <item row="0" column="1" colspan="2">
+ <widget class="QComboBox" name="proxyType">
<item>
- <property name="text" >
+ <property name="text">
<string>Socks5</string>
</property>
</item>
<item>
- <property name="text" >
+ <property name="text">
<string>Http</string>
</property>
</item>
</widget>
</item>
- <item row="1" column="0" >
- <widget class="QLabel" name="label_10" >
- <property name="text" >
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_10">
+ <property name="text">
<string>Host:</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
- <item row="1" column="1" colspan="2" >
- <widget class="QLineEdit" name="proxyHostName" />
+ <item row="1" column="1" colspan="2">
+ <widget class="QLineEdit" name="proxyHostName"/>
</item>
- <item row="2" column="0" >
- <widget class="QLabel" name="label_11" >
- <property name="text" >
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_11">
+ <property name="text">
<string>Port:</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
- <item row="2" column="1" >
- <widget class="QSpinBox" name="proxyPort" >
- <property name="maximum" >
+ <item row="2" column="1">
+ <widget class="QSpinBox" name="proxyPort">
+ <property name="maximum">
<number>10000</number>
</property>
- <property name="value" >
+ <property name="value">
<number>1080</number>
</property>
</widget>
</item>
- <item row="2" column="2" >
- <spacer name="horizontalSpacer_2" >
- <property name="orientation" >
+ <item row="2" column="2">
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="sizeHint" stdset="0" >
+ <property name="sizeHint" stdset="0">
<size>
<width>293</width>
<height>20</height>
@@ -504,42 +446,42 @@
</property>
</spacer>
</item>
- <item row="3" column="0" >
- <widget class="QLabel" name="label_12" >
- <property name="text" >
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_12">
+ <property name="text">
<string>User Name:</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
- <item row="3" column="1" colspan="2" >
- <widget class="QLineEdit" name="proxyUserName" />
+ <item row="3" column="1" colspan="2">
+ <widget class="QLineEdit" name="proxyUserName"/>
</item>
- <item row="4" column="0" >
- <widget class="QLabel" name="label_13" >
- <property name="text" >
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_13">
+ <property name="text">
<string>Password:</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
- <item row="4" column="1" colspan="2" >
- <widget class="QLineEdit" name="proxyPassword" >
- <property name="echoMode" >
+ <item row="4" column="1" colspan="2">
+ <widget class="QLineEdit" name="proxyPassword">
+ <property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
- <item row="5" column="0" >
- <spacer name="verticalSpacer_2" >
- <property name="orientation" >
+ <item row="5" column="0">
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
<enum>Qt::Vertical</enum>
</property>
- <property name="sizeHint" stdset="0" >
+ <property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>8</height>
@@ -552,27 +494,27 @@
</item>
</layout>
</widget>
- <widget class="QWidget" name="tab_5" >
- <attribute name="title" >
+ <widget class="QWidget" name="tab_5">
+ <attribute name="title">
<string>Advanced</string>
</attribute>
- <layout class="QGridLayout" name="gridLayout_2" >
- <item row="0" column="0" >
- <widget class="QLabel" name="label_14" >
- <property name="text" >
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_14">
+ <property name="text">
<string>Style Sheet:</string>
</property>
</widget>
</item>
- <item row="0" column="1" >
- <widget class="QLineEdit" name="userStyleSheet" />
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="userStyleSheet"/>
</item>
- <item row="1" column="1" >
- <spacer name="verticalSpacer_3" >
- <property name="orientation" >
+ <item row="2" column="1">
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
<enum>Qt::Vertical</enum>
</property>
- <property name="sizeHint" stdset="0" >
+ <property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>176</height>
@@ -580,6 +522,16 @@
</property>
</spacer>
</item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="httpUserAgent"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_15">
+ <property name="text">
+ <string>HTTP User-Agent:</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</widget>
@@ -594,11 +546,11 @@
<receiver>Settings</receiver>
<slot>accept()</slot>
<hints>
- <hint type="sourcelabel" >
+ <hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
- <hint type="destinationlabel" >
+ <hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
@@ -610,11 +562,11 @@
<receiver>Settings</receiver>
<slot>reject()</slot>
<hints>
- <hint type="sourcelabel" >
+ <hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
- <hint type="destinationlabel" >
+ <hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
diff --git a/examples/webenginewidgets/browser/webview.cpp b/examples/webenginewidgets/browser/webview.cpp
index 5ea273e3a..9b42f2ab2 100644
--- a/examples/webenginewidgets/browser/webview.cpp
+++ b/examples/webenginewidgets/browser/webview.cpp
@@ -97,37 +97,15 @@ BrowserMainWindow *WebPage::mainWindow()
return BrowserApplication::instance()->mainWindow();
}
-#if defined(QWEBENGINEPAGE_ACCEPTNAVIGATIONREQUEST)
-bool WebPage::acceptNavigationRequest(QWebEngineFrame *frame, const QNetworkRequest &request, NavigationType type)
+bool WebPage::acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
{
- // ctrl open in new tab
- // ctrl-shift open in new tab and select
- // ctrl-alt open in new window
- if (type == QWebEnginePage::NavigationTypeLinkClicked
- && (m_keyboardModifiers & Qt::ControlModifier
- || m_pressedButtons == Qt::MidButton)) {
- bool newWindow = (m_keyboardModifiers & Qt::AltModifier);
- WebView *webView;
- if (newWindow) {
- BrowserApplication::instance()->newMainWindow();
- BrowserMainWindow *newMainWindow = BrowserApplication::instance()->mainWindow();
- webView = newMainWindow->currentTab();
- newMainWindow->raise();
- newMainWindow->activateWindow();
- webView->setFocus();
- } else {
- bool selectNewTab = (m_keyboardModifiers & Qt::ShiftModifier);
- webView = mainWindow()->tabWidget()->newTab(selectNewTab);
- }
- webView->load(request);
- m_keyboardModifiers = Qt::NoModifier;
- m_pressedButtons = Qt::NoButton;
- return false;
+ Q_UNUSED(type);
+ if (isMainFrame) {
+ m_loadingUrl = url;
+ emit loadingUrl(m_loadingUrl);
}
- m_loadingUrl = request.url();
- emit loadingUrl(m_loadingUrl);
+ return true;
}
-#endif
bool WebPage::certificateError(const QWebEngineCertificateError &error)
{
diff --git a/examples/webenginewidgets/browser/webview.h b/examples/webenginewidgets/browser/webview.h
index 2cedeb79b..5ed674f6a 100644
--- a/examples/webenginewidgets/browser/webview.h
+++ b/examples/webenginewidgets/browser/webview.h
@@ -65,9 +65,7 @@ public:
BrowserMainWindow *mainWindow();
protected:
-#if defined(QWEBENGINEPAGE_ACCEPTNAVIGATIONREQUEST)
- bool acceptNavigationRequest(QWebEngineFrame *frame, const QNetworkRequest &request, NavigationType type);
-#endif
+ bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame);
QWebEnginePage *createWindow(QWebEnginePage::WebWindowType type);
#if !defined(QT_NO_UITOOLS)
QObject *createPlugin(const QString &classId, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues);
diff --git a/qtwebengine.pro b/qtwebengine.pro
index 366446c7a..5156e4620 100644
--- a/qtwebengine.pro
+++ b/qtwebengine.pro
@@ -1,8 +1,2 @@
load(qt_build_config)
-
-# As long as we are a module separate from the rest of Qt, we want to unconditionally build examples.
-# Once part of Qt 5, this should be removed and we should respect the Qt wide configuration.
-QTWEBENGINE_BUILD_PARTS = $$QT_BUILD_PARTS
-QTWEBENGINE_BUILD_PARTS *= examples
-
load(qt_parts)
diff --git a/src/core/access_token_store_qt.cpp b/src/core/access_token_store_qt.cpp
index 85a91c3f7..791d628ba 100644
--- a/src/core/access_token_store_qt.cpp
+++ b/src/core/access_token_store_qt.cpp
@@ -34,11 +34,27 @@
**
****************************************************************************/
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
#include "access_token_store_qt.h"
-#include <QDebug>
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/public/browser/browser_thread.h"
+
+#include "browser_context_qt.h"
+#include "browser_context_adapter.h"
+#include "content_browser_client_qt.h"
+#include "web_engine_context.h"
+
+using content::AccessTokenStore;
+using content::BrowserThread;
AccessTokenStoreQt::AccessTokenStoreQt()
+ : m_systemRequestContext(0)
{
}
@@ -48,9 +64,23 @@ AccessTokenStoreQt::~AccessTokenStoreQt()
void AccessTokenStoreQt::LoadAccessTokens(const LoadAccessTokensCallbackType& callback)
{
+ BrowserThread::PostTaskAndReply(BrowserThread::UI, FROM_HERE
+ , base::Bind(&AccessTokenStoreQt::performWorkOnUIThread, this)
+ , base::Bind(&AccessTokenStoreQt::respondOnOriginatingThread, this, callback));
+}
+
+void AccessTokenStoreQt::performWorkOnUIThread()
+{
+ m_systemRequestContext = WebEngineContext::current()->defaultBrowserContext()->browserContext()->GetRequestContext();
}
-void AccessTokenStoreQt::SaveAccessToken(const GURL& server_url, const base::string16& access_token)
+void AccessTokenStoreQt::respondOnOriginatingThread(const LoadAccessTokensCallbackType& callback)
{
+ callback.Run(m_accessTokenSet, m_systemRequestContext);
+ m_systemRequestContext = 0;
}
+void AccessTokenStoreQt::SaveAccessToken(const GURL& serverUrl, const base::string16& accessToken)
+{
+ m_accessTokenSet[serverUrl] = accessToken;
+}
diff --git a/src/core/access_token_store_qt.h b/src/core/access_token_store_qt.h
index 2a76681f0..9493da774 100644
--- a/src/core/access_token_store_qt.h
+++ b/src/core/access_token_store_qt.h
@@ -37,20 +37,33 @@
#ifndef ACCESS_TOKEN_STORE_QT_H
#define ACCESS_TOKEN_STORE_QT_H
+#include "base/memory/ref_counted.h"
#include "content/public/browser/access_token_store.h"
-#include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE
+#include <QtCore/qcompilerdetection.h>
+#include <QtCore/QFile>
+#include <QtCore/QScopedPointer>
-class AccessTokenStoreQt : public content::AccessTokenStore
-{
+namespace net {
+class URLRequestContextGetter;
+}
+
+class AccessTokenStoreQt : public content::AccessTokenStore {
public:
AccessTokenStoreQt();
~AccessTokenStoreQt();
- virtual void LoadAccessTokens(const LoadAccessTokensCallbackType& callback) Q_DECL_OVERRIDE;
- virtual void SaveAccessToken(const GURL& server_url, const base::string16& access_token) Q_DECL_OVERRIDE;
+ virtual void LoadAccessTokens(const LoadAccessTokensCallbackType& request) Q_DECL_OVERRIDE;
+ virtual void SaveAccessToken(const GURL& serverUrl, const base::string16& accessToken) Q_DECL_OVERRIDE;
private:
+ void performWorkOnUIThread();
+ void respondOnOriginatingThread(const LoadAccessTokensCallbackType& callback);
+
+
+ net::URLRequestContextGetter *m_systemRequestContext;
+ AccessTokenSet m_accessTokenSet;
+
DISALLOW_COPY_AND_ASSIGN(AccessTokenStoreQt);
};
diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp
new file mode 100644
index 000000000..95ddc4d87
--- /dev/null
+++ b/src/core/browser_context_adapter.cpp
@@ -0,0 +1,316 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "browser_context_adapter.h"
+
+#include "content/public/browser/browser_thread.h"
+#include "browser_context_qt.h"
+#include "content_client_qt.h"
+#include "download_manager_delegate_qt.h"
+#include "web_engine_context.h"
+#include "web_engine_visited_links_manager.h"
+#include "url_request_context_getter_qt.h"
+
+#include "net/proxy/proxy_service.h"
+
+#include <QCoreApplication>
+#include <QDir>
+#include <QString>
+#include <QStringBuilder>
+#include <QStandardPaths>
+
+namespace {
+inline QString buildLocationFromStandardPath(const QString &standardPath, const QString &name) {
+ QString location = standardPath;
+ if (location.isEmpty())
+ location = QDir::homePath() % QLatin1String("/.") % QCoreApplication::applicationName();
+
+ location.append(QLatin1String("/QtWebEngine/") % name);
+ return location;
+}
+}
+
+BrowserContextAdapter::BrowserContextAdapter(bool offTheRecord)
+ : m_offTheRecord(offTheRecord)
+ , m_browserContext(new BrowserContextQt(this))
+ , m_httpCacheType(DiskHttpCache)
+ , m_persistentCookiesPolicy(AllowPersistentCookies)
+ , m_visitedLinksPolicy(TrackVisitedLinksOnDisk)
+ , m_client(0)
+ , m_httpCacheMaxSize(0)
+{
+}
+
+BrowserContextAdapter::BrowserContextAdapter(const QString &storageName)
+ : m_name(storageName)
+ , m_offTheRecord(false)
+ , m_browserContext(new BrowserContextQt(this))
+ , m_httpCacheType(DiskHttpCache)
+ , m_persistentCookiesPolicy(AllowPersistentCookies)
+ , m_visitedLinksPolicy(TrackVisitedLinksOnDisk)
+ , m_httpCacheMaxSize(0)
+{
+}
+
+BrowserContextAdapter::~BrowserContextAdapter()
+{
+ if (m_downloadManagerDelegate)
+ content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE, m_downloadManagerDelegate.take());
+}
+
+void BrowserContextAdapter::setStorageName(const QString &storageName)
+{
+ if (storageName == m_name)
+ return;
+ m_name = storageName;
+ if (m_browserContext->url_request_getter_)
+ m_browserContext->url_request_getter_->updateStorageSettings();
+ m_visitedLinksManager.reset();
+}
+
+void BrowserContextAdapter::setOffTheRecord(bool offTheRecord)
+{
+ if (offTheRecord == m_offTheRecord)
+ return;
+ m_offTheRecord = offTheRecord;
+ if (m_browserContext->url_request_getter_)
+ m_browserContext->url_request_getter_->updateStorageSettings();
+ m_visitedLinksManager.reset();
+}
+
+BrowserContextQt *BrowserContextAdapter::browserContext()
+{
+ return m_browserContext.data();
+}
+
+WebEngineVisitedLinksManager *BrowserContextAdapter::visitedLinksManager()
+{
+ if (!m_visitedLinksManager)
+ m_visitedLinksManager.reset(new WebEngineVisitedLinksManager(this));
+ return m_visitedLinksManager.data();
+}
+
+DownloadManagerDelegateQt *BrowserContextAdapter::downloadManagerDelegate()
+{
+ if (!m_downloadManagerDelegate)
+ m_downloadManagerDelegate.reset(new DownloadManagerDelegateQt(this));
+ return m_downloadManagerDelegate.data();
+}
+
+void BrowserContextAdapter::setClient(BrowserContextAdapterClient *adapterClient)
+{
+ m_client = adapterClient;
+}
+
+void BrowserContextAdapter::cancelDownload(quint32 downloadId)
+{
+ downloadManagerDelegate()->cancelDownload(downloadId);
+}
+
+BrowserContextAdapter* BrowserContextAdapter::defaultContext()
+{
+ return WebEngineContext::current()->defaultBrowserContext();
+}
+
+BrowserContextAdapter* BrowserContextAdapter::offTheRecordContext()
+{
+ return WebEngineContext::current()->offTheRecordBrowserContext();
+}
+
+QString BrowserContextAdapter::dataPath() const
+{
+ if (m_offTheRecord)
+ return QString();
+ if (!m_dataPath.isEmpty())
+ return m_dataPath;
+ if (!m_name.isNull())
+ return buildLocationFromStandardPath(QStandardPaths::writableLocation(QStandardPaths::DataLocation), m_name);
+ return QString();
+}
+
+void BrowserContextAdapter::setDataPath(const QString &path)
+{
+ if (m_dataPath == path)
+ return;
+ m_dataPath = path;
+ if (m_browserContext->url_request_getter_)
+ m_browserContext->url_request_getter_->updateStorageSettings();
+ m_visitedLinksManager.reset();
+}
+
+QString BrowserContextAdapter::cachePath() const
+{
+ if (m_offTheRecord)
+ return QString();
+ if (!m_cachePath.isEmpty())
+ return m_cachePath;
+ if (!m_name.isNull())
+ return buildLocationFromStandardPath(QStandardPaths::writableLocation(QStandardPaths::CacheLocation), m_name);
+ return QString();
+}
+
+void BrowserContextAdapter::setCachePath(const QString &path)
+{
+ if (m_cachePath == path)
+ return;
+ m_cachePath = path;
+ if (m_browserContext->url_request_getter_)
+ m_browserContext->url_request_getter_->updateHttpCache();
+}
+
+QString BrowserContextAdapter::cookiesPath() const
+{
+ if (m_offTheRecord)
+ return QString();
+ QString basePath = dataPath();
+ if (!basePath.isEmpty())
+ return basePath % QLatin1String("/Coookies");
+ return QString();
+}
+
+QString BrowserContextAdapter::httpCachePath() const
+{
+ if (m_offTheRecord)
+ return QString();
+ QString basePath = cachePath();
+ if (!basePath.isEmpty())
+ return basePath % QLatin1String("/Cache");
+ return QString();
+}
+
+QString BrowserContextAdapter::httpUserAgent() const
+{
+ if (m_httpUserAgent.isNull())
+ return QString::fromStdString(ContentClientQt::getUserAgent());
+ return m_httpUserAgent;
+}
+
+void BrowserContextAdapter::setHttpUserAgent(const QString &userAgent)
+{
+ if (m_httpUserAgent == userAgent)
+ return;
+ m_httpUserAgent = userAgent;
+ if (m_browserContext->url_request_getter_)
+ m_browserContext->url_request_getter_->updateUserAgent();
+}
+
+BrowserContextAdapter::HttpCacheType BrowserContextAdapter::httpCacheType() const
+{
+ if (isOffTheRecord() || httpCachePath().isEmpty())
+ return MemoryHttpCache;
+ return m_httpCacheType;
+}
+
+void BrowserContextAdapter::setHttpCacheType(BrowserContextAdapter::HttpCacheType newhttpCacheType)
+{
+ BrowserContextAdapter::HttpCacheType oldCacheType = httpCacheType();
+ m_httpCacheType = newhttpCacheType;
+ if (oldCacheType == httpCacheType())
+ return;
+ if (m_browserContext->url_request_getter_)
+ m_browserContext->url_request_getter_->updateHttpCache();
+}
+
+BrowserContextAdapter::PersistentCookiesPolicy BrowserContextAdapter::persistentCookiesPolicy() const
+{
+ if (isOffTheRecord() || cookiesPath().isEmpty())
+ return NoPersistentCookies;
+ return m_persistentCookiesPolicy;
+}
+
+void BrowserContextAdapter::setPersistentCookiesPolicy(BrowserContextAdapter::PersistentCookiesPolicy newPersistentCookiesPolicy)
+{
+ BrowserContextAdapter::PersistentCookiesPolicy oldPolicy = persistentCookiesPolicy();
+ m_persistentCookiesPolicy = newPersistentCookiesPolicy;
+ if (oldPolicy == persistentCookiesPolicy())
+ return;
+ if (m_browserContext->url_request_getter_)
+ m_browserContext->url_request_getter_->updateCookieStore();
+}
+
+BrowserContextAdapter::VisitedLinksPolicy BrowserContextAdapter::visitedLinksPolicy() const
+{
+ if (isOffTheRecord() || m_visitedLinksPolicy == DoNotTrackVisitedLinks)
+ return DoNotTrackVisitedLinks;
+ if (dataPath().isEmpty())
+ return TrackVisitedLinksInMemory;
+ return m_visitedLinksPolicy;
+}
+
+bool BrowserContextAdapter::trackVisitedLinks() const
+{
+ switch (visitedLinksPolicy()) {
+ case DoNotTrackVisitedLinks:
+ return false;
+ default:
+ break;
+ }
+ return true;
+}
+
+bool BrowserContextAdapter::persistVisitedLinks() const
+{
+ switch (visitedLinksPolicy()) {
+ case DoNotTrackVisitedLinks:
+ case TrackVisitedLinksInMemory:
+ return false;
+ default:
+ break;
+ }
+ return true;
+}
+
+void BrowserContextAdapter::setVisitedLinksPolicy(BrowserContextAdapter::VisitedLinksPolicy visitedLinksPolicy)
+{
+ if (m_visitedLinksPolicy == visitedLinksPolicy)
+ return;
+ m_visitedLinksPolicy = visitedLinksPolicy;
+ m_visitedLinksManager.reset();
+}
+
+int BrowserContextAdapter::httpCacheMaxSize() const
+{
+ return m_httpCacheMaxSize;
+}
+
+void BrowserContextAdapter::setHttpCacheMaxSize(int maxSize)
+{
+ if (m_httpCacheMaxSize == maxSize)
+ return;
+ m_httpCacheMaxSize = maxSize;
+ if (m_browserContext->url_request_getter_)
+ m_browserContext->url_request_getter_->updateHttpCache();
+}
diff --git a/src/core/browser_context_adapter.h b/src/core/browser_context_adapter.h
new file mode 100644
index 000000000..1c12c465d
--- /dev/null
+++ b/src/core/browser_context_adapter.h
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BROWSER_CONTEXT_ADAPTER_H
+#define BROWSER_CONTEXT_ADAPTER_H
+
+#include "qtwebenginecoreglobal.h"
+
+#include <QScopedPointer>
+#include <QSharedData>
+#include <QString>
+
+class BrowserContextAdapterClient;
+class BrowserContextQt;
+class DownloadManagerDelegateQt;
+class WebEngineVisitedLinksManager;
+
+class QWEBENGINE_EXPORT BrowserContextAdapter : public QSharedData
+{
+public:
+ explicit BrowserContextAdapter(bool offTheRecord = false);
+ explicit BrowserContextAdapter(const QString &storagePrefix);
+ virtual ~BrowserContextAdapter();
+
+ static BrowserContextAdapter* defaultContext();
+ static BrowserContextAdapter* offTheRecordContext();
+
+ WebEngineVisitedLinksManager *visitedLinksManager();
+ DownloadManagerDelegateQt *downloadManagerDelegate();
+
+ BrowserContextAdapterClient* client() { return m_client; }
+
+ void setClient(BrowserContextAdapterClient *adapterClient);
+ void cancelDownload(quint32 downloadId);
+
+ BrowserContextQt *browserContext();
+
+ QString storageName() const { return m_name; }
+ void setStorageName(const QString &storageName);
+
+ bool isOffTheRecord() const { return m_offTheRecord; }
+ void setOffTheRecord(bool offTheRecord);
+
+ QString dataPath() const;
+ void setDataPath(const QString &path);
+
+ QString cachePath() const;
+ void setCachePath(const QString &path);
+
+ QString httpCachePath() const;
+ QString cookiesPath() const;
+
+ QString httpUserAgent() const;
+ void setHttpUserAgent(const QString &userAgent);
+
+ // KEEP IN SYNC with API or add mapping layer
+ enum HttpCacheType {
+ MemoryHttpCache = 0,
+ DiskHttpCache
+ };
+
+ enum PersistentCookiesPolicy {
+ NoPersistentCookies = 0,
+ AllowPersistentCookies,
+ ForcePersistentCookies
+ };
+
+ enum VisitedLinksPolicy {
+ DoNotTrackVisitedLinks = 0,
+ TrackVisitedLinksInMemory,
+ TrackVisitedLinksOnDisk,
+ };
+
+ HttpCacheType httpCacheType() const;
+ void setHttpCacheType(BrowserContextAdapter::HttpCacheType);
+
+ PersistentCookiesPolicy persistentCookiesPolicy() const;
+ void setPersistentCookiesPolicy(BrowserContextAdapter::PersistentCookiesPolicy);
+
+ VisitedLinksPolicy visitedLinksPolicy() const;
+ void setVisitedLinksPolicy(BrowserContextAdapter::VisitedLinksPolicy);
+
+ int httpCacheMaxSize() const;
+ void setHttpCacheMaxSize(int maxSize);
+
+ bool trackVisitedLinks() const;
+ bool persistVisitedLinks() const;
+
+private:
+ QString m_name;
+ bool m_offTheRecord;
+ QScopedPointer<BrowserContextQt> m_browserContext;
+ QScopedPointer<WebEngineVisitedLinksManager> m_visitedLinksManager;
+ QScopedPointer<DownloadManagerDelegateQt> m_downloadManagerDelegate;
+ QString m_dataPath;
+ QString m_cachePath;
+ QString m_httpUserAgent;
+ HttpCacheType m_httpCacheType;
+ PersistentCookiesPolicy m_persistentCookiesPolicy;
+ VisitedLinksPolicy m_visitedLinksPolicy;
+ BrowserContextAdapterClient *m_client;
+ int m_httpCacheMaxSize;
+
+ Q_DISABLE_COPY(BrowserContextAdapter)
+};
+
+#endif // BROWSER_CONTEXT_ADAPTER_H
diff --git a/src/core/browser_context_adapter_client.h b/src/core/browser_context_adapter_client.h
new file mode 100644
index 000000000..2b6b4f434
--- /dev/null
+++ b/src/core/browser_context_adapter_client.h
@@ -0,0 +1,63 @@
+ /****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BROWSER_CONTEXT_ADAPTER_CLIENT_H
+#define BROWSER_CONTEXT_ADAPTER_CLIENT_H
+
+#include "qtwebenginecoreglobal.h"
+#include <QString>
+
+class QWEBENGINE_EXPORT BrowserContextAdapterClient
+{
+public:
+ // Keep in sync with content::DownloadItem::DownloadState
+ enum DownloadState {
+ // Download is actively progressing.
+ DownloadInProgress = 0,
+ // Download is completely finished.
+ DownloadCompleted,
+ // Download has been cancelled.
+ DownloadCancelled,
+ // This state indicates that the download has been interrupted.
+ DownloadInterrupted
+ };
+ virtual ~BrowserContextAdapterClient() { }
+
+ virtual void downloadRequested(quint32 downloadId, QString &downloadPath, bool &cancelled) = 0;
+ virtual void downloadUpdated(quint32 downloadId, int downloadState, int percentComplete) = 0;
+};
+
+#endif // BROWSER_CONTEXT_ADAPTER_CLIENT_H
diff --git a/src/core/browser_context_qt.cpp b/src/core/browser_context_qt.cpp
index 44b6ca4ef..4661f59fc 100644
--- a/src/core/browser_context_qt.cpp
+++ b/src/core/browser_context_qt.cpp
@@ -36,27 +36,21 @@
#include "browser_context_qt.h"
+#include "browser_context_adapter.h"
+#include "download_manager_delegate_qt.h"
#include "type_conversion.h"
#include "qtwebenginecoreglobal.h"
#include "resource_context_qt.h"
#include "url_request_context_getter_qt.h"
-#include "base/files/scoped_temp_dir.h"
#include "base/time/time.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "net/proxy/proxy_config_service.h"
-#include <QByteArray>
-#include <QCoreApplication>
-#include <QDir>
-#include <QStandardPaths>
-#include <QString>
-#include <QStringBuilder>
-
-BrowserContextQt::BrowserContextQt()
+BrowserContextQt::BrowserContextQt(BrowserContextAdapter *adapter)
+ : m_adapter(adapter)
{
- resourceContext.reset(new ResourceContextQt(this));
}
BrowserContextQt::~BrowserContextQt()
@@ -67,29 +61,17 @@ BrowserContextQt::~BrowserContextQt()
base::FilePath BrowserContextQt::GetPath() const
{
- QString dataLocation = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
- if (dataLocation.isEmpty())
- dataLocation = QDir::homePath() % QDir::separator() % QChar::fromLatin1('.') % QCoreApplication::applicationName();
-
- dataLocation.append(QDir::separator() % QLatin1String("QtWebEngine"));
- dataLocation.append(QDir::separator() % QLatin1String("Default"));
- return base::FilePath(toFilePathString(dataLocation));
+ return toFilePath(m_adapter->dataPath());
}
base::FilePath BrowserContextQt::GetCachePath() const
{
- QString cacheLocation = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
- if (cacheLocation.isEmpty())
- cacheLocation = QDir::homePath() % QDir::separator() % QChar::fromLatin1('.') % QCoreApplication::applicationName();
-
- cacheLocation.append(QDir::separator() % QLatin1String("QtWebEngine"));
- cacheLocation.append(QDir::separator() % QLatin1String("Default"));
- return base::FilePath(toFilePathString(cacheLocation));
+ return toFilePath(m_adapter->cachePath());
}
bool BrowserContextQt::IsOffTheRecord() const
{
- return false;
+ return m_adapter->isOffTheRecord();
}
net::URLRequestContextGetter *BrowserContextQt::GetRequestContext()
@@ -119,12 +101,14 @@ net::URLRequestContextGetter *BrowserContextQt::GetMediaRequestContextForStorage
content::ResourceContext *BrowserContextQt::GetResourceContext()
{
+ if (!resourceContext)
+ resourceContext.reset(new ResourceContextQt(this));
return resourceContext.get();
}
content::DownloadManagerDelegate *BrowserContextQt::GetDownloadManagerDelegate()
{
- return downloadManagerDelegate.get();
+ return m_adapter->downloadManagerDelegate();
}
content::BrowserPluginGuestManager *BrowserContextQt::GetGuestManager()
@@ -145,7 +129,7 @@ content::PushMessagingService *BrowserContextQt::GetPushMessagingService()
net::URLRequestContextGetter *BrowserContextQt::CreateRequestContext(content::ProtocolHandlerMap *protocol_handlers)
{
- url_request_getter_ = new URLRequestContextGetterQt(GetPath(), GetCachePath(), protocol_handlers);
- static_cast<ResourceContextQt*>(resourceContext.get())->set_url_request_context_getter(url_request_getter_.get());
+ url_request_getter_ = new URLRequestContextGetterQt(m_adapter, protocol_handlers);
+ static_cast<ResourceContextQt*>(GetResourceContext())->set_url_request_context_getter(url_request_getter_.get());
return url_request_getter_.get();
}
diff --git a/src/core/browser_context_qt.h b/src/core/browser_context_qt.h
index 125c0fc46..8ab6024ae 100644
--- a/src/core/browser_context_qt.h
+++ b/src/core/browser_context_qt.h
@@ -41,12 +41,16 @@
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/resource_context.h"
#include "net/url_request/url_request_context.h"
-#include "download_manager_delegate_qt.h"
+
+#include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE
+
+class BrowserContextAdapter;
+class URLRequestContextGetterQt;
class BrowserContextQt : public content::BrowserContext
{
public:
- explicit BrowserContextQt();
+ explicit BrowserContextQt(BrowserContextAdapter *);
virtual ~BrowserContextQt();
@@ -68,8 +72,9 @@ public:
private:
scoped_ptr<content::ResourceContext> resourceContext;
- scoped_refptr<net::URLRequestContextGetter> url_request_getter_;
- scoped_ptr<DownloadManagerDelegateQt> downloadManagerDelegate;
+ scoped_refptr<URLRequestContextGetterQt> url_request_getter_;
+ BrowserContextAdapter *m_adapter;
+ friend class BrowserContextAdapter;
DISALLOW_COPY_AND_ASSIGN(BrowserContextQt);
};
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 4948d1d8d..6dfaa64c7 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -55,17 +55,22 @@
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_share_group.h"
+#include "access_token_store_qt.h"
#include "browser_context_qt.h"
#include "certificate_error_controller.h"
#include "certificate_error_controller_p.h"
#include "desktop_screen_qt.h"
#include "dev_tools_http_handler_delegate_qt.h"
+#ifdef QT_USE_POSITIONING
+#include "location_provider_qt.h"
+#endif
#include "media_capture_devices_dispatcher.h"
#include "resource_dispatcher_host_delegate_qt.h"
#include "web_contents_delegate_qt.h"
#include "access_token_store_qt.h"
#include <QGuiApplication>
+#include <QLocale>
#include <QOpenGLContext>
#include <qpa/qplatformnativeinterface.h>
@@ -203,12 +208,10 @@ public:
void PreMainMessageLoopRun() Q_DECL_OVERRIDE
{
- m_browserContext.reset(new BrowserContextQt());
}
void PostMainMessageLoopRun()
{
- m_browserContext.reset();
}
int PreCreateThreads() Q_DECL_OVERRIDE
@@ -219,13 +222,7 @@ public:
return 0;
}
- BrowserContextQt* browser_context() const {
- return m_browserContext.get();
- }
-
private:
- scoped_ptr<BrowserContextQt> m_browserContext;
-
DISALLOW_COPY_AND_ASSIGN(BrowserMainPartsQt);
};
@@ -246,7 +243,7 @@ public:
m_handle = pni->nativeResourceForContext(QByteArrayLiteral("cglcontextobj"), qtContext);
else if (platform == QLatin1String("qnx"))
m_handle = pni->nativeResourceForContext(QByteArrayLiteral("eglcontext"), qtContext);
- else if (platform == QLatin1String("eglfs"))
+ else if (platform == QLatin1String("eglfs") || platform == QLatin1String("wayland"))
m_handle = pni->nativeResourceForContext(QByteArrayLiteral("eglcontext"), qtContext);
else if (platform == QLatin1String("windows")) {
if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
@@ -364,22 +361,15 @@ content::AccessTokenStore *ContentBrowserClientQt::CreateAccessTokenStore()
return new AccessTokenStoreQt;
}
-BrowserContextQt* ContentBrowserClientQt::browser_context() {
- Q_ASSERT(m_browserMainParts);
- return static_cast<BrowserMainPartsQt*>(m_browserMainParts)->browser_context();
-}
-
-net::URLRequestContextGetter* ContentBrowserClientQt::CreateRequestContext(content::BrowserContext* content_browser_context, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors)
+net::URLRequestContextGetter* ContentBrowserClientQt::CreateRequestContext(content::BrowserContext* browser_context, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors)
{
- if (content_browser_context != browser_context())
- fprintf(stderr, "Warning: off the record browser context not implemented !\n");
- return static_cast<BrowserContextQt*>(browser_context())->CreateRequestContext(protocol_handlers);
+ return static_cast<BrowserContextQt*>(browser_context)->CreateRequestContext(protocol_handlers);
}
-void ContentBrowserClientQt::enableInspector(bool enable)
+void ContentBrowserClientQt::enableInspector(bool enable, content::BrowserContext* browser_context)
{
if (enable && !m_devtools) {
- m_devtools.reset(new DevToolsHttpHandlerDelegateQt(browser_context()));
+ m_devtools.reset(new DevToolsHttpHandlerDelegateQt(browser_context));
} else if (!enable && m_devtools) {
m_devtools.reset();
}
@@ -409,19 +399,28 @@ void ContentBrowserClientQt::AllowCertificateError(int render_process_id, int re
contentsDelegate->allowCertificateError(errorController);
}
-void ContentBrowserClientQt::RequestGeolocationPermission(content::WebContents *webContents,
- int bridge_id,
- const GURL &requesting_frame,
- bool user_gesture,
- base::Callback<void(bool)> result_callback,
- base::Closure *cancel_callback)
+void ContentBrowserClientQt::RequestGeolocationPermission(content::WebContents *webContents, int /*bridgeId*/, const GURL &requestingFrameOrigin, bool /*userGesture*/, base::Callback<void (bool)> resultCallback, base::Closure *cancelCallback)
+{
+ WebContentsDelegateQt* contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
+ Q_ASSERT(contentsDelegate);
+ contentsDelegate->requestGeolocationPermission(requestingFrameOrigin, resultCallback, cancelCallback);
+}
+
+blink::WebNotificationPresenter::Permission ContentBrowserClientQt::CheckDesktopNotificationPermission(const GURL&, content::ResourceContext *, int )
+{
+ return blink::WebNotificationPresenter::PermissionDenied;
+}
+
+content::LocationProvider *ContentBrowserClientQt::OverrideSystemLocationProvider()
+{
+#ifdef QT_USE_POSITIONING
+ return new LocationProviderQt;
+#else
+ return 0; // Leave it up to Chromium to figure something out.
+#endif
+}
+
+std::string ContentBrowserClientQt::GetApplicationLocale()
{
- Q_UNUSED(webContents);
- Q_UNUSED(bridge_id);
- Q_UNUSED(requesting_frame);
- Q_UNUSED(user_gesture);
- Q_UNUSED(cancel_callback);
-
- // TODO: Add geolocation support
- result_callback.Run(false);
+ return QLocale().name().toStdString();
}
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index f1ecf5825..d5b49e835 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -52,6 +52,7 @@ class BrowserContext;
class BrowserMainParts;
class RenderProcessHost;
class RenderViewHostDelegateView;
+class ResourceContext;
class WebContentsViewPort;
class WebContents;
struct MainFunctionParams;
@@ -78,9 +79,9 @@ public:
virtual void ResourceDispatcherHostCreated() Q_DECL_OVERRIDE;
virtual gfx::GLShareGroup* GetInProcessGpuShareGroup() Q_DECL_OVERRIDE;
virtual content::MediaObserver* GetMediaObserver() Q_DECL_OVERRIDE;
- virtual void OverrideWebkitPrefs(content::RenderViewHost *, const GURL &, WebPreferences *) Q_DECL_OVERRIDE;
- virtual content::AccessTokenStore *CreateAccessTokenStore() Q_DECL_OVERRIDE;
+ virtual content::AccessTokenStore* CreateAccessTokenStore() Q_DECL_OVERRIDE;
virtual content::QuotaPermissionContext *CreateQuotaPermissionContext() Q_DECL_OVERRIDE;
+ virtual void OverrideWebkitPrefs(content::RenderViewHost *, const GURL &, WebPreferences *) Q_DECL_OVERRIDE;
virtual void AllowCertificateError(
int render_process_id,
int render_frame_id,
@@ -92,19 +93,18 @@ public:
bool strict_enforcement,
const base::Callback<void(bool)>& callback,
content::CertificateRequestResultType* result) Q_DECL_OVERRIDE;
- virtual void RequestGeolocationPermission(
- content::WebContents *webContents,
- int bridge_id,
- const GURL &requesting_frame,
- bool user_gesture,
- base::Callback<void(bool)> result_callback,
- base::Closure *cancel_callback) Q_DECL_OVERRIDE;
+ void RequestGeolocationPermission(content::WebContents* web_contents, int, const GURL& requesting_frame
+ , bool, base::Callback<void(bool)> resultCallback
+ , base::Closure* cancelCallback) Q_DECL_OVERRIDE;
+ content::LocationProvider* OverrideSystemLocationProvider() Q_DECL_OVERRIDE;
+
+ virtual net::URLRequestContextGetter *CreateRequestContext(content::BrowserContext *browser_context, content::ProtocolHandlerMap *protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptorss) Q_DECL_OVERRIDE;
- BrowserContextQt* browser_context();
+ virtual blink::WebNotificationPresenter::Permission CheckDesktopNotificationPermission(const GURL& source_origin, content::ResourceContext* context, int render_process_id) Q_DECL_OVERRIDE;
- virtual net::URLRequestContextGetter *CreateRequestContext(content::BrowserContext *content_browser_context, content::ProtocolHandlerMap *protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptorss) Q_DECL_OVERRIDE;
+ virtual std::string GetApplicationLocale() Q_DECL_OVERRIDE;
- void enableInspector(bool);
+ void enableInspector(bool enable, content::BrowserContext *browser_context);
private:
BrowserMainPartsQt* m_browserMainParts;
diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp
index e41888976..44dc0b8bd 100644
--- a/src/core/content_main_delegate_qt.cpp
+++ b/src/core/content_main_delegate_qt.cpp
@@ -52,6 +52,8 @@
#include "renderer/content_renderer_client_qt.h"
#include "web_engine_library_info.h"
+#include <QLocale>
+
static base::StringPiece PlatformResourceProvider(int key) {
if (key == IDR_DIR_HEADER_HTML) {
base::StringPiece html_data = ui::ResourceBundle::GetSharedInstance().GetRawDataResource(IDR_DIR_HEADER_HTML);
@@ -63,7 +65,7 @@ static base::StringPiece PlatformResourceProvider(int key) {
void ContentMainDelegateQt::PreSandboxStartup()
{
net::NetModule::SetResourceProvider(PlatformResourceProvider);
- ui::ResourceBundle::InitSharedInstanceWithLocale(l10n_util::GetApplicationLocale(std::string("en-US")), 0);
+ ui::ResourceBundle::InitSharedInstanceWithLocale(QLocale().name().toStdString(), 0);
// Suppress info, warning and error messages per default.
int logLevel = logging::LOG_FATAL;
diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro
index 3817c334b..ae2422957 100644
--- a/src/core/core_gyp_generator.pro
+++ b/src/core/core_gyp_generator.pro
@@ -11,7 +11,7 @@ TEMPLATE = lib
# gyp/ninja will take care of the compilation, qmake/make will finish with linking and install.
TARGET = QtWebEngineCore
QT += qml quick
-QT_PRIVATE += gui-private
+QT_PRIVATE += quick-private gui-private core-private
# Defining keywords such as 'signal' clashes with the chromium code base.
DEFINES += QT_NO_KEYWORDS \
@@ -35,6 +35,7 @@ SOURCES = \
access_token_store_qt.cpp \
browser_accessibility_manager_qt.cpp \
browser_accessibility_qt.cpp \
+ browser_context_adapter.cpp \
browser_context_qt.cpp \
certificate_error_controller.cpp \
chromium_gpu_helper.cpp \
@@ -83,6 +84,8 @@ HEADERS = \
access_token_store_qt.h \
browser_accessibility_manager_qt.h \
browser_accessibility_qt.h \
+ browser_context_adapter.h \
+ browser_context_adapter_client.h \
browser_context_qt.h \
certificate_error_controller_p.h \
certificate_error_controller.h \
@@ -116,6 +119,7 @@ HEADERS = \
resource_dispatcher_host_delegate_qt.h \
stream_video_node.h \
surface_factory_qt.h \
+ type_conversion.h \
url_request_context_getter_qt.h \
url_request_qrc_job_qt.h \
web_contents_adapter.h \
@@ -130,3 +134,10 @@ HEADERS = \
web_engine_visited_links_manager.h \
web_event_factory.h \
yuv_video_node.h
+
+qtHaveModule(positioning) {
+ SOURCES += location_provider_qt.cpp
+ HEADERS += location_provider_qt.h
+ DEFINES += QT_USE_POSITIONING=1
+ QT += positioning
+}
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index 8e445bd3a..e6933cc4b 100644
--- a/src/core/core_module.pro
+++ b/src/core/core_module.pro
@@ -1,8 +1,9 @@
MODULE = webenginecore
TARGET = QtWebEngineCore
+qtHaveModule(positioning):QT += positioning
QT += qml quick
-QT_PRIVATE += gui-private
+QT_PRIVATE += quick-private gui-private core-private
# Needed to set a CFBundleIdentifier
QMAKE_INFO_PLIST = Info_mac.plist
diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp
index e12873c81..8d09794be 100644
--- a/src/core/delegated_frame_node.cpp
+++ b/src/core/delegated_frame_node.cpp
@@ -55,6 +55,7 @@
#include "base/bind.h"
#include "cc/output/delegated_frame_data.h"
#include "cc/quads/checkerboard_draw_quad.h"
+#include "cc/quads/debug_border_draw_quad.h"
#include "cc/quads/draw_quad.h"
#include "cc/quads/render_pass_draw_quad.h"
#include "cc/quads/solid_color_draw_quad.h"
@@ -62,80 +63,60 @@
#include "cc/quads/texture_draw_quad.h"
#include "cc/quads/tile_draw_quad.h"
#include "cc/quads/yuv_video_draw_quad.h"
+#include "content/common/host_shared_bitmap_manager.h"
#include <QOpenGLContext>
-#include <QOpenGLFramebufferObject>
#include <QOpenGLFunctions>
-#include <QSGAbstractRenderer>
-#include <QSGEngine>
#include <QSGSimpleRectNode>
#include <QSGSimpleTextureNode>
#include <QSGTexture>
+#include <private/qsgadaptationlayer_p.h>
#if !defined(QT_NO_EGL)
#include <EGL/egl.h>
#include <EGL/eglext.h>
#endif
-class RenderPassTexture : public QSGTexture, protected QOpenGLFunctions
-{
-public:
- RenderPassTexture(const cc::RenderPass::Id &id);
-
- const cc::RenderPass::Id &id() const { return m_id; }
- void bind();
-
- int textureId() const { return m_fbo ? m_fbo->texture() : 0; }
- QSize textureSize() const { return m_rect.size(); }
- bool hasAlphaChannel() const { return m_format != GL_RGB; }
- bool hasMipmaps() const { return false; }
-
- void setRect(const QRect &rect) { m_rect = rect; }
- void setFormat(GLenum format) { m_format = format; }
- QSGNode *rootNode() { return m_rootNode.data(); }
-
- void grab();
-
-private:
- cc::RenderPass::Id m_id;
- QRect m_rect;
- GLenum m_format;
-
- QScopedPointer<QSGEngine> m_sgEngine;
- QScopedPointer<QSGRootNode> m_rootNode;
- QScopedPointer<QSGAbstractRenderer> m_renderer;
- QScopedPointer<QOpenGLFramebufferObject> m_fbo;
-};
-
class MailboxTexture : public QSGTexture, protected QOpenGLFunctions {
public:
- MailboxTexture(const cc::TransferableResource &resource);
+ MailboxTexture(const gpu::MailboxHolder &mailboxHolder, const QSize textureSize);
virtual int textureId() const Q_DECL_OVERRIDE { return m_textureId; }
- void setTextureSize(const QSize& size) { m_textureSize = size; }
virtual QSize textureSize() const Q_DECL_OVERRIDE { return m_textureSize; }
virtual bool hasAlphaChannel() const Q_DECL_OVERRIDE { return m_hasAlpha; }
void setHasAlphaChannel(bool hasAlpha) { m_hasAlpha = hasAlpha; }
virtual bool hasMipmaps() const Q_DECL_OVERRIDE { return false; }
virtual void bind() Q_DECL_OVERRIDE;
- bool needsToFetch() const { return !m_textureId; }
- cc::TransferableResource &resource() { return m_resource; }
- cc::ReturnedResource returnResource();
+ gpu::MailboxHolder &mailboxHolder() { return m_mailboxHolder; }
void fetchTexture(gpu::gles2::MailboxManager *mailboxManager);
void setTarget(GLenum target);
- void incImportCount() { ++m_importCount; }
private:
- cc::TransferableResource m_resource;
+ gpu::MailboxHolder m_mailboxHolder;
int m_textureId;
QSize m_textureSize;
bool m_hasAlpha;
GLenum m_target;
- int m_importCount;
#ifdef Q_OS_QNX
EGLStreamData m_eglStreamData;
#endif
};
+class ResourceHolder {
+public:
+ ResourceHolder(const cc::TransferableResource &resource);
+ QSharedPointer<QSGTexture> initTexture(bool quadIsAllOpaque, RenderWidgetHostViewQtDelegate *apiDelegate = 0);
+ QSGTexture *texture() const { return m_texture.data(); }
+ cc::TransferableResource &transferableResource() { return m_resource; }
+ cc::ReturnedResource returnResource();
+ void incImportCount() { ++m_importCount; }
+ bool needsToFetch() const { return !m_resource.is_software && m_texture && !m_texture.data()->textureId(); }
+
+private:
+ QWeakPointer<QSGTexture> m_texture;
+ cc::TransferableResource m_resource;
+ int m_importCount;
+};
+
class RectClipNode : public QSGClipNode
{
public:
@@ -144,23 +125,13 @@ private:
QSGGeometry m_geometry;
};
-static inline QSharedPointer<RenderPassTexture> findRenderPassTexture(const cc::RenderPass::Id &id, const QList<QSharedPointer<RenderPassTexture> > &list)
-{
- Q_FOREACH (const QSharedPointer<RenderPassTexture> &texture, list)
- if (texture->id() == id)
- return texture;
- return QSharedPointer<RenderPassTexture>();
-}
-
-static inline QSharedPointer<MailboxTexture> &findMailboxTexture(unsigned resourceId
- , QHash<unsigned, QSharedPointer<MailboxTexture> > &usedTextures
- , QHash<unsigned, QSharedPointer<MailboxTexture> > &candidateTextures)
+static inline QSharedPointer<QSGLayer> findRenderPassLayer(const cc::RenderPass::Id &id, const QList<QPair<cc::RenderPass::Id, QSharedPointer<QSGLayer> > > &list)
{
- QSharedPointer<MailboxTexture> &texture = usedTextures[resourceId];
- if (!texture)
- texture = candidateTextures.take(resourceId);
- Q_ASSERT(texture);
- return texture;
+ typedef QPair<cc::RenderPass::Id, QSharedPointer<QSGLayer> > Pair;
+ Q_FOREACH (const Pair &pair, list)
+ if (pair.first == id)
+ return pair.second;
+ return QSharedPointer<QSGLayer>();
}
static QSGNode *buildRenderPassChain(QSGNode *chainParent)
@@ -294,59 +265,20 @@ static void deleteChromiumSync(gfx::TransferableFence *sync)
Q_ASSERT(!*sync);
}
-RenderPassTexture::RenderPassTexture(const cc::RenderPass::Id &id)
- : QSGTexture()
- , m_id(id)
- , m_format(GL_RGBA)
- , m_sgEngine(new QSGEngine)
- , m_rootNode(new QSGRootNode)
-{
- initializeOpenGLFunctions();
-}
-
-void RenderPassTexture::bind()
-{
- glBindTexture(GL_TEXTURE_2D, m_fbo ? m_fbo->texture() : 0);
- updateBindOptions();
-}
-
-void RenderPassTexture::grab()
-{
- if (!m_renderer) {
- m_sgEngine->initialize(QOpenGLContext::currentContext());
- m_renderer.reset(m_sgEngine->createRenderer());
- m_renderer->setRootNode(m_rootNode.data());
- }
-
- if (!m_fbo || m_fbo->size() != m_rect.size() || m_fbo->format().internalTextureFormat() != m_format)
- {
- QOpenGLFramebufferObjectFormat format;
- format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
- format.setInternalTextureFormat(m_format);
-
- m_fbo.reset(new QOpenGLFramebufferObject(m_rect.size(), format));
- glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
- updateBindOptions(true);
- }
-
- m_renderer->setDeviceRect(m_rect.size());
- m_renderer->setViewportRect(m_rect.size());
- QRectF mirrored(m_rect.left(), m_rect.bottom(), m_rect.width(), -m_rect.height());
- m_renderer->setProjectionMatrixToRect(mirrored);
- m_renderer->setClearColor(Qt::transparent);
-
- m_renderer->renderScene(m_fbo->handle());
-}
-
-MailboxTexture::MailboxTexture(const cc::TransferableResource &resource)
- : m_resource(resource)
+MailboxTexture::MailboxTexture(const gpu::MailboxHolder &mailboxHolder, const QSize textureSize)
+ : m_mailboxHolder(mailboxHolder)
, m_textureId(0)
- , m_textureSize(toQt(resource.size))
+ , m_textureSize(textureSize)
, m_hasAlpha(false)
, m_target(GL_TEXTURE_2D)
- , m_importCount(1)
{
initializeOpenGLFunctions();
+
+ // Assume that resources without a size will be used with a full source rect.
+ // Setting a size of 1x1 will let any texture node compute a normalized source
+ // rect of (0, 0) to (1, 1) while an empty texture size would set (0, 0) on all corners.
+ if (m_textureSize.isEmpty())
+ m_textureSize = QSize(1, 1);
}
void MailboxTexture::bind()
@@ -373,7 +305,55 @@ void MailboxTexture::setTarget(GLenum target)
m_target = target;
}
-cc::ReturnedResource MailboxTexture::returnResource()
+void MailboxTexture::fetchTexture(gpu::gles2::MailboxManager *mailboxManager)
+{
+ gpu::gles2::Texture *tex = ConsumeTexture(mailboxManager, m_target, m_mailboxHolder.mailbox);
+
+ // The texture might already have been deleted (e.g. when navigating away from a page).
+ if (tex) {
+ m_textureId = service_id(tex);
+#ifdef Q_OS_QNX
+ if (m_target == GL_TEXTURE_EXTERNAL_OES) {
+ m_eglStreamData = eglstream_connect_consumer(tex);
+ }
+#endif
+ }
+}
+
+ResourceHolder::ResourceHolder(const cc::TransferableResource &resource)
+ : m_resource(resource)
+ , m_importCount(1)
+{
+}
+
+QSharedPointer<QSGTexture> ResourceHolder::initTexture(bool quadNeedsBlending, RenderWidgetHostViewQtDelegate *apiDelegate)
+{
+ QSharedPointer<QSGTexture> texture = m_texture.toStrongRef();
+ if (!texture) {
+ if (m_resource.is_software) {
+ Q_ASSERT(apiDelegate);
+ scoped_ptr<cc::SharedBitmap> sharedBitmap = content::HostSharedBitmapManager::current()->GetSharedBitmapFromId(m_resource.size, m_resource.mailbox_holder.mailbox);
+ // QSG interprets QImage::hasAlphaChannel meaning that a node should enable blending
+ // to draw it but Chromium keeps this information in the quads.
+ // The input format is currently always Format_ARGB32_Premultiplied, so assume that all
+ // alpha bytes are 0xff if quads aren't requesting blending and avoid the conversion
+ // from Format_ARGB32_Premultiplied to Format_RGB32 just to get hasAlphaChannel to
+ // return false.
+ QImage::Format format = quadNeedsBlending ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
+ QImage image(sharedBitmap->pixels(), m_resource.size.width(), m_resource.size.height(), format);
+ texture.reset(apiDelegate->createTextureFromImage(image.copy()));
+ } else {
+ texture.reset(new MailboxTexture(m_resource.mailbox_holder, toQt(m_resource.size)));
+ static_cast<MailboxTexture *>(texture.data())->setHasAlphaChannel(quadNeedsBlending);
+ }
+ m_texture = texture;
+ }
+ // All quads using a resource should request the same blending state.
+ Q_ASSERT(texture->hasAlphaChannel() || !quadNeedsBlending);
+ return texture;
+}
+
+cc::ReturnedResource ResourceHolder::returnResource()
{
cc::ReturnedResource returned;
// The ResourceProvider ensures that the resource isn't used by the parent compositor's GL
@@ -389,20 +369,6 @@ cc::ReturnedResource MailboxTexture::returnResource()
return returned;
}
-void MailboxTexture::fetchTexture(gpu::gles2::MailboxManager *mailboxManager)
-{
- gpu::gles2::Texture *tex = ConsumeTexture(mailboxManager, m_target, m_resource.mailbox_holder.mailbox);
-
- // The texture might already have been deleted (e.g. when navigating away from a page).
- if (tex) {
- m_textureId = service_id(tex);
-#ifdef Q_OS_QNX
- if (m_target == GL_TEXTURE_EXTERNAL_OES) {
- m_eglStreamData = eglstream_connect_consumer(tex);
- }
-#endif
- }
-}
RectClipNode::RectClipNode(const QRectF &rect)
: m_geometry(QSGGeometry::defaultAttributes_Point2D(), 4)
@@ -429,9 +395,12 @@ void DelegatedFrameNode::preprocess()
// We can now wait for the Chromium GPU thread to produce textures that will be
// rendered on our quads and fetch the IDs from the mailboxes we were given.
QList<MailboxTexture *> mailboxesToFetch;
- Q_FOREACH (const QSharedPointer<MailboxTexture> &mailboxTexture, m_data->mailboxTextures.values())
- if (mailboxTexture->needsToFetch())
- mailboxesToFetch.append(mailboxTexture.data());
+ typedef QHash<unsigned, QSharedPointer<ResourceHolder> >::const_iterator ResourceHolderIterator;
+ ResourceHolderIterator end = m_chromiumCompositorData->resourceHolders.constEnd();
+ for (ResourceHolderIterator it = m_chromiumCompositorData->resourceHolders.constBegin(); it != end ; ++it) {
+ if ((*it)->needsToFetch())
+ mailboxesToFetch.append(static_cast<MailboxTexture *>((*it)->texture()));
+ }
if (!mailboxesToFetch.isEmpty()) {
QMap<uint32, gfx::TransferableFence> transferredFences;
@@ -442,7 +411,7 @@ void DelegatedFrameNode::preprocess()
Q_FOREACH (MailboxTexture *mailboxTexture, mailboxesToFetch) {
m_numPendingSyncPoints++;
- AddSyncPointCallbackOnGpuThread(gpuMessageLoop, syncPointManager, mailboxTexture->resource().mailbox_holder.sync_point, base::Bind(&DelegatedFrameNode::syncPointRetired, this, &mailboxesToFetch));
+ AddSyncPointCallbackOnGpuThread(gpuMessageLoop, syncPointManager, mailboxTexture->mailboxHolder().sync_point, base::Bind(&DelegatedFrameNode::syncPointRetired, this, &mailboxesToFetch));
}
m_mailboxesFetchedWaitCond.wait(&m_mutex);
@@ -452,7 +421,7 @@ void DelegatedFrameNode::preprocess()
// Tell GL to wait until Chromium is done generating resource textures on the GPU thread
// for each mailbox. We can safely start referencing those textures onto geometries afterward.
Q_FOREACH (MailboxTexture *mailboxTexture, mailboxesToFetch) {
- gfx::TransferableFence fence = transferredFences.take(mailboxTexture->resource().mailbox_holder.sync_point);
+ gfx::TransferableFence fence = transferredFences.take(mailboxTexture->mailboxHolder().sync_point);
waitChromiumSync(&fence);
deleteChromiumSync(&fence);
}
@@ -464,14 +433,19 @@ void DelegatedFrameNode::preprocess()
}
// Then render any intermediate RenderPass in order.
- Q_FOREACH (const QSharedPointer<RenderPassTexture> &renderPass, m_renderPassTextures)
- renderPass->grab();
+ typedef QPair<cc::RenderPass::Id, QSharedPointer<QSGLayer> > Pair;
+ Q_FOREACH (const Pair &pair, m_sgObjects.renderPassLayers) {
+ // The layer is non-live, request a one-time update here.
+ pair.second->scheduleUpdate();
+ // Proceed with the actual update.
+ pair.second->updateTexture();
+ }
}
-void DelegatedFrameNode::commit(DelegatedFrameNodeData* data, cc::ReturnedResourceArray *resourcesToRelease)
+void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, cc::ReturnedResourceArray *resourcesToRelease, RenderWidgetHostViewQtDelegate *apiDelegate)
{
- m_data = data;
- cc::DelegatedFrameData* frameData = m_data->frameData.get();
+ m_chromiumCompositorData = chromiumCompositorData;
+ cc::DelegatedFrameData* frameData = m_chromiumCompositorData->frameData.get();
if (!frameData)
return;
@@ -479,14 +453,15 @@ void DelegatedFrameNode::commit(DelegatedFrameNodeData* data, cc::ReturnedResour
// countering the scale of devicePixel-scaled tiles when rendering them
// to the final surface.
QMatrix4x4 matrix;
- matrix.scale(1 / m_data->frameDevicePixelRatio, 1 / m_data->frameDevicePixelRatio);
+ matrix.scale(1 / m_chromiumCompositorData->frameDevicePixelRatio, 1 / m_chromiumCompositorData->frameDevicePixelRatio);
setMatrix(matrix);
- // Keep the old texture lists around to find the ones we can re-use.
- QList<QSharedPointer<RenderPassTexture> > oldRenderPassTextures;
- m_renderPassTextures.swap(oldRenderPassTextures);
- QHash<unsigned, QSharedPointer<MailboxTexture> > mailboxTextureCandidates;
- m_data->mailboxTextures.swap(mailboxTextureCandidates);
+ // Keep the old objects in scope to hold a ref on layers, resources and textures
+ // that we can re-use. Destroy the remaining objects before returning.
+ SGObjects previousSGObjects;
+ qSwap(m_sgObjects, previousSGObjects);
+ QHash<unsigned, QSharedPointer<ResourceHolder> > resourceCandidates;
+ qSwap(m_chromiumCompositorData->resourceHolders, resourceCandidates);
// A frame's resource_list only contains the new resources to be added to the scene. Quads can
// still reference resources that were added in previous frames. Add them to the list of
@@ -494,14 +469,21 @@ void DelegatedFrameNode::commit(DelegatedFrameNodeData* data, cc::ReturnedResour
// to the producing child compositor.
for (unsigned i = 0; i < frameData->resource_list.size(); ++i) {
const cc::TransferableResource &res = frameData->resource_list.at(i);
- if (QSharedPointer<MailboxTexture> texture = mailboxTextureCandidates.value(res.id))
- texture->incImportCount();
+ if (QSharedPointer<ResourceHolder> resource = resourceCandidates.value(res.id))
+ resource->incImportCount();
else
- mailboxTextureCandidates[res.id] = QSharedPointer<MailboxTexture>(new MailboxTexture(res));
+ resourceCandidates[res.id] = QSharedPointer<ResourceHolder>(new ResourceHolder(res));
}
frameData->resource_list.clear();
+ // There is currently no way to know which and how quads changed since the last frame.
+ // We have to reconstruct the node chain with their geometries on every update.
+ // Intermediate render pass node chains are going to be destroyed when previousSGObjects
+ // goes out of scope together with any QSGLayer that could reference them.
+ while (QSGNode *oldChain = firstChild())
+ delete oldChain;
+
// The RenderPasses list is actually a tree where a parent RenderPass is connected
// to its dependencies through a RenderPass::Id reference in one or more RenderPassQuads.
// The list is already ordered with intermediate RenderPasses placed before their
@@ -515,21 +497,24 @@ void DelegatedFrameNode::commit(DelegatedFrameNodeData* data, cc::ReturnedResour
QSGNode *renderPassParent = 0;
if (pass != rootRenderPass) {
- QSharedPointer<RenderPassTexture> rpTexture = findRenderPassTexture(pass->id, oldRenderPassTextures);
- if (!rpTexture)
- rpTexture = QSharedPointer<RenderPassTexture>(new RenderPassTexture(pass->id));
- m_renderPassTextures.append(rpTexture);
- rpTexture->setRect(toQt(pass->output_rect));
- rpTexture->setFormat(pass->has_transparent_background ? GL_RGBA : GL_RGB);
- renderPassParent = rpTexture->rootNode();
+ QSharedPointer<QSGLayer> rpLayer = findRenderPassLayer(pass->id, previousSGObjects.renderPassLayers);
+ if (!rpLayer) {
+ rpLayer = QSharedPointer<QSGLayer>(apiDelegate->createLayer());
+ // Avoid any premature texture update since we need to wait
+ // for the GPU thread to produce the dependent resources first.
+ rpLayer->setLive(false);
+ }
+ QSharedPointer<QSGRootNode> rootNode(new QSGRootNode);
+ rpLayer->setRect(toQt(pass->output_rect));
+ rpLayer->setSize(toQt(pass->output_rect.size()));
+ rpLayer->setFormat(pass->has_transparent_background ? GL_RGBA : GL_RGB);
+ rpLayer->setItem(rootNode.data());
+ m_sgObjects.renderPassLayers.append(QPair<cc::RenderPass::Id, QSharedPointer<QSGLayer> >(pass->id, rpLayer));
+ m_sgObjects.renderPassRootNodes.append(rootNode);
+ renderPassParent = rootNode.data();
} else
renderPassParent = this;
- // There is currently no way to know which and how quads changed since the last frame.
- // We have to reconstruct the node chain with their geometries on every update.
- while (QSGNode *oldChain = renderPassParent->firstChild())
- delete oldChain;
-
QSGNode *renderPassChain = buildRenderPassChain(renderPassParent);
const cc::SharedQuadState *currentLayerState = 0;
QSGNode *currentLayerChain = 0;
@@ -555,37 +540,28 @@ void DelegatedFrameNode::commit(DelegatedFrameNodeData* data, cc::ReturnedResour
break;
} case cc::DrawQuad::RENDER_PASS: {
const cc::RenderPassDrawQuad *renderPassQuad = cc::RenderPassDrawQuad::MaterialCast(quad);
- QSGTexture *texture = findRenderPassTexture(renderPassQuad->render_pass_id, m_renderPassTextures).data();
+ QSGTexture *layer = findRenderPassLayer(renderPassQuad->render_pass_id, m_sgObjects.renderPassLayers).data();
// cc::GLRenderer::DrawRenderPassQuad silently ignores missing render passes.
- if (!texture)
+ if (!layer)
continue;
- QSGSimpleTextureNode *textureNode = new QSGSimpleTextureNode;
- textureNode->setRect(toQt(quad->rect));
- textureNode->setTexture(texture);
- currentLayerChain->appendChildNode(textureNode);
+ // Only QSGImageNode currently supports QSGLayer textures.
+ QSGImageNode *imageNode = apiDelegate->createImageNode();
+ imageNode->setTargetRect(toQt(quad->rect));
+ imageNode->setInnerTargetRect(toQt(quad->rect));
+ imageNode->setTexture(layer);
+ imageNode->update();
+ currentLayerChain->appendChildNode(imageNode);
break;
} case cc::DrawQuad::TEXTURE_CONTENT: {
const cc::TextureDrawQuad *tquad = cc::TextureDrawQuad::MaterialCast(quad);
- QSharedPointer<MailboxTexture> &texture = findMailboxTexture(tquad->resource_id, m_data->mailboxTextures, mailboxTextureCandidates);
-
- // FIXME: TransferableResource::size isn't always set properly for TextureDrawQuads, use the size of its DrawQuad::rect instead.
- texture->setTextureSize(toQt(quad->rect.size()));
-
- // TransferableResource::format seems to always be GL_BGRA even though it might not
- // contain any pixel with alpha < 1.0. The information about if they need blending
- // for the contents itself is actually stored in quads.
- // Tell the scene graph to enable blending for a texture only when at least one quad asks for it.
- // Do not rely on DrawQuad::ShouldDrawWithBlending() since the shared_quad_state->opacity
- // case will be handled by QtQuick by fetching this information from QSGOpacityNodes.
- if (!quad->visible_rect.IsEmpty() && !quad->opaque_rect.Contains(quad->visible_rect))
- texture->setHasAlphaChannel(true);
+ ResourceHolder *resource = findAndHoldResource(tquad->resource_id, resourceCandidates);
QSGSimpleTextureNode *textureNode = new QSGSimpleTextureNode;
textureNode->setTextureCoordinatesTransform(tquad->flipped ? QSGSimpleTextureNode::MirrorVertically : QSGSimpleTextureNode::NoTransform);
textureNode->setRect(toQt(quad->rect));
- textureNode->setFiltering(texture->resource().filter == GL_LINEAR ? QSGTexture::Linear : QSGTexture::Nearest);
- textureNode->setTexture(texture.data());
+ textureNode->setFiltering(resource->transferableResource().filter == GL_LINEAR ? QSGTexture::Linear : QSGTexture::Nearest);
+ textureNode->setTexture(initAndHoldTexture(resource, quad->ShouldDrawWithBlending(), apiDelegate));
currentLayerChain->appendChildNode(textureNode);
break;
} case cc::DrawQuad::SOLID_COLOR: {
@@ -601,46 +577,67 @@ void DelegatedFrameNode::commit(DelegatedFrameNodeData* data, cc::ReturnedResour
rectangleNode->setColor(toQt(scquad->color));
currentLayerChain->appendChildNode(rectangleNode);
break;
+ } case cc::DrawQuad::DEBUG_BORDER: {
+ const cc::DebugBorderDrawQuad *dbquad = cc::DebugBorderDrawQuad::MaterialCast(quad);
+ QSGGeometryNode *geometryNode = new QSGGeometryNode;
+
+ QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4);
+ geometry->setDrawingMode(GL_LINE_LOOP);
+ geometry->setLineWidth(dbquad->width);
+ // QSGGeometry::updateRectGeometry would actually set the corners in the following order:
+ // top-left, bottom-left, top-right, bottom-right, leading to a nice criss cross, instead
+ // of having a closed loop.
+ const gfx::Rect &r(dbquad->rect);
+ geometry->vertexDataAsPoint2D()[0].set(r.x(), r.y());
+ geometry->vertexDataAsPoint2D()[1].set(r.x() + r.width(), r.y());
+ geometry->vertexDataAsPoint2D()[2].set(r.x() + r.width(), r.y() + r.height());
+ geometry->vertexDataAsPoint2D()[3].set(r.x(), r.y() + r.height());
+ geometryNode->setGeometry(geometry);
+
+ QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
+ material->setColor(toQt(dbquad->color));
+ geometryNode->setMaterial(material);
+
+ geometryNode->setFlags(QSGNode::OwnsGeometry | QSGNode::OwnsMaterial);
+ currentLayerChain->appendChildNode(geometryNode);
+ break;
} case cc::DrawQuad::TILED_CONTENT: {
const cc::TileDrawQuad *tquad = cc::TileDrawQuad::MaterialCast(quad);
- QSharedPointer<MailboxTexture> &texture = findMailboxTexture(tquad->resource_id, m_data->mailboxTextures, mailboxTextureCandidates);
-
- if (!quad->visible_rect.IsEmpty() && !quad->opaque_rect.Contains(quad->visible_rect))
- texture->setHasAlphaChannel(true);
+ ResourceHolder *resource = findAndHoldResource(tquad->resource_id, resourceCandidates);
QSGSimpleTextureNode *textureNode = new QSGSimpleTextureNode;
textureNode->setRect(toQt(quad->rect));
- textureNode->setFiltering(texture->resource().filter == GL_LINEAR ? QSGTexture::Linear : QSGTexture::Nearest);
- textureNode->setTexture(texture.data());
-
- // FIXME: Find out if we can implement a QSGSimpleTextureNode::setSourceRect instead of this hack.
- // This has to be done at the end since many QSGSimpleTextureNode methods would overwrite this.
- QSGGeometry::updateTexturedRectGeometry(textureNode->geometry(), textureNode->rect(), textureNode->texture()->convertToNormalizedSourceRect(toQt(tquad->tex_coord_rect)));
+ textureNode->setSourceRect(toQt(tquad->tex_coord_rect));
+ textureNode->setFiltering(resource->transferableResource().filter == GL_LINEAR ? QSGTexture::Linear : QSGTexture::Nearest);
+ textureNode->setTexture(initAndHoldTexture(resource, quad->ShouldDrawWithBlending(), apiDelegate));
currentLayerChain->appendChildNode(textureNode);
break;
} case cc::DrawQuad::YUV_VIDEO_CONTENT: {
const cc::YUVVideoDrawQuad *vquad = cc::YUVVideoDrawQuad::MaterialCast(quad);
- QSharedPointer<MailboxTexture> &yTexture = findMailboxTexture(vquad->y_plane_resource_id, m_data->mailboxTextures, mailboxTextureCandidates);
- QSharedPointer<MailboxTexture> &uTexture = findMailboxTexture(vquad->u_plane_resource_id, m_data->mailboxTextures, mailboxTextureCandidates);
- QSharedPointer<MailboxTexture> &vTexture = findMailboxTexture(vquad->v_plane_resource_id, m_data->mailboxTextures, mailboxTextureCandidates);
-
- // Do not use a reference for this one, it might be null.
- QSharedPointer<MailboxTexture> aTexture;
+ ResourceHolder *yResource = findAndHoldResource(vquad->y_plane_resource_id, resourceCandidates);
+ ResourceHolder *uResource = findAndHoldResource(vquad->u_plane_resource_id, resourceCandidates);
+ ResourceHolder *vResource = findAndHoldResource(vquad->v_plane_resource_id, resourceCandidates);
+ ResourceHolder *aResource = 0;
// This currently requires --enable-vp8-alpha-playback and needs a video with alpha data to be triggered.
if (vquad->a_plane_resource_id)
- aTexture = findMailboxTexture(vquad->a_plane_resource_id, m_data->mailboxTextures, mailboxTextureCandidates);
+ aResource = findAndHoldResource(vquad->a_plane_resource_id, resourceCandidates);
- YUVVideoNode *videoNode = new YUVVideoNode(yTexture.data(), uTexture.data(), vTexture.data(), aTexture.data(), toQt(vquad->tex_coord_rect));
+ YUVVideoNode *videoNode = new YUVVideoNode(
+ initAndHoldTexture(yResource, quad->ShouldDrawWithBlending()),
+ initAndHoldTexture(uResource, quad->ShouldDrawWithBlending()),
+ initAndHoldTexture(vResource, quad->ShouldDrawWithBlending()),
+ aResource ? initAndHoldTexture(aResource, quad->ShouldDrawWithBlending()) : 0, toQt(vquad->tex_coord_rect));
videoNode->setRect(toQt(quad->rect));
currentLayerChain->appendChildNode(videoNode);
break;
#ifdef GL_OES_EGL_image_external
} case cc::DrawQuad::STREAM_VIDEO_CONTENT: {
const cc::StreamVideoDrawQuad *squad = cc::StreamVideoDrawQuad::MaterialCast(quad);
- QSharedPointer<MailboxTexture> &texture = findMailboxTexture(squad->resource_id, m_data->mailboxTextures, mailboxTextureCandidates);
+ ResourceHolder *resource = findAndHoldResource(squad->resource_id, resourceCandidates);
+ MailboxTexture *texture = static_cast<MailboxTexture *>(initAndHoldTexture(resource, quad->ShouldDrawWithBlending()));
texture->setTarget(GL_TEXTURE_EXTERNAL_OES); // since this is not default TEXTURE_2D type
- StreamVideoNode *svideoNode = new StreamVideoNode(texture.data());
+ StreamVideoNode *svideoNode = new StreamVideoNode(texture);
svideoNode->setRect(toQt(squad->rect));
svideoNode->setTextureMatrix(toQt(squad->matrix.matrix()));
currentLayerChain->appendChildNode(svideoNode);
@@ -653,8 +650,30 @@ void DelegatedFrameNode::commit(DelegatedFrameNodeData* data, cc::ReturnedResour
}
// Send resources of remaining candidates back to the child compositors so that they can be freed or reused.
- Q_FOREACH (const QSharedPointer<MailboxTexture> &mailboxTexture, mailboxTextureCandidates.values())
- resourcesToRelease->push_back(mailboxTexture->returnResource());
+ typedef QHash<unsigned, QSharedPointer<ResourceHolder> >::const_iterator ResourceHolderIterator;
+ ResourceHolderIterator end = resourceCandidates.constEnd();
+ for (ResourceHolderIterator it = resourceCandidates.constBegin(); it != end ; ++it)
+ resourcesToRelease->push_back((*it)->returnResource());
+}
+
+ResourceHolder *DelegatedFrameNode::findAndHoldResource(unsigned resourceId, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates)
+{
+ // ResourceHolders must survive when the scene graph destroys our node branch
+ QSharedPointer<ResourceHolder> &resource = m_chromiumCompositorData->resourceHolders[resourceId];
+ if (!resource)
+ resource = candidates.take(resourceId);
+ Q_ASSERT(resource);
+ return resource.data();
+}
+
+QSGTexture *DelegatedFrameNode::initAndHoldTexture(ResourceHolder *resource, bool quadIsAllOpaque, RenderWidgetHostViewQtDelegate *apiDelegate)
+{
+ // QSGTextures must be destroyed in the scene graph thread as part of the QSGNode tree,
+ // so we can't store them with the ResourceHolder in m_chromiumCompositorData.
+ // Hold them through a QSharedPointer solely on the root DelegatedFrameNode of the web view
+ // and access them through a QWeakPointer from the resource holder to find them later.
+ m_sgObjects.textureStrongRefs.append(resource->initTexture(quadIsAllOpaque, apiDelegate));
+ return m_sgObjects.textureStrongRefs.last().data();
}
void DelegatedFrameNode::fetchTexturesAndUnlockQt(DelegatedFrameNode *frameNode, QList<MailboxTexture *> *mailboxesToFetch)
diff --git a/src/core/delegated_frame_node.h b/src/core/delegated_frame_node.h
index a031a464f..b866c94b4 100644
--- a/src/core/delegated_frame_node.h
+++ b/src/core/delegated_frame_node.h
@@ -38,6 +38,7 @@
#define DELEGATED_FRAME_NODE_H
#include "base/memory/scoped_ptr.h"
+#include "cc/quads/render_pass.h"
#include "cc/resources/transferable_resource.h"
#include <QMutex>
#include <QSGNode>
@@ -46,20 +47,25 @@
#include <QWaitCondition>
#include "chromium_gpu_helper.h"
+#include "render_widget_host_view_qt_delegate.h"
+
+QT_BEGIN_NAMESPACE
+class QSGLayer;
+QT_END_NAMESPACE
namespace cc {
class DelegatedFrameData;
}
class MailboxTexture;
-class RenderPassTexture;
+class ResourceHolder;
// Separating this data allows another DelegatedFrameNode to reconstruct the QSGNode tree from the mailbox textures
// and render pass information.
-class DelegatedFrameNodeData : public QSharedData {
+class ChromiumCompositorData : public QSharedData {
public:
- DelegatedFrameNodeData() : frameDevicePixelRatio(1) { }
- QHash<unsigned, QSharedPointer<MailboxTexture> > mailboxTextures;
+ ChromiumCompositorData() : frameDevicePixelRatio(1) { }
+ QHash<unsigned, QSharedPointer<ResourceHolder> > resourceHolders;
scoped_ptr<cc::DelegatedFrameData> frameData;
qreal frameDevicePixelRatio;
};
@@ -69,20 +75,27 @@ public:
DelegatedFrameNode();
~DelegatedFrameNode();
void preprocess();
- void commit(DelegatedFrameNodeData* data, cc::ReturnedResourceArray *resourcesToRelease);
+ void commit(ChromiumCompositorData *chromiumCompositorData, cc::ReturnedResourceArray *resourcesToRelease, RenderWidgetHostViewQtDelegate *apiDelegate);
private:
- QExplicitlySharedDataPointer<DelegatedFrameNodeData> m_data;
- QList<QSharedPointer<RenderPassTexture> > m_renderPassTextures;
- int m_numPendingSyncPoints;
- QMap<uint32, gfx::TransferableFence> m_mailboxGLFences;
- QWaitCondition m_mailboxesFetchedWaitCond;
- QMutex m_mutex;
-
// Making those callbacks static bypasses base::Bind's ref-counting requirement
// of the this pointer when the callback is a method.
static void fetchTexturesAndUnlockQt(DelegatedFrameNode *frameNode, QList<MailboxTexture *> *mailboxesToFetch);
static void syncPointRetired(DelegatedFrameNode *frameNode, QList<MailboxTexture *> *mailboxesToFetch);
+
+ ResourceHolder *findAndHoldResource(unsigned resourceId, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates);
+ QSGTexture *initAndHoldTexture(ResourceHolder *resource, bool quadIsAllOpaque, RenderWidgetHostViewQtDelegate *apiDelegate = 0);
+
+ QExplicitlySharedDataPointer<ChromiumCompositorData> m_chromiumCompositorData;
+ struct SGObjects {
+ QList<QPair<cc::RenderPass::Id, QSharedPointer<QSGLayer> > > renderPassLayers;
+ QList<QSharedPointer<QSGRootNode> > renderPassRootNodes;
+ QList<QSharedPointer<QSGTexture> > textureStrongRefs;
+ } m_sgObjects;
+ int m_numPendingSyncPoints;
+ QMap<uint32, gfx::TransferableFence> m_mailboxGLFences;
+ QWaitCondition m_mailboxesFetchedWaitCond;
+ QMutex m_mutex;
};
#endif // DELEGATED_FRAME_NODE_H
diff --git a/src/core/dev_tools_http_handler_delegate_qt.cpp b/src/core/dev_tools_http_handler_delegate_qt.cpp
index 4f8992dab..1bb8ec1f1 100644
--- a/src/core/dev_tools_http_handler_delegate_qt.cpp
+++ b/src/core/dev_tools_http_handler_delegate_qt.cpp
@@ -34,6 +34,10 @@
**
****************************************************************************/
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
#include "dev_tools_http_handler_delegate_qt.h"
#include <QByteArray>
@@ -42,16 +46,90 @@
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/devtools_http_handler.h"
#include "content/public/browser/devtools_target.h"
+#include "content/public/browser/favicon_status.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/content_switches.h"
#include "net/socket/stream_listen_socket.h"
#include "net/socket/tcp_listen_socket.h"
using namespace content;
+namespace {
+
+const char kTargetTypePage[] = "page";
+
+class Target : public content::DevToolsTarget {
+public:
+ explicit Target(WebContents* web_contents);
+
+ virtual std::string GetId() const OVERRIDE { return id_; }
+ virtual std::string GetParentId() const OVERRIDE { return std::string(); }
+ virtual std::string GetType() const OVERRIDE { return kTargetTypePage; }
+ virtual std::string GetTitle() const OVERRIDE { return title_; }
+ virtual std::string GetDescription() const OVERRIDE { return std::string(); }
+ virtual GURL GetURL() const OVERRIDE { return url_; }
+ virtual GURL GetFaviconURL() const OVERRIDE { return favicon_url_; }
+ virtual base::TimeTicks GetLastActivityTime() const OVERRIDE {
+ return last_activity_time_;
+ }
+ virtual bool IsAttached() const OVERRIDE {
+ return agent_host_->IsAttached();
+ }
+ virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const OVERRIDE {
+ return agent_host_;
+ }
+ virtual bool Activate() const OVERRIDE;
+ virtual bool Close() const OVERRIDE;
+
+private:
+ scoped_refptr<DevToolsAgentHost> agent_host_;
+ std::string id_;
+ std::string title_;
+ GURL url_;
+ GURL favicon_url_;
+ base::TimeTicks last_activity_time_;
+};
+
+Target::Target(WebContents* web_contents) {
+ agent_host_ = DevToolsAgentHost::GetOrCreateFor(web_contents->GetRenderViewHost());
+ id_ = agent_host_->GetId();
+ title_ = base::UTF16ToUTF8(web_contents->GetTitle());
+ url_ = web_contents->GetURL();
+ content::NavigationController& controller = web_contents->GetController();
+ content::NavigationEntry* entry = controller.GetActiveEntry();
+ if (entry != NULL && entry->GetURL().is_valid())
+ favicon_url_ = entry->GetFavicon().url;
+ last_activity_time_ = web_contents->GetLastActiveTime();
+}
+
+bool Target::Activate() const {
+ RenderViewHost* rvh = agent_host_->GetRenderViewHost();
+ if (!rvh)
+ return false;
+ WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
+ if (!web_contents)
+ return false;
+ web_contents->GetDelegate()->ActivateContents(web_contents);
+ return true;
+}
+
+bool Target::Close() const {
+ RenderViewHost* rvh = agent_host_->GetRenderViewHost();
+ if (!rvh)
+ return false;
+ rvh->ClosePage();
+ return true;
+}
+
+} // namespace
+
DevToolsHttpHandlerDelegateQt::DevToolsHttpHandlerDelegateQt(BrowserContext* browser_context)
: m_browserContext(browser_context)
{
@@ -107,7 +185,14 @@ scoped_ptr<DevToolsTarget> DevToolsHttpHandlerDelegateQt::CreateNewTarget(const
void DevToolsHttpHandlerDelegateQt::EnumerateTargets(TargetCallback callback)
{
- callback.Run(TargetList());
+ TargetList targets;
+ std::vector<RenderViewHost*> rvh_list = content::DevToolsAgentHost::GetValidRenderViewHosts();
+ for (std::vector<RenderViewHost*>::iterator it = rvh_list.begin(); it != rvh_list.end(); ++it) {
+ WebContents* web_contents = WebContents::FromRenderViewHost(*it);
+ if (web_contents)
+ targets.push_back(new Target(web_contents));
+ }
+ callback.Run(targets);
}
scoped_ptr<net::StreamListenSocket> DevToolsHttpHandlerDelegateQt::CreateSocketForTethering(net::StreamListenSocket::Delegate* delegate, std::string* name)
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index 3df03ffa3..3f6ec7bcc 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -36,6 +36,7 @@
#include "download_manager_delegate_qt.h"
+#include "content/public/browser/download_manager.h"
#include "content/public/browser/download_item.h"
#include "content/public/browser/save_page_type.h"
#include "content/public/browser/web_contents.h"
@@ -46,115 +47,21 @@
#include <QMap>
#include <QStandardPaths>
+#include "browser_context_adapter.h"
+#include "browser_context_adapter_client.h"
+#include "browser_context_qt.h"
#include "type_conversion.h"
#include "qtwebenginecoreglobal.h"
-// Helper class to track currently ongoing downloads to prevent file name
-// clashes / overwriting of files.
-class DownloadTargetHelper : public content::DownloadItem::Observer {
-public:
- DownloadTargetHelper()
- : m_defaultDownloadDirectory(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation))
- {
-
- }
- virtual ~DownloadTargetHelper() {}
-
- bool determineDownloadTarget(content::DownloadItem *item, const content::DownloadTargetCallback &callback);
-
- virtual void OnDownloadUpdated(content::DownloadItem *download) Q_DECL_OVERRIDE;
- virtual void OnDownloadDestroyed(content::DownloadItem *download) Q_DECL_OVERRIDE;
-private:
- bool isPathAvailable(const QString& path);
-
- QDir m_defaultDownloadDirectory;
- QMap<content::DownloadItem*, QString> m_ongoingDownloads;
-};
-
-bool DownloadTargetHelper::isPathAvailable(const QString& path)
-{
- return !m_ongoingDownloads.values().contains(path) && !QFile::exists(path);
-}
-
-bool DownloadTargetHelper::determineDownloadTarget(content::DownloadItem *item, const content::DownloadTargetCallback &callback)
-{
- std::string suggestedFilename = item->GetSuggestedFilename();
-
- if (suggestedFilename.empty())
- suggestedFilename = item->GetTargetFilePath().AsUTF8Unsafe();
-
- if (suggestedFilename.empty())
- suggestedFilename = item->GetURL().ExtractFileName();
-
- if (suggestedFilename.empty())
- suggestedFilename = "qwe_download";
-
- if (!m_defaultDownloadDirectory.exists() && !m_defaultDownloadDirectory.mkpath(m_defaultDownloadDirectory.absolutePath()))
- return false;
-
- QString suggestedFilePath = m_defaultDownloadDirectory.absoluteFilePath(QString::fromStdString(suggestedFilename));
- if (!isPathAvailable(suggestedFilePath)) {
- int i = 1;
- for (; i < 99; i++) {
- QFileInfo tmpFile(suggestedFilePath);
- QString tmpFilePath = QString("%1%2%3(%4).%5").arg(tmpFile.absolutePath()).arg(QDir::separator()).arg(tmpFile.baseName()).arg(i).arg(tmpFile.completeSuffix());
- if (isPathAvailable(tmpFilePath)) {
- suggestedFilePath = tmpFilePath;
- break;
- }
- }
- if (i >= 99) {
- callback.Run(base::FilePath(), content::DownloadItem::TARGET_DISPOSITION_PROMPT, content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, base::FilePath());
- return false;
- }
- }
-
- m_ongoingDownloads.insert(item, suggestedFilePath);
- item->AddObserver(this);
-
- base::FilePath filePathForCallback(toFilePathString(suggestedFilePath));
- callback.Run(filePathForCallback, content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
- content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, filePathForCallback.AddExtension(toFilePathString("download")));
- return true;
-}
-
-void DownloadTargetHelper::OnDownloadUpdated(content::DownloadItem *download)
+DownloadManagerDelegateQt::DownloadManagerDelegateQt(BrowserContextAdapter *contextAdapter)
+ : m_currentId(0)
+ , m_contextAdapter(contextAdapter)
{
- switch (download->GetState()) {
- case content::DownloadItem::COMPLETE:
- case content::DownloadItem::CANCELLED:
- case content::DownloadItem::INTERRUPTED:
- download->RemoveObserver(this);
- m_ongoingDownloads.remove(download);
- break;
- case content::DownloadItem::IN_PROGRESS:
- default:
- break;
- }
-}
-
-void DownloadTargetHelper::OnDownloadDestroyed(content::DownloadItem *download)
-{
- download->RemoveObserver(this);
- m_ongoingDownloads.remove(download);
-}
-
-DownloadManagerDelegateQt::DownloadManagerDelegateQt()
- : m_targetHelper(new DownloadTargetHelper())
- , m_currentId(0)
-{
-
+ Q_ASSERT(m_contextAdapter);
}
DownloadManagerDelegateQt::~DownloadManagerDelegateQt()
{
- delete m_targetHelper;
-}
-
-
-void DownloadManagerDelegateQt::Shutdown()
-{
- QT_NOT_YET_IMPLEMENTED
}
void DownloadManagerDelegateQt::GetNextId(const content::DownloadIdCallback& callback)
@@ -162,24 +69,17 @@ void DownloadManagerDelegateQt::GetNextId(const content::DownloadIdCallback& cal
callback.Run(++m_currentId);
}
-bool DownloadManagerDelegateQt::ShouldOpenFileBasedOnExtension(const base::FilePath& path)
-{
- QT_NOT_YET_IMPLEMENTED
- return false;
-}
-
-bool DownloadManagerDelegateQt::ShouldCompleteDownload(content::DownloadItem* item,
- const base::Closure& complete_callback)
+void DownloadManagerDelegateQt::cancelDownload(const content::DownloadTargetCallback& callback)
{
- QT_NOT_YET_IMPLEMENTED
- return true;
+ callback.Run(base::FilePath(), content::DownloadItem::TARGET_DISPOSITION_PROMPT, content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, base::FilePath());
}
-bool DownloadManagerDelegateQt::ShouldOpenDownload(content::DownloadItem* item,
- const content::DownloadOpenDelayedCallback& callback)
+void DownloadManagerDelegateQt::cancelDownload(quint32 downloadId)
{
- QT_NOT_YET_IMPLEMENTED
- return false;
+ content::DownloadManager* dlm = content::BrowserContext::GetDownloadManager(m_contextAdapter->browserContext());
+ content::DownloadItem *download = dlm->GetDownload(downloadId);
+ if (download)
+ download->Cancel(/* user_cancel */ true);
}
bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* item,
@@ -194,41 +94,55 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* i
return true;
}
- // Let the target helper determine the download target path.
- return m_targetHelper->determineDownloadTarget(item, callback);
-}
+ std::string suggestedFilename = item->GetSuggestedFilename();
-bool DownloadManagerDelegateQt::GenerateFileHash()
-{
- QT_NOT_YET_IMPLEMENTED
- return false;
-}
+ if (suggestedFilename.empty())
+ suggestedFilename = item->GetTargetFilePath().AsUTF8Unsafe();
-void DownloadManagerDelegateQt::ChooseSavePath(
- content::WebContents* web_contents,
- const base::FilePath& suggested_path,
- const base::FilePath::StringType& default_extension,
- bool can_save_as_complete,
- const content::SavePackagePathPickedCallback& callback)
-{
- QT_NOT_YET_IMPLEMENTED
-}
+ if (suggestedFilename.empty())
+ suggestedFilename = item->GetURL().ExtractFileName();
-void DownloadManagerDelegateQt::OpenDownload(content::DownloadItem* download)
-{
- QT_NOT_YET_IMPLEMENTED
-}
+ if (suggestedFilename.empty())
+ suggestedFilename = "qwe_download";
-void DownloadManagerDelegateQt::ShowDownloadInShell(content::DownloadItem* download)
-{
- QT_NOT_YET_IMPLEMENTED
-}
+ QDir defaultDownloadDirectory = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
-void DownloadManagerDelegateQt::CheckForFileExistence(
- content::DownloadItem* download,
- const content::CheckForFileExistenceCallback& callback)
-{
- QT_NOT_YET_IMPLEMENTED
+ QFileInfo suggestedFile(defaultDownloadDirectory.absoluteFilePath(QString::fromStdString(suggestedFilename)));
+ QString suggestedFilePath = suggestedFile.absoluteFilePath();
+ QString tmpFileBase = QString("%1%2%3").arg(suggestedFile.absolutePath()).arg(QDir::separator()).arg(suggestedFile.baseName());
+
+ for (int i = 1; QFileInfo::exists(suggestedFilePath); ++i) {
+ suggestedFilePath = QString("%1(%2).%3").arg(tmpFileBase).arg(i).arg(suggestedFile.completeSuffix());
+ if (i >= 99) {
+ suggestedFilePath = suggestedFile.absoluteFilePath();
+ break;
+ }
+ }
+
+ item->AddObserver(this);
+ quint32 downloadId = item->GetId();
+ if (m_contextAdapter->client()) {
+ bool cancelled = false;
+ m_contextAdapter->client()->downloadRequested(downloadId, suggestedFilePath, cancelled);
+ suggestedFile.setFile(suggestedFilePath);
+
+ if (!cancelled && !suggestedFile.absoluteDir().mkpath(suggestedFile.absolutePath())) {
+ qWarning("Creating download path failed, download cancelled: %s", suggestedFile.absolutePath().toUtf8().data());
+ cancelled = true;
+ }
+
+ if (cancelled) {
+ cancelDownload(callback);
+ return true;
+ }
+
+ base::FilePath filePathForCallback(toFilePathString(suggestedFile.absoluteFilePath()));
+ callback.Run(filePathForCallback, content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+ content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, filePathForCallback.AddExtension(toFilePathString("download")));
+ } else
+ cancelDownload(callback);
+
+ return true;
}
void DownloadManagerDelegateQt::GetSaveDir(content::BrowserContext* browser_context,
@@ -242,4 +156,16 @@ void DownloadManagerDelegateQt::GetSaveDir(content::BrowserContext* browser_cont
*skip_dir_check = true;
}
+void DownloadManagerDelegateQt::OnDownloadUpdated(content::DownloadItem *download)
+{
+ const quint32 downloadId = download->GetId();
+
+ if (m_contextAdapter->client())
+ m_contextAdapter->client()->downloadUpdated(downloadId, download->GetState(), download->PercentComplete());
+}
+void DownloadManagerDelegateQt::OnDownloadDestroyed(content::DownloadItem *download)
+{
+ download->RemoveObserver(this);
+ download->Cancel(/* user_cancel */ false);
+}
diff --git a/src/core/download_manager_delegate_qt.h b/src/core/download_manager_delegate_qt.h
index 4c838363f..007f2e580 100644
--- a/src/core/download_manager_delegate_qt.h
+++ b/src/core/download_manager_delegate_qt.h
@@ -39,7 +39,7 @@
#include "content/public/browser/download_manager_delegate.h"
-#include <qglobal.h>
+#include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE
namespace base {
class FilePath;
@@ -51,46 +51,38 @@ class DownloadItem;
class WebContents;
}
-class DownloadTargetHelper;
-
-class DownloadManagerDelegateQt : public content::DownloadManagerDelegate
+class BrowserContextAdapter;
+class DownloadManagerDelegateInstance;
+class DownloadManagerDelegateQt
+ : public content::DownloadManagerDelegate
+ , public content::DownloadItem::Observer
{
public:
- DownloadManagerDelegateQt();
- virtual ~DownloadManagerDelegateQt();
-
- void Shutdown() Q_DECL_OVERRIDE;
+ DownloadManagerDelegateQt(BrowserContextAdapter *contextAdapter);
+ ~DownloadManagerDelegateQt();
void GetNextId(const content::DownloadIdCallback& callback) Q_DECL_OVERRIDE;
- bool ShouldOpenFileBasedOnExtension(const base::FilePath& path) Q_DECL_OVERRIDE;
- bool ShouldCompleteDownload(content::DownloadItem* item,
- const base::Closure& complete_callback) Q_DECL_OVERRIDE;
-
- bool ShouldOpenDownload(content::DownloadItem* item,
- const content::DownloadOpenDelayedCallback& callback) Q_DECL_OVERRIDE;
bool DetermineDownloadTarget(content::DownloadItem* item,
const content::DownloadTargetCallback& callback) Q_DECL_OVERRIDE;
- bool GenerateFileHash() Q_DECL_OVERRIDE;
- void ChooseSavePath(content::WebContents* web_contents,
- const base::FilePath& suggested_path,
- const base::FilePath::StringType& default_extension,
- bool can_save_as_complete,
- const content::SavePackagePathPickedCallback& callback) Q_DECL_OVERRIDE;
-
- void OpenDownload(content::DownloadItem* download) Q_DECL_OVERRIDE;
- void ShowDownloadInShell(content::DownloadItem* download) Q_DECL_OVERRIDE;
- void CheckForFileExistence(content::DownloadItem* download,
- const content::CheckForFileExistenceCallback& callback) Q_DECL_OVERRIDE;
-
void GetSaveDir(content::BrowserContext* browser_context,
base::FilePath* website_save_dir,
base::FilePath* download_save_dir,
bool* skip_dir_check) Q_DECL_OVERRIDE;
+ void cancelDownload(quint32 downloadId);
+
+ // Inherited from content::DownloadItem::Observer
+ void OnDownloadUpdated(content::DownloadItem *download) Q_DECL_OVERRIDE;
+ void OnDownloadDestroyed(content::DownloadItem *download) Q_DECL_OVERRIDE;
+
private:
- DownloadTargetHelper* m_targetHelper;
+ void cancelDownload(const content::DownloadTargetCallback& callback);
+ BrowserContextAdapter *m_contextAdapter;
+
uint64 m_currentId;
+
+ friend class DownloadManagerDelegateInstance;
DISALLOW_COPY_AND_ASSIGN(DownloadManagerDelegateQt);
};
diff --git a/src/core/location_provider_qt.cpp b/src/core/location_provider_qt.cpp
new file mode 100644
index 000000000..cdc9f1a44
--- /dev/null
+++ b/src/core/location_provider_qt.cpp
@@ -0,0 +1,248 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "location_provider_qt.h"
+
+#include <math.h>
+
+#include "type_conversion.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QThread>
+#include <QtPositioning/QGeoPositionInfoSource>
+
+#include "base/message_loop/message_loop.h"
+#include "base/bind.h"
+#include "content/browser/geolocation/geolocation_provider_impl.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/geolocation_provider.h"
+
+using content::BrowserThread;
+
+class QtPositioningHelper : public QObject {
+ Q_OBJECT
+public:
+ QtPositioningHelper(LocationProviderQt *provider);
+ ~QtPositioningHelper();
+
+ bool start(bool highAccuracy);
+ void stop();
+ void refresh();
+
+private Q_SLOTS:
+ void updatePosition(const QGeoPositionInfo &);
+ void error(QGeoPositionInfoSource::Error positioningError);
+ void timeout();
+
+private:
+ LocationProviderQt *m_locationProvider;
+ QGeoPositionInfoSource *m_positionInfoSource;
+
+ void postToLocationProvider(const base::Closure &task);
+};
+
+QtPositioningHelper::QtPositioningHelper(LocationProviderQt *provider)
+ : m_locationProvider(provider)
+ , m_positionInfoSource(0)
+{
+ Q_ASSERT(provider);
+}
+
+QtPositioningHelper::~QtPositioningHelper()
+{
+ m_locationProvider->m_positioningHelper = 0;
+}
+
+bool QtPositioningHelper::start(bool highAccuracy)
+{
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ Q_UNUSED(highAccuracy);
+ // FIXME: go through availableSources until one supports QGeoPositionInfoSource::SatellitePositioningMethods
+ // for the highAccuracy case.
+ m_positionInfoSource = QGeoPositionInfoSource::createDefaultSource(this);
+ if (!m_positionInfoSource)
+ return false;
+
+ connect(m_positionInfoSource, &QGeoPositionInfoSource::positionUpdated, this, &QtPositioningHelper::updatePosition);
+ // disambiguate the error getter and the signal in QGeoPositionInfoSource.
+ connect(m_positionInfoSource, static_cast<void (QGeoPositionInfoSource::*)(QGeoPositionInfoSource::Error)>(&QGeoPositionInfoSource::error)
+ , this, &QtPositioningHelper::error);
+ connect(m_positionInfoSource, &QGeoPositionInfoSource::updateTimeout, this, &QtPositioningHelper::timeout);
+
+ m_positionInfoSource->startUpdates();
+ return true;
+}
+
+void QtPositioningHelper::stop()
+{
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!m_positionInfoSource)
+ return;
+ m_positionInfoSource->stopUpdates();
+}
+
+void QtPositioningHelper::refresh()
+{
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!m_positionInfoSource)
+ return;
+ m_positionInfoSource->stopUpdates();
+}
+
+void QtPositioningHelper::updatePosition(const QGeoPositionInfo &pos)
+{
+ if (!pos.isValid())
+ return;
+ Q_ASSERT(m_positionInfoSource->error() == QGeoPositionInfoSource::NoError);
+ content::Geoposition newPos;
+ newPos.error_code = content::Geoposition::ERROR_CODE_NONE;
+ newPos.error_message.clear();
+
+ newPos.timestamp = toTime(pos.timestamp());
+ newPos.latitude = pos.coordinate().latitude();
+ newPos.longitude = pos.coordinate().longitude();
+
+ const double altitude = pos.coordinate().altitude();
+ if (!qIsNaN(altitude))
+ newPos.altitude = altitude;
+
+ // Chromium's geoposition needs a valid (as in >=0.) accuracy field.
+ // try and get an accuracy estimate from QGeoPositionInfo.
+ // If we don't have any accuracy info, 100m seems a pesimistic enough default.
+ if (!pos.hasAttribute(QGeoPositionInfo::VerticalAccuracy) && !pos.hasAttribute(QGeoPositionInfo::HorizontalAccuracy))
+ newPos.accuracy = 100;
+ else {
+ const double vAccuracy = pos.hasAttribute(QGeoPositionInfo::VerticalAccuracy) ? pos.attribute(QGeoPositionInfo::VerticalAccuracy) : 0;
+ const double hAccuracy = pos.hasAttribute(QGeoPositionInfo::HorizontalAccuracy) ? pos.attribute(QGeoPositionInfo::HorizontalAccuracy) : 0;
+ newPos.accuracy = sqrt(vAccuracy * vAccuracy + hAccuracy * hAccuracy);
+ }
+
+ // And now the "nice to have" fields (-1 means invalid).
+ newPos.speed = pos.hasAttribute(QGeoPositionInfo::GroundSpeed) ? pos.attribute(QGeoPositionInfo::GroundSpeed) : -1;
+ newPos.heading = pos.hasAttribute(QGeoPositionInfo::Direction) ? pos.attribute(QGeoPositionInfo::Direction) : -1;
+
+ postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, base::Unretained(m_locationProvider), newPos));
+}
+
+void QtPositioningHelper::error(QGeoPositionInfoSource::Error positioningError)
+{
+ Q_ASSERT(positioningError != QGeoPositionInfoSource::NoError);
+ content::Geoposition newPos;
+ switch (positioningError) {
+ case QGeoPositionInfoSource::AccessError:
+ newPos.error_code = content::Geoposition::ERROR_CODE_PERMISSION_DENIED;
+ break;
+ case QGeoPositionInfoSource::ClosedError:
+ case QGeoPositionInfoSource::UnknownSourceError: // position unavailable is as good as it gets in Geoposition
+ default:
+ newPos.error_code = content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
+ break;
+ }
+ postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, base::Unretained(m_locationProvider), newPos));
+}
+
+void QtPositioningHelper::timeout()
+{
+ content::Geoposition newPos;
+ // content::Geoposition::ERROR_CODE_TIMEOUT is not handled properly in the renderer process, and the timeout
+ // argument used in JS never comes all the way to the browser process.
+ // Let's just treat it like any other error where the position is unavailable.
+ newPos.error_code = content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
+ postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, base::Unretained(m_locationProvider), newPos));
+}
+
+inline void QtPositioningHelper::postToLocationProvider(const base::Closure &task)
+{
+ LocationProviderQt::messageLoop()->PostTask(FROM_HERE, task);
+}
+
+#include "location_provider_qt.moc"
+
+LocationProviderQt::LocationProviderQt()
+ : m_positioningHelper(0)
+{
+}
+
+LocationProviderQt::~LocationProviderQt()
+{
+ m_positioningHelper->deleteLater();
+}
+
+bool LocationProviderQt::StartProvider(bool highAccuracy)
+{
+ DCHECK(base::MessageLoop::current() == messageLoop());
+ QThread *guiThread = qApp->thread();
+ if (!m_positioningHelper) {
+ m_positioningHelper = new QtPositioningHelper(this);
+ m_positioningHelper->moveToThread(guiThread);
+ }
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(base::IgnoreResult(&QtPositioningHelper::start)
+ , base::Unretained(m_positioningHelper), highAccuracy));
+ return true;
+}
+
+void LocationProviderQt::StopProvider()
+{
+ DCHECK(base::MessageLoop::current() == messageLoop());
+ if (m_positioningHelper)
+ BrowserThread::PostTask(BrowserThread::UI,FROM_HERE, base::Bind(&QtPositioningHelper::stop
+ , base::Unretained(m_positioningHelper)));
+}
+
+void LocationProviderQt::RequestRefresh()
+{
+ DCHECK(base::MessageLoop::current() == messageLoop());
+ if (m_positioningHelper)
+ BrowserThread::PostTask(BrowserThread::UI,FROM_HERE, base::Bind(&QtPositioningHelper::refresh
+ , base::Unretained(m_positioningHelper)));
+}
+
+void LocationProviderQt::OnPermissionGranted()
+{
+ RequestRefresh();
+}
+
+void LocationProviderQt::updatePosition(const content::Geoposition &position)
+{
+ DCHECK(base::MessageLoop::current() == messageLoop());
+ m_lastKnownPosition = position;
+ NotifyCallback(position);
+}
+
+base::MessageLoop *LocationProviderQt::messageLoop()
+{
+ return static_cast<content::GeolocationProviderImpl*>(content::GeolocationProvider::GetInstance())->message_loop();
+}
diff --git a/src/core/location_provider_qt.h b/src/core/location_provider_qt.h
new file mode 100644
index 000000000..c3e462092
--- /dev/null
+++ b/src/core/location_provider_qt.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LOCATION_PROVIDER_QT_H
+#define LOCATION_PROVIDER_QT_H
+
+#include <QtCore/qcompilerdetection.h>
+
+#include "content/browser/geolocation/location_provider_base.h"
+#include "content/public/common/geoposition.h"
+
+QT_FORWARD_DECLARE_CLASS(QThread)
+class QtPositioningHelper;
+
+namespace base {
+class MessageLoop;
+}
+
+class LocationProviderQt : public content::LocationProviderBase
+{
+public:
+ LocationProviderQt();
+ virtual ~LocationProviderQt();
+
+ // LocationProviderBase
+ virtual bool StartProvider(bool highAccuracy) Q_DECL_OVERRIDE;
+ virtual void StopProvider() Q_DECL_OVERRIDE;
+ virtual void GetPosition(content::Geoposition *position) Q_DECL_OVERRIDE { *position = m_lastKnownPosition; }
+ virtual void RequestRefresh() Q_DECL_OVERRIDE;
+ virtual void OnPermissionGranted() Q_DECL_OVERRIDE;
+
+private:
+ friend class QtPositioningHelper;
+
+ static base::MessageLoop *messageLoop();
+ void updatePosition(const content::Geoposition &);
+
+ content::Geoposition m_lastKnownPosition;
+ QtPositioningHelper *m_positioningHelper;
+};
+//#define QT_USE_POSITIONING 1
+
+#endif // LOCATION_PROVIDER_QT_H
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index c221e94e3..a94ae6995 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -189,7 +189,7 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget
: m_host(content::RenderWidgetHostImpl::From(widget))
, m_gestureProvider(QtGestureProviderConfig(), this)
, m_sendMotionActionDown(false)
- , m_frameNodeData(new DelegatedFrameNodeData)
+ , m_chromiumCompositorData(new ChromiumCompositorData)
, m_needsDelegatedFrameAck(false)
, m_didFirstVisuallyNonEmptyLayout(false)
, m_adapterClient(0)
@@ -352,12 +352,19 @@ gfx::Rect RenderWidgetHostViewQt::GetViewBounds() const
// Return value indicates whether the mouse is locked successfully or not.
bool RenderWidgetHostViewQt::LockMouse()
{
- QT_NOT_USED
- return false;
+ mouse_locked_ = true;
+ m_lockedMousePosition = QCursor::pos();
+ m_delegate->lockMouse();
+ qApp->setOverrideCursor(Qt::BlankCursor);
+ return true;
}
+
void RenderWidgetHostViewQt::UnlockMouse()
{
- QT_NOT_USED
+ mouse_locked_ = false;
+ m_delegate->unlockMouse();
+ qApp->restoreOverrideCursor();
+ m_host->LostMouseLock();
}
void RenderWidgetHostViewQt::WasShown()
@@ -594,14 +601,14 @@ void RenderWidgetHostViewQt::OnSwapCompositorFrame(uint32 output_surface_id, sco
m_needsDelegatedFrameAck = true;
m_pendingOutputSurfaceId = output_surface_id;
Q_ASSERT(frame->delegated_frame_data);
- Q_ASSERT(!m_frameNodeData->frameData || m_frameNodeData->frameData->resource_list.empty());
- m_frameNodeData->frameData = frame->delegated_frame_data.Pass();
- m_frameNodeData->frameDevicePixelRatio = frame->metadata.device_scale_factor;
+ Q_ASSERT(!m_chromiumCompositorData->frameData || m_chromiumCompositorData->frameData->resource_list.empty());
+ m_chromiumCompositorData->frameData = frame->delegated_frame_data.Pass();
+ m_chromiumCompositorData->frameDevicePixelRatio = frame->metadata.device_scale_factor;
// Support experimental.viewport.devicePixelRatio, see GetScreenInfo implementation below.
float dpiScale = this->dpiScale();
if (dpiScale != 0 && dpiScale != 1)
- m_frameNodeData->frameDevicePixelRatio /= dpiScale;
+ m_chromiumCompositorData->frameDevicePixelRatio /= dpiScale;
m_delegate->update();
@@ -661,7 +668,7 @@ QSGNode *RenderWidgetHostViewQt::updatePaintNode(QSGNode *oldNode)
if (!frameNode)
frameNode = new DelegatedFrameNode;
- frameNode->commit(m_frameNodeData.data(), &m_resourcesToRelease);
+ frameNode->commit(m_chromiumCompositorData.data(), &m_resourcesToRelease, m_delegate.get());
// This is possibly called from the Qt render thread, post the ack back to the UI
// to tell the child compositors to release resources and trigger a new frame.
@@ -833,11 +840,20 @@ void RenderWidgetHostViewQt::handleMouseEvent(QMouseEvent* event)
m_clickHelper.lastPressPosition = QPointF(event->pos()).toPoint();
}
+ if (IsMouseLocked()) {
+ webEvent.movementX = -(m_lockedMousePosition.x() - event->globalX());
+ webEvent.movementY = -(m_lockedMousePosition.y() - event->globalY());
+ QCursor::setPos(m_lockedMousePosition);
+ }
+
m_host->ForwardMouseEvent(webEvent);
}
void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev)
{
+ if (IsMouseLocked() && ev->key() == Qt::Key_Escape && ev->type() == QEvent::KeyRelease)
+ UnlockMouse();
+
content::NativeWebKeyboardEvent webEvent = WebEventFactory::toWebKeyboardEvent(ev);
m_host->ForwardKeyboardEvent(webEvent);
if (webEvent.type == blink::WebInputEvent::RawKeyDown && !ev->text().isEmpty()) {
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index d4a3ff248..6ba95213b 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -235,7 +235,7 @@ private:
QMap<int, int> m_touchIdMapping;
scoped_ptr<RenderWidgetHostViewQtDelegate> m_delegate;
- QExplicitlySharedDataPointer<DelegatedFrameNodeData> m_frameNodeData;
+ QExplicitlySharedDataPointer<ChromiumCompositorData> m_chromiumCompositorData;
cc::ReturnedResourceArray m_resourcesToRelease;
bool m_needsDelegatedFrameAck;
bool m_didFirstVisuallyNonEmptyLayout;
@@ -248,6 +248,7 @@ private:
QRect m_cursorRect;
size_t m_anchorPositionWithinSelection;
size_t m_cursorPositionWithinSelection;
+ QPoint m_lockedMousePosition;
bool m_initPending;
};
diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h
index 3f6d9caac..018a914d8 100644
--- a/src/core/render_widget_host_view_qt_delegate.h
+++ b/src/core/render_widget_host_view_qt_delegate.h
@@ -46,7 +46,10 @@ QT_BEGIN_NAMESPACE
class QCursor;
class QEvent;
class QPainter;
+class QSGImageNode;
+class QSGLayer;
class QSGNode;
+class QSGTexture;
class QVariant;
class QWindow;
class QInputMethodEvent;
@@ -74,10 +77,15 @@ public:
virtual QRectF contentsRect() const = 0;
virtual void setKeyboardFocus() = 0;
virtual bool hasKeyboardFocus() = 0;
+ virtual void lockMouse() = 0;
+ virtual void unlockMouse() = 0;
virtual void show() = 0;
virtual void hide() = 0;
virtual bool isVisible() const = 0;
virtual QWindow* window() const = 0;
+ virtual QSGTexture *createTextureFromImage(const QImage &) = 0;
+ virtual QSGLayer *createLayer() = 0;
+ virtual QSGImageNode *createImageNode() = 0;
virtual void update() = 0;
virtual void updateCursor(const QCursor &) = 0;
virtual void resize(int width, int height) = 0;
diff --git a/src/core/resources/devtools_discovery_page.html b/src/core/resources/devtools_discovery_page.html
index 79463cc16..7aac74932 100644
--- a/src/core/resources/devtools_discovery_page.html
+++ b/src/core/resources/devtools_discovery_page.html
@@ -1,18 +1,55 @@
-<!--
-Copyright (c) 2013 BlackBerry Limited. All rights reserved.
--->
<html>
<head>
-<title>QtWebEngine remote debugging</title>
+<title>QtWebEngine Remote Debugging</title>
<style>
+body {
+ background-color: rgb(245, 245, 245);
+ font-family: Helvetica, Arial, sans-serif;
+ text-shadow: rgba(255, 255, 255, 0.496094) 0px 1px 0px;
+}
+
+#caption {
+ color: black;
+ font-size: 16px;
+ margin-top: 30px;
+ margin-bottom: 0px;
+ margin-left: 70px;
+ height: 20px;
+ text-align: left;
+}
+
+#items {
+ margin-left: 60px;
+ margin-right: 60px;
+ -webkit-box-orient: horizontal;
+ -webkit-box-lines: multiple;
+}
+
+.frontend_ref {
+ color: black;
+ text-decoration: initial;
+}
+
+.text {
+ background: no-repeat 0;
+ background-size: 16px;
+ font-size: 12px;
+ margin: 4px 0px 0px 4px;
+ overflow: hidden;
+ padding: 2px 0px 0px 20px;
+ text-align: left;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
</style>
<script>
+
function onLoad() {
- var tabs_list_request = new XMLHttpRequest();
- tabs_list_request.open('GET', '/json/list?t=' + new Date().getTime(), true);
- tabs_list_request.onreadystatechange = onReady;
- tabs_list_request.send();
+ var tabsListRequest = new XMLHttpRequest();
+ tabsListRequest.open('GET', '/json/list', true);
+ tabsListRequest.onreadystatechange = onReady;
+ tabsListRequest.send();
}
function onReady() {
@@ -24,23 +61,35 @@ function onReady() {
}
}
+function overrideFrontendUrl(item) {
+ if (window.location.hash) {
+ var overridden_url = window.location.hash.substr(1);
+ var ws_suffix = item.webSocketDebuggerUrl.replace('ws://', 'ws=');
+ if (overridden_url.indexOf('?') == -1)
+ return overridden_url + '?' + ws_suffix;
+ else
+ return overridden_url + '&' + ws_suffix;
+ }
+ return item.devtoolsFrontendUrl;
+}
+
function appendItem(item_object) {
var frontend_ref;
if (item_object.devtoolsFrontendUrl) {
frontend_ref = document.createElement('a');
- frontend_ref.href = item_object.devtoolsFrontendUrl;
+ frontend_ref.href = overrideFrontendUrl(item_object);
frontend_ref.title = item_object.title;
} else {
frontend_ref = document.createElement('div');
- frontend_ref.title = 'The tab already has active debugging session';
+ frontend_ref.title = 'The tab already has an active debug session';
}
+ frontend_ref.className = 'frontend_ref';
var text = document.createElement('div');
- if (item_object.title)
- text.innerText = item_object.title;
- else
- text.innerText = '(untitled tab)';
- text.style.cssText = 'background-image:url(' + item_object.faviconUrl + ')';
+ text.className = 'text';
+ text.innerText = item_object.description || item_object.title;
+ text.style.cssText = 'background-image:url(' +
+ item_object.faviconUrl + ')';
frontend_ref.appendChild(text);
var item = document.createElement('p');
@@ -51,7 +100,9 @@ function appendItem(item_object) {
</script>
</head>
<body onload='onLoad()'>
- <div id='caption'>Inspectable WebContents</div>
- <div id='items'></div>
+ <div id='caption'>Inspectable pages</div>
+ <div id='items'>
+ </div>
+ <hr>
</body>
</html>
diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h
index 9d9cdd675..781023b7c 100644
--- a/src/core/type_conversion.h
+++ b/src/core/type_conversion.h
@@ -39,6 +39,7 @@
#include <QColor>
#include <QDateTime>
+#include <QDir>
#include <QMatrix4x4>
#include <QRect>
#include <QString>
@@ -135,10 +136,14 @@ inline QDateTime toQt(base::Time time)
return QDateTime::fromMSecsSinceEpoch(time.ToJavaTime());
}
+inline base::Time toTime(const QDateTime &dateTime) {
+ return base::Time::FromInternalValue(dateTime.toMSecsSinceEpoch());
+}
+
inline base::FilePath::StringType toFilePathString(const QString &str)
{
#if defined(OS_WIN)
- return str.toStdWString();
+ return QDir::toNativeSeparators(str).toStdWString();
#else
return str.toStdString();
#endif
@@ -150,7 +155,7 @@ inline base::FilePath toFilePath(const QString &str)
}
template <typename T>
-inline T fileListingHelper(const QString &) {qFatal("Specialization missing for %s.", Q_FUNC_INFO);}
+inline T fileListingHelper(const QString &) {qFatal("Specialization missing for %s.", Q_FUNC_INFO); return T(); }
template <>
inline ui::SelectedFileInfo fileListingHelper<ui::SelectedFileInfo>(const QString &file)
diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp
index 8ec600a85..5d32ef470 100644
--- a/src/core/url_request_context_getter_qt.cpp
+++ b/src/core/url_request_context_getter_qt.cpp
@@ -61,125 +61,229 @@
#include "net/url_request/ftp_protocol_handler.h"
#include "net/ftp/ftp_network_layer.h"
-#include "network_delegate_qt.h"
+#include "browser_context_adapter.h"
#include "content_client_qt.h"
+#include "network_delegate_qt.h"
#include "qrc_protocol_handler_qt.h"
+#include "type_conversion.h"
static const char kQrcSchemeQt[] = "qrc";
using content::BrowserThread;
-URLRequestContextGetterQt::URLRequestContextGetterQt(const base::FilePath &dataPath, const base::FilePath &cachePath, content::ProtocolHandlerMap *protocolHandlers)
+URLRequestContextGetterQt::URLRequestContextGetterQt(BrowserContextAdapter *browserContext, content::ProtocolHandlerMap *protocolHandlers)
: m_ignoreCertificateErrors(false)
- , m_dataPath(dataPath)
- , m_cachePath(cachePath)
+ , m_updateStorageSettings(false)
+ , m_updateCookieStore(false)
+ , m_updateHttpCache(false)
+ , m_browserContext(browserContext)
{
std::swap(m_protocolHandlers, *protocolHandlers);
- // We must create the proxy config service on the UI loop on Linux because it
- // must synchronously run on the glib message loop. This will be passed to
- // the URLRequestContextStorage on the IO thread in GetURLRequestContext().
-//#ifdef Q_OS_LINUX
- m_proxyConfigService.reset(net::ProxyService::CreateSystemProxyConfigService(BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO)->message_loop_proxy()
- , BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE)));
-//#endif
+ updateStorageSettings();
}
net::URLRequestContext *URLRequestContextGetterQt::GetURLRequestContext()
{
if (!m_urlRequestContext) {
-
m_urlRequestContext.reset(new net::URLRequestContext());
- m_networkDelegate.reset(new NetworkDelegateQt);
+ m_networkDelegate.reset(new NetworkDelegateQt);
m_urlRequestContext->set_network_delegate(m_networkDelegate.get());
- base::FilePath cookiesPath = m_dataPath.Append(FILE_PATH_LITERAL("Cookies"));
- content::CookieStoreConfig cookieStoreConfig(cookiesPath, content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES, NULL, NULL);
- scoped_refptr<net::CookieStore> cookieStore = content::CreateCookieStore(cookieStoreConfig);
+ generateStorage();
+ generateJobFactory();
+ }
+
+ return m_urlRequestContext.get();
+}
+
+void URLRequestContextGetterQt::updateStorageSettings()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ if (!m_proxyConfigService) {
+ // We must create the proxy config service on the UI loop on Linux because it
+ // must synchronously run on the glib message loop. This will be passed to
+ // the URLRequestContextStorage on the IO thread in GetURLRequestContext().
+ m_proxyConfigService.reset(net::ProxyService::CreateSystemProxyConfigService(
+ BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO)->message_loop_proxy(),
+ BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE))
+ );
+ }
+ if (m_storage && !m_updateStorageSettings) {
+ m_updateStorageSettings = true;
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateStorage, this));
+ }
+}
+
+void URLRequestContextGetterQt::generateStorage()
+{
+ Q_ASSERT(m_urlRequestContext);
+ Q_ASSERT(m_proxyConfigService);
+ m_updateStorageSettings = false;
+
+ m_storage.reset(new net::URLRequestContextStorage(m_urlRequestContext.get()));
+
+ generateCookieStore();
+ generateUserAgent();
+
+ m_storage->set_server_bound_cert_service(new net::ServerBoundCertService(
+ new net::DefaultServerBoundCertStore(NULL),
+ base::WorkerPool::GetTaskRunner(true)));
+
+ m_storage->set_cert_verifier(net::CertVerifier::CreateDefault());
+ m_storage->set_proxy_service(net::ProxyService::CreateUsingSystemProxyResolver(
+ m_proxyConfigService.release(), 0, NULL));
+ m_storage->set_ssl_config_service(new net::SSLConfigServiceDefaults);
+ m_storage->set_transport_security_state(new net::TransportSecurityState());
+
+ scoped_ptr<net::HostResolver> host_resolver(net::HostResolver::CreateDefaultResolver(NULL));
+ m_storage->set_http_auth_handler_factory(net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get()));
+ m_storage->set_http_server_properties(scoped_ptr<net::HttpServerProperties>(new net::HttpServerPropertiesImpl));
+
+ // Give |m_storage| ownership at the end in case it's |mapped_host_resolver|.
+ m_storage->set_host_resolver(host_resolver.Pass());
+
+ generateHttpCache();
+}
+
+void URLRequestContextGetterQt::updateCookieStore()
+{
+ if (m_urlRequestContext && !m_updateCookieStore && !m_updateStorageSettings) {
+ m_updateCookieStore = true;
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateCookieStore, this));
+ }
+}
- m_storage.reset(new net::URLRequestContextStorage(m_urlRequestContext.get()));
- m_storage->set_cookie_store(cookieStore.get());
- m_storage->set_server_bound_cert_service(new net::ServerBoundCertService(
- new net::DefaultServerBoundCertStore(NULL),
- base::WorkerPool::GetTaskRunner(true)));
- m_storage->set_http_user_agent_settings(
- new net::StaticHttpUserAgentSettings("en-us,en", ContentClientQt::getUserAgent()));
+void URLRequestContextGetterQt::generateCookieStore()
+{
+ Q_ASSERT(m_urlRequestContext);
+ Q_ASSERT(m_storage);
+ m_updateCookieStore = false;
- scoped_ptr<net::HostResolver> host_resolver(
- net::HostResolver::CreateDefaultResolver(NULL));
+ // Unset it first to get a chance to destroy and flush the old cookie store before before opening a new on possibly the same file.
+ m_storage->set_cookie_store(0);
- m_storage->set_cert_verifier(net::CertVerifier::CreateDefault());
+ net::CookieStore* cookieStore = 0;
+ switch (m_browserContext->persistentCookiesPolicy()) {
+ case BrowserContextAdapter::NoPersistentCookies:
+ cookieStore =
+ content::CreateCookieStore(content::CookieStoreConfig(
+ base::FilePath(),
+ content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES,
+ NULL, NULL)
+ );
+ break;
+ case BrowserContextAdapter::AllowPersistentCookies:
+ cookieStore =
+ content::CreateCookieStore(content::CookieStoreConfig(
+ toFilePath(m_browserContext->cookiesPath()),
+ content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES,
+ NULL, NULL)
+ );
+ break;
+ case BrowserContextAdapter::ForcePersistentCookies:
+ cookieStore =
+ content::CreateCookieStore(content::CookieStoreConfig(
+ toFilePath(m_browserContext->cookiesPath()),
+ content::CookieStoreConfig::RESTORED_SESSION_COOKIES,
+ NULL, NULL)
+ );
+ break;
+ }
+ m_storage->set_cookie_store(cookieStore);
+}
- m_storage->set_proxy_service(net::ProxyService::CreateUsingSystemProxyResolver(m_proxyConfigService.release(), 0, NULL));
+void URLRequestContextGetterQt::updateUserAgent()
+{
+ if (m_urlRequestContext && !m_updateStorageSettings)
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateUserAgent, this));
+}
- m_storage->set_ssl_config_service(new net::SSLConfigServiceDefaults);
- m_storage->set_transport_security_state(new net::TransportSecurityState());
+void URLRequestContextGetterQt::generateUserAgent()
+{
+ Q_ASSERT(m_urlRequestContext);
+ Q_ASSERT(m_storage);
- m_storage->set_http_auth_handler_factory(
- net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get()));
- m_storage->set_http_server_properties(scoped_ptr<net::HttpServerProperties>(new net::HttpServerPropertiesImpl));
+ m_storage->set_http_user_agent_settings(
+ new net::StaticHttpUserAgentSettings("en-us,en", m_browserContext->httpUserAgent().toStdString()));
+}
- base::FilePath cache_path = m_cachePath.Append(FILE_PATH_LITERAL("Cache"));
- net::HttpCache::DefaultBackend* main_backend =
+void URLRequestContextGetterQt::updateHttpCache()
+{
+ if (m_urlRequestContext && !m_updateHttpCache && !m_updateStorageSettings) {
+ m_updateHttpCache = true;
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateHttpCache, this));
+ }
+}
+
+void URLRequestContextGetterQt::generateHttpCache()
+{
+ Q_ASSERT(m_urlRequestContext);
+ Q_ASSERT(m_storage);
+ m_updateHttpCache = false;
+
+ net::HttpCache::DefaultBackend* main_backend = 0;
+ switch (m_browserContext->httpCacheType()) {
+ case BrowserContextAdapter::MemoryHttpCache:
+ main_backend =
+ new net::HttpCache::DefaultBackend(
+ net::MEMORY_CACHE,
+ net::CACHE_BACKEND_DEFAULT,
+ base::FilePath(),
+ m_browserContext->httpCacheMaxSize(),
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)
+ );
+ break;
+ case BrowserContextAdapter::DiskHttpCache:
+ main_backend =
new net::HttpCache::DefaultBackend(
net::DISK_CACHE,
net::CACHE_BACKEND_DEFAULT,
- cache_path,
- 0,
- BrowserThread::GetMessageLoopProxyForThread(
- BrowserThread::CACHE));
-
- net::HttpNetworkSession::Params network_session_params;
- network_session_params.transport_security_state =
- m_urlRequestContext->transport_security_state();
- network_session_params.cert_verifier =
- m_urlRequestContext->cert_verifier();
- network_session_params.server_bound_cert_service =
- m_urlRequestContext->server_bound_cert_service();
- network_session_params.proxy_service =
- m_urlRequestContext->proxy_service();
- network_session_params.ssl_config_service =
- m_urlRequestContext->ssl_config_service();
- network_session_params.http_auth_handler_factory =
- m_urlRequestContext->http_auth_handler_factory();
- network_session_params.network_delegate =
- m_networkDelegate.get();
- network_session_params.http_server_properties =
- m_urlRequestContext->http_server_properties();
- network_session_params.ignore_certificate_errors =
- m_ignoreCertificateErrors;
-
- // Give |m_storage| ownership at the end in case it's |mapped_host_resolver|.
- m_storage->set_host_resolver(host_resolver.Pass());
- network_session_params.host_resolver =
- m_urlRequestContext->host_resolver();
-
- net::HttpCache* main_cache = new net::HttpCache(
- network_session_params, main_backend);
- m_storage->set_http_transaction_factory(main_cache);
-
-
- m_jobFactory.reset(new net::URLRequestJobFactoryImpl());
-
- // Chromium has a few protocol handlers ready for us, only pick blob: and throw away the rest.
- content::ProtocolHandlerMap::iterator it = m_protocolHandlers.find(url::kBlobScheme);
- Q_ASSERT(it != m_protocolHandlers.end());
- m_jobFactory->SetProtocolHandler(it->first, it->second.release());
- m_protocolHandlers.clear();
-
- m_jobFactory->SetProtocolHandler(url::kDataScheme, new net::DataProtocolHandler());
- m_jobFactory->SetProtocolHandler(url::kFileScheme, new net::FileProtocolHandler(
- content::BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
- m_jobFactory->SetProtocolHandler(kQrcSchemeQt, new QrcProtocolHandlerQt());
- m_jobFactory->SetProtocolHandler(url::kFtpScheme, new net::FtpProtocolHandler(
- new net::FtpNetworkLayer(m_urlRequestContext->host_resolver())));
- m_urlRequestContext->set_job_factory(m_jobFactory.get());
+ toFilePath(m_browserContext->httpCachePath()),
+ m_browserContext->httpCacheMaxSize(),
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)
+ );
+ break;
}
- return m_urlRequestContext.get();
+ net::HttpNetworkSession::Params network_session_params;
+ network_session_params.transport_security_state = m_urlRequestContext->transport_security_state();
+ network_session_params.cert_verifier = m_urlRequestContext->cert_verifier();
+ network_session_params.server_bound_cert_service = m_urlRequestContext->server_bound_cert_service();
+ network_session_params.proxy_service = m_urlRequestContext->proxy_service();
+ network_session_params.ssl_config_service = m_urlRequestContext->ssl_config_service();
+ network_session_params.http_auth_handler_factory = m_urlRequestContext->http_auth_handler_factory();
+ network_session_params.network_delegate = m_networkDelegate.get();
+ network_session_params.http_server_properties = m_urlRequestContext->http_server_properties();
+ network_session_params.ignore_certificate_errors = m_ignoreCertificateErrors;
+ network_session_params.host_resolver = m_urlRequestContext->host_resolver();
+
+ m_storage->set_http_transaction_factory(new net::HttpCache(network_session_params, main_backend));
}
+void URLRequestContextGetterQt::generateJobFactory()
+{
+ Q_ASSERT(m_urlRequestContext);
+ Q_ASSERT(!m_jobFactory);
+ m_jobFactory.reset(new net::URLRequestJobFactoryImpl());
+
+ // Chromium has a few protocol handlers ready for us, only pick blob: and throw away the rest.
+ content::ProtocolHandlerMap::iterator it = m_protocolHandlers.find(url::kBlobScheme);
+ Q_ASSERT(it != m_protocolHandlers.end());
+ m_jobFactory->SetProtocolHandler(it->first, it->second.release());
+ m_protocolHandlers.clear();
+
+ m_jobFactory->SetProtocolHandler(url::kDataScheme, new net::DataProtocolHandler());
+ m_jobFactory->SetProtocolHandler(url::kFileScheme, new net::FileProtocolHandler(
+ content::BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
+ base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
+ m_jobFactory->SetProtocolHandler(kQrcSchemeQt, new QrcProtocolHandlerQt());
+ m_jobFactory->SetProtocolHandler(url::kFtpScheme,
+ new net::FtpProtocolHandler(new net::FtpNetworkLayer(m_urlRequestContext->host_resolver())));
+
+ m_urlRequestContext->set_job_factory(m_jobFactory.get());
+}
scoped_refptr<base::SingleThreadTaskRunner> URLRequestContextGetterQt::GetNetworkTaskRunner() const
{
diff --git a/src/core/url_request_context_getter_qt.h b/src/core/url_request_context_getter_qt.h
index 6c9ac6d59..5f6048403 100644
--- a/src/core/url_request_context_getter_qt.h
+++ b/src/core/url_request_context_getter_qt.h
@@ -40,6 +40,7 @@
#include "net/url_request/url_request_context_getter.h"
#include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/single_thread_task_runner.h"
#include "content/public/browser/content_browser_client.h"
@@ -50,25 +51,41 @@
#include "qglobal.h"
namespace net {
-class HostResolver;
class MappedHostResolver;
class NetworkDelegate;
class ProxyConfigService;
}
+class BrowserContextAdapter;
+
class URLRequestContextGetterQt : public net::URLRequestContextGetter {
public:
- explicit URLRequestContextGetterQt(const base::FilePath &, const base::FilePath &, content::ProtocolHandlerMap *protocolHandlers);
+ explicit URLRequestContextGetterQt(BrowserContextAdapter *browserContext, content::ProtocolHandlerMap *protocolHandlers);
virtual net::URLRequestContext *GetURLRequestContext() Q_DECL_OVERRIDE;
virtual scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() const Q_DECL_OVERRIDE;
+ // Called on the UI thread:
+ void updateStorageSettings();
+ void updateUserAgent();
+ void updateCookieStore();
+ void updateHttpCache();
+
private:
virtual ~URLRequestContextGetterQt() {}
+ // Called on the IO thread:
+ void generateStorage();
+ void generateCookieStore();
+ void generateHttpCache();
+ void generateUserAgent();
+ void generateJobFactory();
+
bool m_ignoreCertificateErrors;
- base::FilePath m_dataPath;
- base::FilePath m_cachePath;
+ volatile bool m_updateStorageSettings;
+ volatile bool m_updateCookieStore;
+ volatile bool m_updateHttpCache;
+ BrowserContextAdapter *m_browserContext;
content::ProtocolHandlerMap m_protocolHandlers;
scoped_ptr<net::ProxyConfigService> m_proxyConfigService;
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 3f223f733..9398046d0 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -41,6 +41,7 @@
#include "web_contents_adapter.h"
#include "web_contents_adapter_p.h"
+#include "browser_context_adapter.h"
#include "browser_context_qt.h"
#include "content_browser_client_qt.h"
#include "javascript_dialog_manager_qt.h"
@@ -175,9 +176,8 @@ static QStringList listRecursively(const QDir& dir) {
return ret;
}
-static content::WebContents *createBlankWebContents(WebContentsAdapterClient *adapterClient)
+static content::WebContents *createBlankWebContents(WebContentsAdapterClient *adapterClient, content::BrowserContext *browserContext)
{
- content::BrowserContext* browserContext = ContentBrowserClientQt::Get()->browser_context();
content::WebContents::CreateParams create_params(browserContext, NULL);
create_params.routing_id = MSG_ROUTING_NONE;
create_params.initial_size = gfx::Size(kTestWindowWidth, kTestWindowHeight);
@@ -222,7 +222,7 @@ static void serializeNavigationHistory(const content::NavigationController &cont
}
}
-void deserializeNavigationHistory(QDataStream &input, int *currentIndex, std::vector<content::NavigationEntry*> *entries)
+static void deserializeNavigationHistory(QDataStream &input, int *currentIndex, std::vector<content::NavigationEntry*> *entries, content::BrowserContext *browserContext)
{
int version;
input >> version;
@@ -278,7 +278,7 @@ void deserializeNavigationHistory(QDataStream &input, int *currentIndex, std::ve
false,
// The extra headers are not sync'ed across sessions.
std::string(),
- ContentBrowserClientQt::Get()->browser_context());
+ browserContext);
entry->SetTitle(toString16(title));
entry->SetPageState(content::PageState::CreateFromEncodedData(std::string(pageState.data(), pageState.size())));
@@ -292,6 +292,30 @@ void deserializeNavigationHistory(QDataStream &input, int *currentIndex, std::ve
}
}
+namespace {
+static QList<WebContentsAdapter *> recursive_guard_loading_adapters;
+
+class LoadRecursionGuard {
+ public:
+ static bool isGuarded(WebContentsAdapter *adapter)
+ {
+ return recursive_guard_loading_adapters.contains(adapter);
+ }
+ LoadRecursionGuard(WebContentsAdapter *adapter)
+ : m_adapter(adapter)
+ {
+ recursive_guard_loading_adapters.append(adapter);
+ }
+
+ ~LoadRecursionGuard() {
+ recursive_guard_loading_adapters.removeOne(m_adapter);
+ }
+
+ private:
+ WebContentsAdapter *m_adapter;
+};
+} // Anonymous namespace
+
WebContentsAdapterPrivate::WebContentsAdapterPrivate()
// This has to be the first thing we create, and the last we destroy.
: engineContext(WebEngineContext::current())
@@ -308,13 +332,13 @@ QExplicitlySharedDataPointer<WebContentsAdapter> WebContentsAdapter::createFromS
{
int currentIndex;
std::vector<content::NavigationEntry*> entries;
- deserializeNavigationHistory(input, &currentIndex, &entries);
+ deserializeNavigationHistory(input, &currentIndex, &entries, adapterClient->browserContextAdapter()->browserContext());
if (currentIndex == -1)
return QExplicitlySharedDataPointer<WebContentsAdapter>();
// Unlike WebCore, Chromium only supports Restoring to a new WebContents instance.
- content::WebContents* newWebContents = createBlankWebContents(adapterClient);
+ content::WebContents* newWebContents = createBlankWebContents(adapterClient, adapterClient->browserContextAdapter()->browserContext());
content::NavigationController &controller = newWebContents->GetController();
controller.Restore(currentIndex, content::NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY, &entries);
@@ -347,10 +371,13 @@ void WebContentsAdapter::initialize(WebContentsAdapterClient *adapterClient)
{
Q_D(WebContentsAdapter);
d->adapterClient = adapterClient;
+ // We keep a reference to browserContextAdapter to keep it alive as long as we use it.
+ // This is needed in case the QML WebEngineProfile is garbage collected before the WebEnginePage.
+ d->browserContextAdapter = adapterClient->browserContextAdapter();
// Create our own if a WebContents wasn't provided at construction.
if (!d->webContents)
- d->webContents.reset(createBlankWebContents(adapterClient));
+ d->webContents.reset(createBlankWebContents(adapterClient, d->browserContextAdapter->browserContext()));
// This might replace any adapter that has been initialized with this WebEngineSettings.
adapterClient->webEngineSettings()->setWebContentsAdapter(this);
@@ -421,6 +448,19 @@ void WebContentsAdapter::reload()
void WebContentsAdapter::load(const QUrl &url)
{
+ // The situation can occur when relying on the editingFinished signal in QML to set the url
+ // of the WebView.
+ // When enter is pressed, onEditingFinished fires and the url of the webview is set, which
+ // calls into this and focuses the webview, taking the focus from the TextField/TextInput,
+ // which in turn leads to editingFinished firing again. This scenario would cause a crash
+ // down the line when unwinding as the first RenderWidgetHostViewQtDelegateQuick instance is
+ // a dangling pointer by that time.
+
+ if (LoadRecursionGuard::isGuarded(this))
+ return;
+ LoadRecursionGuard guard(this);
+ Q_UNUSED(guard);
+
Q_D(WebContentsAdapter);
content::NavigationController::LoadURLParams params(toGurl(url));
params.transition_type = content::PageTransitionFromInt(content::PAGE_TRANSITION_TYPED | content::PAGE_TRANSITION_FROM_ADDRESS_BAR);
@@ -625,7 +665,13 @@ qreal WebContentsAdapter::currentZoomFactor() const
void WebContentsAdapter::enableInspector(bool enable)
{
- ContentBrowserClientQt::Get()->enableInspector(enable);
+ ContentBrowserClientQt::Get()->enableInspector(enable, browserContext());
+}
+
+BrowserContextQt* WebContentsAdapter::browserContext()
+{
+ Q_D(WebContentsAdapter);
+ return d->browserContextAdapter->browserContext();
}
QAccessibleInterface *WebContentsAdapter::browserAccessible()
@@ -724,6 +770,26 @@ void WebContentsAdapter::grantMediaAccessPermission(const QUrl &securityOrigin,
MediaCaptureDevicesDispatcher::GetInstance()->handleMediaAccessPermissionResponse(d->webContents.get(), securityOrigin, flags);
}
+void WebContentsAdapter::runGeolocationRequestCallback(const QUrl &securityOrigin, bool allowed)
+{
+ Q_D(WebContentsAdapter);
+ d->webContentsDelegate->m_lastGeolocationRequestCallbacks.first.Run(allowed);
+}
+
+void WebContentsAdapter::grantMouseLockPermission(bool granted)
+{
+ Q_D(WebContentsAdapter);
+
+ if (granted) {
+ if (RenderWidgetHostViewQt *rwhv = static_cast<RenderWidgetHostViewQt *>(d->webContents->GetRenderWidgetHostView()))
+ rwhv->Focus();
+ else
+ granted = false;
+ }
+
+ d->webContents->GotResponseToLockMouseRequest(granted);
+}
+
void WebContentsAdapter::dpiScaleChanged()
{
Q_D(WebContentsAdapter);
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 6bec50316..432380be2 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -48,6 +48,7 @@
namespace content {
class WebContents;
}
+class BrowserContextQt;
class WebContentsAdapterPrivate;
struct WebPreferences;
@@ -108,14 +109,18 @@ public:
void wasShown();
void wasHidden();
void grantMediaAccessPermission(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags flags);
+ void runGeolocationRequestCallback(const QUrl &securityOrigin, bool allowed);
+ void grantMouseLockPermission(bool granted);
void dpiScaleChanged();
QAccessibleInterface *browserAccessible();
+ BrowserContextQt* browserContext();
private:
Q_DISABLE_COPY(WebContentsAdapter);
Q_DECLARE_PRIVATE(WebContentsAdapter);
QScopedPointer<WebContentsAdapterPrivate> d_ptr;
+
friend class WebContentsDelegateQt;
};
#endif // WEB_CONTENTS_ADAPTER_H
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 8fd401fe4..f4e2c658f 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -48,6 +48,7 @@
QT_FORWARD_DECLARE_CLASS(QVariant)
+class BrowserContextAdapter;
class CertificateErrorController;
class JavaScriptDialogController;
class RenderWidgetHostViewQt;
@@ -171,11 +172,15 @@ public:
virtual QObject *accessibilityParentObject() = 0;
virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) = 0;
virtual void authenticationRequired(const QUrl &requestUrl, const QString &realm, bool isProxy, const QString &challengingHost, QString *outUser, QString *outPassword) = 0;
+ virtual void runGeolocationPermissionRequest(const QUrl &securityOrigin) = 0;
virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) = 0;
+ virtual void runMouseLockPermissionRequest(const QUrl &securityOrigin) = 0;
virtual WebEngineSettings *webEngineSettings() const = 0;
virtual void allowCertificateError(const QExplicitlySharedDataPointer<CertificateErrorController> &errorController) = 0;
+ virtual BrowserContextAdapter* browserContextAdapter() = 0;
+
};
#endif // WEB_CONTENTS_ADAPTER_CLIENT_H
diff --git a/src/core/web_contents_adapter_p.h b/src/core/web_contents_adapter_p.h
index 28df0113a..f47c05de0 100644
--- a/src/core/web_contents_adapter_p.h
+++ b/src/core/web_contents_adapter_p.h
@@ -42,6 +42,9 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include <QExplicitlySharedDataPointer>
+
+class BrowserContextAdapter;
class QtRenderViewObserverHost;
class WebContentsAdapterClient;
class WebContentsDelegateQt;
@@ -52,6 +55,7 @@ public:
WebContentsAdapterPrivate();
~WebContentsAdapterPrivate();
scoped_refptr<WebEngineContext> engineContext;
+ QExplicitlySharedDataPointer<BrowserContextAdapter> browserContextAdapter;
scoped_ptr<content::WebContents> webContents;
scoped_ptr<WebContentsDelegateQt> webContentsDelegate;
scoped_ptr<QtRenderViewObserverHost> renderViewObserverHost;
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index c2cccfedb..d64584c47 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -40,6 +40,7 @@
#include "web_contents_delegate_qt.h"
+#include "browser_context_adapter.h"
#include "media_capture_devices_dispatcher.h"
#include "type_conversion.h"
#include "web_contents_adapter_client.h"
@@ -268,11 +269,21 @@ void WebContentsDelegateQt::UpdateTargetURL(content::WebContents *source, int32
void WebContentsDelegateQt::DidNavigateAnyFrame(const content::LoadCommittedDetails &, const content::FrameNavigateParams &params)
{
- if (!params.should_update_history)
+ // VisistedLinksMaster asserts !IsOffTheRecord().
+ if (!params.should_update_history || !m_viewClient->browserContextAdapter()->trackVisitedLinks())
return;
- WebEngineContext::current()->visitedLinksManager()->addUrl(params.url);
+ m_viewClient->browserContextAdapter()->visitedLinksManager()->addUrl(params.url);
}
+void WebContentsDelegateQt::RequestToLockMouse(content::WebContents *web_contents, bool user_gesture, bool last_unlocked_by_target)
+{
+ Q_UNUSED(user_gesture);
+
+ if (last_unlocked_by_target)
+ web_contents->GotResponseToLockMouseRequest(true);
+ else
+ m_viewClient->runMouseLockPermissionRequest(toQt(web_contents->GetVisibleURL()));
+}
void WebContentsDelegateQt::overrideWebPreferences(content::WebContents *, WebPreferences *webPreferences)
{
@@ -300,3 +311,9 @@ void WebContentsDelegateQt::allowCertificateError(const QExplicitlySharedDataPoi
{
m_viewClient->allowCertificateError(errorController);
}
+
+void WebContentsDelegateQt::requestGeolocationPermission(const GURL &requestingFrameOrigin, base::Callback<void (bool)> resultCallback, base::Closure *cancelCallback)
+{
+ m_lastGeolocationRequestCallbacks = qMakePair(resultCallback, cancelCallback);
+ m_viewClient->runGeolocationPermissionRequest(toQt(requestingFrameOrigin));
+}
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 2ab5fc8cd..aa97b52cc 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -40,6 +40,8 @@
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
+#include "base/callback.h"
+
#include "javascript_dialog_manager_qt.h"
#include <QtCore/qcompilerdetection.h>
@@ -85,10 +87,13 @@ public:
virtual void RequestMediaAccessPermission(content::WebContents* web_contents, const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback) Q_DECL_OVERRIDE;
virtual void UpdateTargetURL(content::WebContents *source, int32 page_id, const GURL &url) Q_DECL_OVERRIDE;
virtual void DidNavigateAnyFrame(const content::LoadCommittedDetails&, const content::FrameNavigateParams& params) Q_DECL_OVERRIDE;
+ virtual void RequestToLockMouse(content::WebContents *web_contents, bool user_gesture, bool last_unlocked_by_target) Q_DECL_OVERRIDE;
void overrideWebPreferences(content::WebContents *, WebPreferences*);
void allowCertificateError(const QExplicitlySharedDataPointer<CertificateErrorController> &) ;
+ void requestGeolocationPermission(const GURL &requestingFrameOrigin, base::Callback<void (bool)> resultCallback, base::Closure *cancelCallback);
+ QPair<base::Callback<void (bool)>, base::Closure*> m_lastGeolocationRequestCallbacks;
private:
WebContentsAdapter *createWindow(content::WebContents *new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture);
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 446f0e92c..85c1136d9 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -66,6 +66,7 @@
#include "content/public/app/startup_helper_win.h"
#endif // OS_WIN
+#include "browser_context_adapter.h"
#include "content_browser_client_qt.h"
#include "content_client_qt.h"
#include "content_main_delegate_qt.h"
@@ -74,7 +75,7 @@
#include "type_conversion.h"
#include "surface_factory_qt.h"
#include "web_engine_library_info.h"
-#include "web_engine_visited_links_manager.h"
+#include <QFileInfo>
#include <QGuiApplication>
#include <QOpenGLContext>
#include <QStringList>
@@ -90,6 +91,46 @@ void destroyContext()
sContext = 0;
}
+bool usingANGLE()
+{
+#if defined(Q_OS_WIN)
+ return QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES;
+#else
+ return false;
+#endif
+}
+
+bool usingSoftwareDynamicGL()
+{
+#if defined(Q_OS_WIN)
+ HMODULE handle = static_cast<HMODULE>(QOpenGLContext::openGLModuleHandle());
+ wchar_t path[MAX_PATH];
+ DWORD size = GetModuleFileName(handle, path, MAX_PATH);
+ QFileInfo openGLModule(QString::fromWCharArray(path, size));
+ return openGLModule.fileName() == QLatin1String("opengl32sw.dll");
+#else
+ return false;
+#endif
+}
+
+bool usingQtQuick2DRenderer()
+{
+ const QStringList args = QGuiApplication::arguments();
+ QString device;
+ for (int index = 0; index < args.count(); ++index) {
+ if (args.at(index).startsWith(QLatin1String("--device="))) {
+ device = args.at(index).mid(9);
+ break;
+ }
+ }
+
+ if (device.isEmpty())
+ device = QString::fromLocal8Bit(qgetenv("QMLSCENE_DEVICE"));
+
+ // This assumes that the plugin is installed and is going to be used by QtQuick.
+ return device == QLatin1String("softwarecontext");
+}
+
} // namespace
WebEngineContext::~WebEngineContext()
@@ -111,9 +152,18 @@ scoped_refptr<WebEngineContext> WebEngineContext::current()
return sContext;
}
-WebEngineVisitedLinksManager *WebEngineContext::visitedLinksManager()
+BrowserContextAdapter* WebEngineContext::defaultBrowserContext()
{
- return m_visitedLinksManager.get();
+ if (!m_defaultBrowserContext)
+ m_defaultBrowserContext = new BrowserContextAdapter(QStringLiteral("Default"));
+ return m_defaultBrowserContext.data();
+}
+
+BrowserContextAdapter* WebEngineContext::offTheRecordBrowserContext()
+{
+ if (!m_offTheRecordBrowserContext)
+ m_offTheRecordBrowserContext = new BrowserContextAdapter(true);
+ return m_offTheRecordBrowserContext.data();
}
#ifndef CHROMIUM_VERSION
@@ -180,16 +230,20 @@ WebEngineContext::WebEngineContext()
GLContextHelper::initialize();
- const char *glType;
- switch (QOpenGLContext::currentContext()->openGLModuleType()) {
- case QOpenGLContext::LibGL:
- glType = gfx::kGLImplementationDesktopName;
- break;
- case QOpenGLContext::LibGLES:
- glType = gfx::kGLImplementationEGLName;
- break;
+ if (usingANGLE() || usingSoftwareDynamicGL() || usingQtQuick2DRenderer()) {
+ parsedCommandLine->AppendSwitch(switches::kDisableGpu);
+ } else {
+ const char *glType;
+ switch (QOpenGLContext::openGLModuleType()) {
+ case QOpenGLContext::LibGL:
+ glType = gfx::kGLImplementationDesktopName;
+ break;
+ case QOpenGLContext::LibGLES:
+ glType = gfx::kGLImplementationEGLName;
+ break;
+ }
+ parsedCommandLine->AppendSwitchASCII(switches::kUseGL, glType);
}
- parsedCommandLine->AppendSwitchASCII(switches::kUseGL, glType);
content::UtilityProcessHostImpl::RegisterUtilityMainThreadFactory(content::CreateInProcessUtilityThread);
content::RenderProcessHostImpl::RegisterRendererMainThreadFactory(content::CreateInProcessRendererThread);
@@ -213,7 +267,4 @@ WebEngineContext::WebEngineContext()
// thread to avoid a thread check assertion in its constructor when it
// first gets referenced on the IO thread.
MediaCaptureDevicesDispatcher::GetInstance();
-
- // Ensure we have a VisitedLinksMaster instance up and running
- m_visitedLinksManager.reset(new WebEngineVisitedLinksManager);
}
diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h
index d1cd9a7a5..a44a48d3a 100644
--- a/src/core/web_engine_context.h
+++ b/src/core/web_engine_context.h
@@ -40,6 +40,8 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include <QExplicitlySharedDataPointer>
+
namespace base {
class RunLoop;
}
@@ -49,15 +51,16 @@ class BrowserMainRunner;
class ContentMainRunner;
}
+class BrowserContextAdapter;
class ContentMainDelegateQt;
class SurfaceFactoryQt;
-class WebEngineVisitedLinksManager;
class WebEngineContext : public base::RefCounted<WebEngineContext> {
public:
static scoped_refptr<WebEngineContext> current();
- WebEngineVisitedLinksManager *visitedLinksManager();
+ BrowserContextAdapter *defaultBrowserContext();
+ BrowserContextAdapter *offTheRecordBrowserContext();
private:
friend class base::RefCounted<WebEngineContext>;
@@ -71,7 +74,8 @@ private:
#if defined(OS_ANDROID)
scoped_ptr<SurfaceFactoryQt> m_surfaceFactory;
#endif
- scoped_ptr<WebEngineVisitedLinksManager> m_visitedLinksManager;
+ QExplicitlySharedDataPointer<BrowserContextAdapter> m_defaultBrowserContext;
+ QExplicitlySharedDataPointer<BrowserContextAdapter> m_offTheRecordBrowserContext;
};
#endif // WEB_ENGINE_CONTEXT_H
diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index 2d72dd5a2..452eee306 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -78,7 +78,7 @@ QString location(QLibraryInfo::LibraryLocation path)
switch (path) {
case QLibraryInfo::TranslationsPath:
if (!webEnginePath.isEmpty())
- return webEnginePath % QDir::separator() % QLatin1String("translations");
+ return webEnginePath % QLatin1String("/translations");
break;
case QLibraryInfo::DataPath:
if (!webEnginePath.isEmpty())
@@ -148,7 +148,7 @@ QString subProcessPath()
% QStringLiteral("/Helpers/" QTWEBENGINEPROCESS_NAME ".app/Contents/MacOS/" QTWEBENGINEPROCESS_NAME));
#else
static QString processPath (location(QLibraryInfo::LibraryExecutablesPath)
- % QDir::separator() % processBinary);
+ % QLatin1Char('/') % processBinary);
#endif
if (!initialized) {
// Allow overriding at runtime for the time being.
@@ -157,7 +157,7 @@ QString subProcessPath()
processPath = QString::fromLatin1(fromEnv);
if (!QFileInfo(processPath).exists()) {
qWarning("QtWebEngineProcess not found at location %s. Trying fallback path...", qPrintable(processPath));
- processPath = QCoreApplication::applicationDirPath() % QDir::separator() % processBinary;
+ processPath = QCoreApplication::applicationDirPath() % QLatin1Char('/') % processBinary;
}
if (!QFileInfo(processPath).exists())
qFatal("QtWebEngineProcess not found at location %s. Try setting the QTWEBENGINEPROCESS_PATH environment variable.", qPrintable(processPath));
@@ -172,7 +172,7 @@ QString pluginsPath()
#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD)
return getPath(frameworkBundle()) % QLatin1String("/Libraries");
#else
- return location(QLibraryInfo::PluginsPath) % QDir::separator() % QLatin1String("qtwebengine");
+ return location(QLibraryInfo::PluginsPath) % QLatin1String("/qtwebengine");
#endif
}
@@ -186,7 +186,7 @@ QString localesPath()
}
QString fallbackDir() {
- static QString directory = QDir::homePath() % QDir::separator() % QChar::fromLatin1('.') % QCoreApplication::applicationName();
+ static QString directory = QDir::homePath() % QLatin1String("/.") % QCoreApplication::applicationName();
return directory;
}
diff --git a/src/core/web_engine_visited_links_manager.cpp b/src/core/web_engine_visited_links_manager.cpp
index 36467ca21..c5ed54f3e 100644
--- a/src/core/web_engine_visited_links_manager.cpp
+++ b/src/core/web_engine_visited_links_manager.cpp
@@ -36,8 +36,9 @@
#include "web_engine_visited_links_manager.h"
-#include "content_browser_client_qt.h"
+#include "browser_context_adapter.h"
#include "browser_context_qt.h"
+#include "content_browser_client_qt.h"
#include "type_conversion.h"
#include "base/memory/scoped_ptr.h"
@@ -80,12 +81,17 @@ void WebEngineVisitedLinksManager::deleteVisitedLinkDataForUrls(const QList<QUrl
m_visitedLinkMaster->DeleteURLs(&iterator);
}
-WebEngineVisitedLinksManager::WebEngineVisitedLinksManager()
+bool WebEngineVisitedLinksManager::containsUrl(const QUrl &url) const
+{
+ return m_visitedLinkMaster->IsVisited(toGurl(url));
+}
+
+WebEngineVisitedLinksManager::WebEngineVisitedLinksManager(BrowserContextAdapter *adapter)
: m_delegate(new VisitedLinkDelegateQt)
{
- Q_ASSERT(ContentBrowserClientQt::Get() && ContentBrowserClientQt::Get()->browser_context());
- BrowserContextQt *browserContext = ContentBrowserClientQt::Get()->browser_context();
- m_visitedLinkMaster.reset(new visitedlink::VisitedLinkMaster(browserContext, m_delegate.data(), /* persist to disk = */true));
+ Q_ASSERT(adapter && adapter->browserContext());
+ BrowserContextQt *browserContext = adapter->browserContext();
+ m_visitedLinkMaster.reset(new visitedlink::VisitedLinkMaster(browserContext, m_delegate.data(), adapter->persistVisitedLinks()));
m_visitedLinkMaster->Init();
}
diff --git a/src/core/web_engine_visited_links_manager.h b/src/core/web_engine_visited_links_manager.h
index aa44dd9cf..dc2a4bff2 100644
--- a/src/core/web_engine_visited_links_manager.h
+++ b/src/core/web_engine_visited_links_manager.h
@@ -49,6 +49,7 @@ namespace visitedlink {
class VisitedLinkMaster;
}
+class BrowserContextAdapter;
class VisitedLinkDelegateQt;
class GURL;
@@ -57,11 +58,13 @@ class QWEBENGINE_EXPORT WebEngineVisitedLinksManager {
public:
virtual~WebEngineVisitedLinksManager();
- WebEngineVisitedLinksManager();
+ WebEngineVisitedLinksManager(BrowserContextAdapter*);
void deleteAllVisitedLinkData();
void deleteVisitedLinkDataForUrls(const QList<QUrl> &);
+ bool containsUrl(const QUrl &) const;
+
private:
void addUrl(const GURL &);
friend class WebContentsDelegateQt;
diff --git a/src/webengine/api/qquickwebenginedownloaditem.cpp b/src/webengine/api/qquickwebenginedownloaditem.cpp
new file mode 100644
index 000000000..729cb0d3f
--- /dev/null
+++ b/src/webengine/api/qquickwebenginedownloaditem.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickwebenginedownloaditem_p.h"
+#include "qquickwebenginedownloaditem_p_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QQuickWebEngineDownloadItemPrivate::QQuickWebEngineDownloadItemPrivate(QQuickWebEngineProfilePrivate *p)
+ : profile(p)
+ , downloadStarted(false)
+ , downloadId(-1)
+ , downloadState(QQuickWebEngineDownloadItem::DownloadCancelled)
+ , downloadProgress(0)
+{
+}
+
+QQuickWebEngineDownloadItemPrivate::~QQuickWebEngineDownloadItemPrivate()
+{
+ Q_Q(QQuickWebEngineDownloadItem);
+ q->cancel();
+}
+
+void QQuickWebEngineDownloadItemPrivate::update(QQuickWebEngineDownloadItem::DownloadState state, int progress)
+{
+ Q_Q(QQuickWebEngineDownloadItem);
+ if (state != downloadState) {
+ downloadState = state;
+ Q_EMIT q->stateChanged();
+ }
+ if (progress != downloadProgress) {
+ downloadProgress = progress;
+ Q_EMIT q->progressChanged();
+ }
+}
+
+void QQuickWebEngineDownloadItem::cancel()
+{
+ Q_D(QQuickWebEngineDownloadItem);
+
+ if (d->downloadState == QQuickWebEngineDownloadItem::DownloadCompleted
+ || d->downloadState == QQuickWebEngineDownloadItem::DownloadCancelled)
+ return;
+
+ d->update(QQuickWebEngineDownloadItem::DownloadCancelled, d->downloadProgress);
+
+ // We directly cancel the download if the user cancels before
+ // it even started, so no need to notify the profile here.
+ if (d->downloadStarted)
+ d->profile->cancelDownload(d->downloadId);
+}
+
+quint32 QQuickWebEngineDownloadItem::id()
+{
+ Q_D(QQuickWebEngineDownloadItem);
+ return d->downloadId;
+}
+
+QQuickWebEngineDownloadItem::DownloadState QQuickWebEngineDownloadItem::state()
+{
+ Q_D(QQuickWebEngineDownloadItem);
+ return d->downloadState;
+}
+
+int QQuickWebEngineDownloadItem::progress()
+{
+ Q_D(QQuickWebEngineDownloadItem);
+ return d->downloadProgress;
+}
+
+QString QQuickWebEngineDownloadItem::path()
+{
+ Q_D(QQuickWebEngineDownloadItem);
+ return d->downloadPath;
+}
+
+void QQuickWebEngineDownloadItem::setPath(QString path)
+{
+ Q_D(QQuickWebEngineDownloadItem);
+ if (d->downloadStarted) {
+ qWarning("Setting the download path is not allowed after the download has been started.");
+ return;
+ }
+ if (d->downloadPath != path) {
+ d->downloadPath = path;
+ Q_EMIT pathChanged();
+ }
+}
+
+QQuickWebEngineDownloadItem::QQuickWebEngineDownloadItem(QQuickWebEngineDownloadItemPrivate *p, QObject *parent)
+ : QObject(parent)
+ , d_ptr(p)
+{
+ p->q_ptr = this;
+}
+
+QQuickWebEngineDownloadItem::~QQuickWebEngineDownloadItem()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebenginedownloaditem_p.h b/src/webengine/api/qquickwebenginedownloaditem_p.h
new file mode 100644
index 000000000..8ea9f0850
--- /dev/null
+++ b/src/webengine/api/qquickwebenginedownloaditem_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKWEBENGINEDOWNLOADITEM_P_H
+#define QQUICKWEBENGINEDOWNLOADITEM_P_H
+
+#include <qtwebengineglobal_p.h>
+#include <QObject>
+#include <QScopedPointer>
+#include <QString>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickWebEngineDownloadItemPrivate;
+class QQuickWebEngineProfilePrivate;
+
+class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineDownloadItem: public QObject {
+ Q_OBJECT
+public:
+ ~QQuickWebEngineDownloadItem();
+ enum DownloadState {
+ DownloadInProgress,
+ DownloadCompleted,
+ DownloadCancelled,
+ DownloadInterrupted
+ };
+ Q_ENUMS(DownloadState)
+
+ Q_PROPERTY(quint32 id READ id() CONSTANT FINAL)
+ Q_PROPERTY(DownloadState state READ state NOTIFY stateChanged)
+ Q_PROPERTY(int progress READ progress NOTIFY progressChanged)
+ Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
+
+ Q_INVOKABLE void cancel();
+
+ quint32 id();
+ DownloadState state();
+ int progress();
+ QString path();
+ void setPath(QString path);
+
+Q_SIGNALS:
+ void stateChanged();
+ void progressChanged();
+ void pathChanged();
+
+private:
+ QQuickWebEngineDownloadItem(QQuickWebEngineDownloadItemPrivate*, QObject *parent = 0);
+ Q_DISABLE_COPY(QQuickWebEngineDownloadItem)
+ Q_DECLARE_PRIVATE(QQuickWebEngineDownloadItem)
+ friend class QQuickWebEngineProfilePrivate;
+
+ QScopedPointer<QQuickWebEngineDownloadItemPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKWEBENGINEDOWNLOADITEM_P_H
diff --git a/src/webengine/api/qquickwebenginedownloaditem_p_p.h b/src/webengine/api/qquickwebenginedownloaditem_p_p.h
new file mode 100644
index 000000000..6b724b4c9
--- /dev/null
+++ b/src/webengine/api/qquickwebenginedownloaditem_p_p.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKWEBENGINEDOWNLOADITEM_P_P_H
+#define QQUICKWEBENGINEDOWNLOADITEM_P_P_H
+
+#include "qquickwebenginedownloaditem_p.h"
+#include "qquickwebengineprofile_p_p.h"
+#include <private/qtwebengineglobal_p.h>
+#include <QString>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickWebEngineDownloadItemPrivate {
+ QQuickWebEngineDownloadItem *q_ptr;
+ QQuickWebEngineProfilePrivate* profile;
+ friend class QQuickWebEngineProfilePrivate;
+public:
+ Q_DECLARE_PUBLIC(QQuickWebEngineDownloadItem)
+ QQuickWebEngineDownloadItemPrivate(QQuickWebEngineProfilePrivate *p);
+ ~QQuickWebEngineDownloadItemPrivate();
+
+ bool downloadStarted;
+ quint32 downloadId;
+ QQuickWebEngineDownloadItem::DownloadState downloadState;
+ int downloadProgress;
+ QString downloadPath;
+
+ void update(QQuickWebEngineDownloadItem::DownloadState state, int progress);
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKWEBENGINEDOWNLOADITEM_P_P_H
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
new file mode 100644
index 000000000..9eecae073
--- /dev/null
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -0,0 +1,293 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickwebengineprofile_p.h"
+
+#include "qquickwebenginedownloaditem_p.h"
+#include "qquickwebenginedownloaditem_p_p.h"
+#include "qquickwebengineprofile_p_p.h"
+#include <QQmlEngine>
+
+#include "browser_context_adapter.h"
+
+QT_BEGIN_NAMESPACE
+
+static inline QQuickWebEngineDownloadItem::DownloadState toDownloadState(int state) {
+ switch (state) {
+ case BrowserContextAdapterClient::DownloadInProgress:
+ return QQuickWebEngineDownloadItem::DownloadInProgress;
+ case BrowserContextAdapterClient::DownloadCompleted:
+ return QQuickWebEngineDownloadItem::DownloadCompleted;
+ case BrowserContextAdapterClient::DownloadCancelled:
+ return QQuickWebEngineDownloadItem::DownloadCancelled;
+ case BrowserContextAdapterClient::DownloadInterrupted:
+ return QQuickWebEngineDownloadItem::DownloadInterrupted;
+ default:
+ Q_UNREACHABLE();
+ return QQuickWebEngineDownloadItem::DownloadCancelled;
+ }
+}
+
+QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(BrowserContextAdapter* browserContext, bool ownsContext)
+ : m_browserContext(browserContext)
+{
+ if (ownsContext)
+ m_browserContextRef = browserContext;
+
+ m_browserContext->setClient(this);
+}
+
+QQuickWebEngineProfilePrivate::~QQuickWebEngineProfilePrivate()
+{
+ m_browserContext->setClient(0);
+
+ Q_FOREACH (QQuickWebEngineDownloadItem* download, m_ongoingDownloads) {
+ if (download)
+ download->cancel();
+ }
+
+ m_ongoingDownloads.clear();
+}
+
+void QQuickWebEngineProfilePrivate::cancelDownload(quint32 downloadId)
+{
+ m_browserContext->cancelDownload(downloadId);
+}
+
+void QQuickWebEngineProfilePrivate::downloadDestroyed(quint32 downloadId)
+{
+ m_ongoingDownloads.remove(downloadId);
+}
+
+void QQuickWebEngineProfilePrivate::downloadRequested(quint32 downloadId, QString &downloadPath, bool &cancelled)
+{
+ Q_Q(QQuickWebEngineProfile);
+
+ Q_ASSERT(!m_ongoingDownloads.contains(downloadId));
+ QQuickWebEngineDownloadItemPrivate *itemPrivate = new QQuickWebEngineDownloadItemPrivate(this);
+ itemPrivate->downloadId = downloadId;
+ itemPrivate->downloadState = QQuickWebEngineDownloadItem::DownloadInProgress;
+ itemPrivate->downloadPath = downloadPath;
+
+ QQuickWebEngineDownloadItem *download = new QQuickWebEngineDownloadItem(itemPrivate, q);
+
+ m_ongoingDownloads.insert(downloadId, download);
+
+ QQmlEngine::setObjectOwnership(download, QQmlEngine::JavaScriptOwnership);
+ Q_EMIT q->downloadStarted(download);
+ download->d_func()->downloadStarted = true;
+
+ downloadPath = download->path();
+ cancelled = download->state() == QQuickWebEngineDownloadItem::DownloadCancelled;
+}
+
+void QQuickWebEngineProfilePrivate::downloadUpdated(quint32 downloadId, int downloadState, int percentComplete)
+{
+ Q_Q(QQuickWebEngineProfile);
+
+ Q_ASSERT(m_ongoingDownloads.contains(downloadId));
+ QQuickWebEngineDownloadItem* download = m_ongoingDownloads.value(downloadId).data();
+
+ if (!download) {
+ cancelDownload(downloadId);
+ return;
+ }
+
+ download->d_func()->update(toDownloadState(downloadState), percentComplete);
+
+ if (downloadState != BrowserContextAdapterClient::DownloadInProgress) {
+ Q_EMIT q->downloadFinished(download);
+ m_ongoingDownloads.remove(downloadId);
+ }
+}
+
+QQuickWebEngineProfile::QQuickWebEngineProfile()
+ : d_ptr(new QQuickWebEngineProfilePrivate(new BrowserContextAdapter(false), true))
+{
+ d_ptr->q_ptr = this;
+}
+
+QQuickWebEngineProfile::QQuickWebEngineProfile(QQuickWebEngineProfilePrivate *privatePtr)
+ : d_ptr(privatePtr)
+{
+ d_ptr->q_ptr = this;
+}
+
+QQuickWebEngineProfile::~QQuickWebEngineProfile()
+{
+}
+
+QString QQuickWebEngineProfile::storageName() const
+{
+ const Q_D(QQuickWebEngineProfile);
+ return d->browserContext()->storageName();
+}
+
+void QQuickWebEngineProfile::setStorageName(const QString &name)
+{
+ Q_D(QQuickWebEngineProfile);
+ if (d->browserContext()->storageName() == name)
+ return;
+ BrowserContextAdapter::HttpCacheType oldCacheType = d->browserContext()->httpCacheType();
+ BrowserContextAdapter::PersistentCookiesPolicy oldPolicy = d->browserContext()->persistentCookiesPolicy();
+ d->browserContext()->setStorageName(name);
+ emit storageNameChanged();
+ emit persistentStoragePathChanged();
+ emit cachePathChanged();
+ if (d->browserContext()->httpCacheType() != oldCacheType)
+ emit httpCacheTypeChanged();
+ if (d->browserContext()->persistentCookiesPolicy() != oldPolicy)
+ emit persistentCookiesPolicyChanged();
+}
+
+bool QQuickWebEngineProfile::isOffTheRecord() const
+{
+ const Q_D(QQuickWebEngineProfile);
+ return d->browserContext()->isOffTheRecord();
+}
+
+void QQuickWebEngineProfile::setOffTheRecord(bool offTheRecord)
+{
+ Q_D(QQuickWebEngineProfile);
+ if (d->browserContext()->isOffTheRecord() == offTheRecord)
+ return;
+ BrowserContextAdapter::HttpCacheType oldCacheType = d->browserContext()->httpCacheType();
+ BrowserContextAdapter::PersistentCookiesPolicy oldPolicy = d->browserContext()->persistentCookiesPolicy();
+ d->browserContext()->setOffTheRecord(offTheRecord);
+ emit offTheRecordChanged();
+ if (d->browserContext()->httpCacheType() != oldCacheType)
+ emit httpCacheTypeChanged();
+ if (d->browserContext()->persistentCookiesPolicy() != oldPolicy)
+ emit persistentCookiesPolicyChanged();
+}
+
+QString QQuickWebEngineProfile::persistentStoragePath() const
+{
+ const Q_D(QQuickWebEngineProfile);
+ return d->browserContext()->dataPath();
+}
+
+void QQuickWebEngineProfile::setPersistentStoragePath(const QString &path)
+{
+ Q_D(QQuickWebEngineProfile);
+ if (persistentStoragePath() == path)
+ return;
+ d->browserContext()->setDataPath(path);
+ emit persistentStoragePathChanged();
+}
+
+QString QQuickWebEngineProfile::cachePath() const
+{
+ const Q_D(QQuickWebEngineProfile);
+ return d->browserContext()->cachePath();
+}
+
+void QQuickWebEngineProfile::setCachePath(const QString &path)
+{
+ Q_D(QQuickWebEngineProfile);
+ if (cachePath() == path)
+ return;
+ d->browserContext()->setCachePath(path);
+ emit cachePathChanged();
+}
+
+QString QQuickWebEngineProfile::httpUserAgent() const
+{
+ const Q_D(QQuickWebEngineProfile);
+ return d->browserContext()->httpUserAgent();
+}
+
+void QQuickWebEngineProfile::setHttpUserAgent(const QString &userAgent)
+{
+ Q_D(QQuickWebEngineProfile);
+ if (d->browserContext()->httpUserAgent() == userAgent)
+ return;
+ d->browserContext()->setHttpUserAgent(userAgent);
+ emit httpUserAgentChanged();
+}
+
+QQuickWebEngineProfile::HttpCacheType QQuickWebEngineProfile::httpCacheType() const
+{
+ const Q_D(QQuickWebEngineProfile);
+ return QQuickWebEngineProfile::HttpCacheType(d->browserContext()->httpCacheType());
+}
+
+void QQuickWebEngineProfile::setHttpCacheType(QQuickWebEngineProfile::HttpCacheType httpCacheType)
+{
+ Q_D(QQuickWebEngineProfile);
+ BrowserContextAdapter::HttpCacheType oldCacheType = d->browserContext()->httpCacheType();
+ d->browserContext()->setHttpCacheType(BrowserContextAdapter::HttpCacheType(httpCacheType));
+ if (d->browserContext()->httpCacheType() != oldCacheType)
+ emit httpCacheTypeChanged();
+}
+
+QQuickWebEngineProfile::PersistentCookiesPolicy QQuickWebEngineProfile::persistentCookiesPolicy() const
+{
+ const Q_D(QQuickWebEngineProfile);
+ return QQuickWebEngineProfile::PersistentCookiesPolicy(d->browserContext()->persistentCookiesPolicy());
+}
+
+void QQuickWebEngineProfile::setPersistentCookiesPolicy(QQuickWebEngineProfile::PersistentCookiesPolicy newPersistentCookiesPolicy)
+{
+ Q_D(QQuickWebEngineProfile);
+ BrowserContextAdapter::PersistentCookiesPolicy oldPolicy = d->browserContext()->persistentCookiesPolicy();
+ d->browserContext()->setPersistentCookiesPolicy(BrowserContextAdapter::PersistentCookiesPolicy(newPersistentCookiesPolicy));
+ if (d->browserContext()->persistentCookiesPolicy() != oldPolicy)
+ emit persistentCookiesPolicyChanged();
+}
+
+int QQuickWebEngineProfile::httpCacheMaxSize() const
+{
+ const Q_D(QQuickWebEngineProfile);
+ return d->browserContext()->httpCacheMaxSize();
+}
+
+void QQuickWebEngineProfile::setHttpCacheMaxSize(int maxSize)
+{
+ Q_D(QQuickWebEngineProfile);
+ if (d->browserContext()->httpCacheMaxSize() == maxSize)
+ return;
+ d->browserContext()->setHttpCacheMaxSize(maxSize);
+ emit httpCacheMaxSizeChanged();
+}
+
+QQuickWebEngineProfile *QQuickWebEngineProfile::defaultProfile()
+{
+ static QQuickWebEngineProfile profile(new QQuickWebEngineProfilePrivate(BrowserContextAdapter::defaultContext(), false));
+ return &profile;
+}
+
+QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebengineprofile_p.h b/src/webengine/api/qquickwebengineprofile_p.h
new file mode 100644
index 000000000..b8d7c8652
--- /dev/null
+++ b/src/webengine/api/qquickwebengineprofile_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKWEBENGINEPROFILE_P_H
+#define QQUICKWEBENGINEPROFILE_P_H
+
+#include <private/qtwebengineglobal_p.h>
+
+#include <QObject>
+#include <QScopedPointer>
+#include <QString>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickWebEngineDownloadItem;
+class QQuickWebEngineProfilePrivate;
+
+class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineProfile : public QObject {
+ Q_OBJECT
+ Q_ENUMS(HttpCacheType);
+ Q_ENUMS(PersistentCookiesPolicy);
+ Q_PROPERTY(QString storageName READ storageName WRITE setStorageName NOTIFY storageNameChanged FINAL)
+ Q_PROPERTY(bool offTheRecord READ isOffTheRecord WRITE setOffTheRecord NOTIFY offTheRecordChanged FINAL)
+ Q_PROPERTY(QString persistentStoragePath READ persistentStoragePath WRITE setPersistentStoragePath NOTIFY persistentStoragePathChanged FINAL)
+ Q_PROPERTY(QString cachePath READ cachePath WRITE setCachePath NOTIFY cachePathChanged FINAL)
+ Q_PROPERTY(QString httpUserAgent READ httpUserAgent WRITE setHttpUserAgent NOTIFY httpUserAgentChanged FINAL)
+ Q_PROPERTY(HttpCacheType httpCacheType READ httpCacheType WRITE setHttpCacheType NOTIFY httpCacheTypeChanged FINAL)
+ Q_PROPERTY(PersistentCookiesPolicy persistentCookiesPolicy READ persistentCookiesPolicy WRITE setPersistentCookiesPolicy NOTIFY persistentCookiesPolicyChanged FINAL)
+ Q_PROPERTY(int httpCacheMaxSize READ httpCacheMaxSize WRITE setHttpCacheMaxSize NOTIFY httpCacheMaxSizeChanged FINAL)
+public:
+ QQuickWebEngineProfile();
+ ~QQuickWebEngineProfile();
+
+ enum HttpCacheType {
+ MemoryHttpCache,
+ DiskHttpCache
+ };
+
+ enum PersistentCookiesPolicy {
+ NoPersistentCookies,
+ AllowPersistentCookies,
+ ForcePersistentCookies
+ };
+
+ QString storageName() const;
+ void setStorageName(const QString &name);
+
+ bool isOffTheRecord() const;
+ void setOffTheRecord(bool offTheRecord);
+
+ QString persistentStoragePath() const;
+ void setPersistentStoragePath(const QString &path);
+
+ QString cachePath() const;
+ void setCachePath(const QString &path);
+
+ QString httpUserAgent() const;
+ void setHttpUserAgent(const QString &userAgent);
+
+ HttpCacheType httpCacheType() const;
+ void setHttpCacheType(QQuickWebEngineProfile::HttpCacheType);
+
+ PersistentCookiesPolicy persistentCookiesPolicy() const;
+ void setPersistentCookiesPolicy(QQuickWebEngineProfile::PersistentCookiesPolicy);
+
+ int httpCacheMaxSize() const;
+ void setHttpCacheMaxSize(int maxSize);
+
+ static QQuickWebEngineProfile *defaultProfile();
+
+signals:
+ void storageNameChanged();
+ void offTheRecordChanged();
+ void persistentStoragePathChanged();
+ void cachePathChanged();
+ void httpUserAgentChanged();
+ void httpCacheTypeChanged();
+ void persistentCookiesPolicyChanged();
+ void httpCacheMaxSizeChanged();
+
+ void downloadStarted(QQuickWebEngineDownloadItem *download);
+ void downloadFinished(QQuickWebEngineDownloadItem *download);
+
+private:
+ Q_DECLARE_PRIVATE(QQuickWebEngineProfile);
+ QQuickWebEngineProfile(QQuickWebEngineProfilePrivate *);
+
+ friend class QQuickWebEngineViewPrivate;
+ QScopedPointer<QQuickWebEngineProfilePrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKWEBENGINEPROFILE_P_H
diff --git a/src/webengine/api/qquickwebengineprofile_p_p.h b/src/webengine/api/qquickwebengineprofile_p_p.h
new file mode 100644
index 000000000..18ccfc467
--- /dev/null
+++ b/src/webengine/api/qquickwebengineprofile_p_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKWEBENGINEPROFILE_P_P_H
+#define QQUICKWEBENGINEPROFILE_P_P_H
+
+class BrowserContextAdapter;
+
+#include "browser_context_adapter_client.h"
+#include "qquickwebengineprofile_p.h"
+
+#include <QExplicitlySharedDataPointer>
+#include <QMap>
+#include <QPointer>
+
+QT_BEGIN_NAMESPACE
+class QQuickWebEngineDownloadItem;
+class QQuickWebEngineProfilePrivate
+ : public BrowserContextAdapterClient
+{
+public:
+ Q_DECLARE_PUBLIC(QQuickWebEngineProfile)
+ QQuickWebEngineProfilePrivate(BrowserContextAdapter* browserContext, bool ownsContext);
+ ~QQuickWebEngineProfilePrivate();
+
+ BrowserContextAdapter *browserContext() const { return m_browserContext; }
+
+ void cancelDownload(quint32 downloadId);
+ void downloadDestroyed(quint32 downloadId);
+
+ void downloadRequested(quint32 downloadId, QString &downloadPath, bool &cancelled) Q_DECL_OVERRIDE;
+ void downloadUpdated(quint32 downloadId, int downloadState, int percentComplete) Q_DECL_OVERRIDE;
+
+private:
+ friend class QQuickWebEngineViewPrivate;
+ QQuickWebEngineProfile *q_ptr;
+ BrowserContextAdapter *m_browserContext;
+ QExplicitlySharedDataPointer<BrowserContextAdapter> m_browserContextRef;
+ QMap<quint32, QPointer<QQuickWebEngineDownloadItem> > m_ongoingDownloads;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKWEBENGINEPROFILE_P_P_H
diff --git a/src/webengine/api/qquickwebenginesettings.cpp b/src/webengine/api/qquickwebenginesettings.cpp
index 743d22d81..e46b1a80d 100644
--- a/src/webengine/api/qquickwebenginesettings.cpp
+++ b/src/webengine/api/qquickwebenginesettings.cpp
@@ -43,6 +43,20 @@ QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QList<QQuickWebEngineSettingsPrivate*>, allSettings)
+class QQuickWebEngineGlobalSettings {
+ QQuickWebEngineSettings globalSettings;
+public:
+ QQuickWebEngineGlobalSettings() {
+ // globalSettings shouldn't be in that list.
+ allSettings->removeAll(globalSettings.d_func());
+ globalSettings.d_func()->coreSettings->initDefaults();
+ }
+
+ QQuickWebEngineSettings *data() { return &globalSettings; }
+};
+
+Q_GLOBAL_STATIC(QQuickWebEngineGlobalSettings, globalInstance)
+
QQuickWebEngineSettingsPrivate::QQuickWebEngineSettingsPrivate()
: coreSettings(new WebEngineSettings(this))
{
@@ -64,16 +78,9 @@ WebEngineSettings *QQuickWebEngineSettingsPrivate::fallbackSettings() const
return QQuickWebEngineSettings::globalSettings()->d_func()->coreSettings.data();
}
-
QQuickWebEngineSettings *QQuickWebEngineSettings::globalSettings()
{
- static QQuickWebEngineSettings *globals = 0;
- if (!globals) {
- globals = new QQuickWebEngineSettings;
- allSettings->removeAll(globals->d_func());
- globals->d_func()->coreSettings->initDefaults();
- }
- return globals;
+ return globalInstance()->data();
}
QQuickWebEngineSettings::~QQuickWebEngineSettings()
@@ -161,7 +168,7 @@ void QQuickWebEngineSettings::setAutoLoadImages(bool on)
// could be from the fallback and is prone to changing later on.
d->coreSettings->setAttribute(WebEngineSettings::AutoLoadImages, on);
if (wasOn ^ on)
- Q_EMIT autoLoadImagesChanged(on);
+ Q_EMIT autoLoadImagesChanged();
}
void QQuickWebEngineSettings::setJavascriptEnabled(bool on)
@@ -170,7 +177,7 @@ void QQuickWebEngineSettings::setJavascriptEnabled(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::JavascriptEnabled);
d->coreSettings->setAttribute(WebEngineSettings::JavascriptEnabled, on);
if (wasOn ^ on)
- Q_EMIT javascriptEnabledChanged(on);
+ Q_EMIT javascriptEnabledChanged();
}
void QQuickWebEngineSettings::setJavascriptCanOpenWindows(bool on)
@@ -179,7 +186,7 @@ void QQuickWebEngineSettings::setJavascriptCanOpenWindows(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::JavascriptCanOpenWindows);
d->coreSettings->setAttribute(WebEngineSettings::JavascriptCanOpenWindows, on);
if (wasOn ^ on)
- Q_EMIT javascriptCanOpenWindowsChanged(on);
+ Q_EMIT javascriptCanOpenWindowsChanged();
}
void QQuickWebEngineSettings::setJavascriptCanAccessClipboard(bool on)
@@ -188,7 +195,7 @@ void QQuickWebEngineSettings::setJavascriptCanAccessClipboard(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::JavascriptCanAccessClipboard);
d->coreSettings->setAttribute(WebEngineSettings::JavascriptCanAccessClipboard, on);
if (wasOn ^ on)
- Q_EMIT javascriptCanAccessClipboardChanged(on);
+ Q_EMIT javascriptCanAccessClipboardChanged();
}
void QQuickWebEngineSettings::setLinksIncludedInFocusChain(bool on)
@@ -197,7 +204,7 @@ void QQuickWebEngineSettings::setLinksIncludedInFocusChain(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::LinksIncludedInFocusChain);
d->coreSettings->setAttribute(WebEngineSettings::LinksIncludedInFocusChain, on);
if (wasOn ^ on)
- Q_EMIT linksIncludedInFocusChainChanged(on);
+ Q_EMIT linksIncludedInFocusChainChanged();
}
void QQuickWebEngineSettings::setLocalStorageEnabled(bool on)
@@ -206,7 +213,7 @@ void QQuickWebEngineSettings::setLocalStorageEnabled(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::LocalStorageEnabled);
d->coreSettings->setAttribute(WebEngineSettings::LocalStorageEnabled, on);
if (wasOn ^ on)
- Q_EMIT localStorageEnabledChanged(on);
+ Q_EMIT localStorageEnabledChanged();
}
void QQuickWebEngineSettings::setLocalContentCanAccessRemoteUrls(bool on)
@@ -215,7 +222,7 @@ void QQuickWebEngineSettings::setLocalContentCanAccessRemoteUrls(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::LocalContentCanAccessRemoteUrls);
d->coreSettings->setAttribute(WebEngineSettings::LocalContentCanAccessRemoteUrls, on);
if (wasOn ^ on)
- Q_EMIT localContentCanAccessRemoteUrlsChanged(on);
+ Q_EMIT localContentCanAccessRemoteUrlsChanged();
}
@@ -225,7 +232,7 @@ void QQuickWebEngineSettings::setSpatialNavigationEnabled(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::SpatialNavigationEnabled);
d->coreSettings->setAttribute(WebEngineSettings::SpatialNavigationEnabled, on);
if (wasOn ^ on)
- Q_EMIT spatialNavigationEnabledChanged(on);
+ Q_EMIT spatialNavigationEnabledChanged();
}
void QQuickWebEngineSettings::setLocalContentCanAccessFileUrls(bool on)
@@ -234,7 +241,7 @@ void QQuickWebEngineSettings::setLocalContentCanAccessFileUrls(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::LocalContentCanAccessFileUrls);
d->coreSettings->setAttribute(WebEngineSettings::LocalContentCanAccessFileUrls, on);
if (wasOn ^ on)
- Q_EMIT localContentCanAccessFileUrlsChanged(on);
+ Q_EMIT localContentCanAccessFileUrlsChanged();
}
void QQuickWebEngineSettings::setHyperlinkAuditingEnabled(bool on)
@@ -243,7 +250,7 @@ void QQuickWebEngineSettings::setHyperlinkAuditingEnabled(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::HyperlinkAuditingEnabled);
d->coreSettings->setAttribute(WebEngineSettings::HyperlinkAuditingEnabled, on);
if (wasOn ^ on)
- Q_EMIT hyperlinkAuditingEnabledChanged(on);
+ Q_EMIT hyperlinkAuditingEnabledChanged();
}
void QQuickWebEngineSettings::setErrorPageEnabled(bool on)
@@ -252,7 +259,7 @@ void QQuickWebEngineSettings::setErrorPageEnabled(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::ErrorPageEnabled);
d->coreSettings->setAttribute(WebEngineSettings::ErrorPageEnabled, on);
if (wasOn ^ on)
- Q_EMIT errorPageEnabledChanged(on);
+ Q_EMIT errorPageEnabledChanged();
}
void QQuickWebEngineSettings::setDefaultTextEncoding(QString encoding)
@@ -261,7 +268,7 @@ void QQuickWebEngineSettings::setDefaultTextEncoding(QString encoding)
const QString oldDefaultTextEncoding = d->coreSettings->defaultTextEncoding();
d->coreSettings->setDefaultTextEncoding(encoding);
if (oldDefaultTextEncoding.compare(encoding))
- Q_EMIT defaultTextEncodingChanged(encoding);
+ Q_EMIT defaultTextEncodingChanged();
}
QQuickWebEngineSettings::QQuickWebEngineSettings()
diff --git a/src/webengine/api/qquickwebenginesettings_p.h b/src/webengine/api/qquickwebenginesettings_p.h
index 4a7c2f834..040a5f5fb 100644
--- a/src/webengine/api/qquickwebenginesettings_p.h
+++ b/src/webengine/api/qquickwebenginesettings_p.h
@@ -44,6 +44,7 @@
QT_BEGIN_NAMESPACE
class QQuickWebEngineSettingsPrivate;
+class QQuickWebEngineGlobalSettings;
class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineSettings : public QObject {
Q_OBJECT
@@ -92,24 +93,25 @@ public:
void setDefaultTextEncoding(QString encoding);
signals:
- void autoLoadImagesChanged(bool on);
- void javascriptEnabledChanged(bool on);
- void javascriptCanOpenWindowsChanged(bool on);
- void javascriptCanAccessClipboardChanged(bool on);
- void linksIncludedInFocusChainChanged(bool on);
- void localStorageEnabledChanged(bool on);
- void localContentCanAccessRemoteUrlsChanged(bool on);
- void spatialNavigationEnabledChanged(bool on);
- void localContentCanAccessFileUrlsChanged(bool on);
- void hyperlinkAuditingEnabledChanged(bool on);
- void errorPageEnabledChanged(bool on);
- void defaultTextEncodingChanged(QString encoding);
+ void autoLoadImagesChanged();
+ void javascriptEnabledChanged();
+ void javascriptCanOpenWindowsChanged();
+ void javascriptCanAccessClipboardChanged();
+ void linksIncludedInFocusChainChanged();
+ void localStorageEnabledChanged();
+ void localContentCanAccessRemoteUrlsChanged();
+ void spatialNavigationEnabledChanged();
+ void localContentCanAccessFileUrlsChanged();
+ void hyperlinkAuditingEnabledChanged();
+ void errorPageEnabledChanged();
+ void defaultTextEncodingChanged();
private:
QQuickWebEngineSettings();
Q_DISABLE_COPY(QQuickWebEngineSettings)
Q_DECLARE_PRIVATE(QQuickWebEngineSettings)
friend class QQuickWebEngineViewPrivate;
+ friend class QQuickWebEngineGlobalSettings;
QScopedPointer<QQuickWebEngineSettingsPrivate> d_ptr;
};
diff --git a/src/webengine/api/qquickwebenginesettings_p_p.h b/src/webengine/api/qquickwebenginesettings_p_p.h
index 8f3e95eea..05a163b92 100644
--- a/src/webengine/api/qquickwebenginesettings_p_p.h
+++ b/src/webengine/api/qquickwebenginesettings_p_p.h
@@ -44,7 +44,6 @@ QT_BEGIN_NAMESPACE
class QQuickWebEngineSettingsPrivate : public WebEngineSettingsDelegate {
public:
QQuickWebEngineSettingsPrivate();
- QQuickWebEngineSettingsPrivate(WebContentsAdapter *adapter);
void apply() Q_DECL_OVERRIDE;
WebEngineSettings *fallbackSettings() const Q_DECL_OVERRIDE;
diff --git a/src/webengine/api/qquickwebenginesingleton.cpp b/src/webengine/api/qquickwebenginesingleton.cpp
index bf4951f3b..280f5b913 100644
--- a/src/webengine/api/qquickwebenginesingleton.cpp
+++ b/src/webengine/api/qquickwebenginesingleton.cpp
@@ -37,6 +37,7 @@
#include "qquickwebenginesingleton_p.h"
#include "qquickwebenginesettings_p.h"
+#include "qquickwebengineprofile_p.h"
QT_BEGIN_NAMESPACE
@@ -45,4 +46,9 @@ QQuickWebEngineSettings *QQuickWebEngineSingleton::settings() const
return QQuickWebEngineSettings::globalSettings();
}
+QQuickWebEngineProfile *QQuickWebEngineSingleton::defaultProfile() const
+{
+ return QQuickWebEngineProfile::defaultProfile();
+}
+
QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebenginesingleton_p.h b/src/webengine/api/qquickwebenginesingleton_p.h
index 23205e2df..f983d0ffb 100644
--- a/src/webengine/api/qquickwebenginesingleton_p.h
+++ b/src/webengine/api/qquickwebenginesingleton_p.h
@@ -41,14 +41,16 @@
#include <qtwebengineglobal_p.h>
QT_BEGIN_NAMESPACE
+class QQuickWebEngineProfile;
class QQuickWebEngineSettings;
-
class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineSingleton : public QObject {
Q_OBJECT
Q_PROPERTY(QQuickWebEngineSettings* settings READ settings CONSTANT FINAL)
+ Q_PROPERTY(QQuickWebEngineProfile* defaultProfile READ defaultProfile CONSTANT FINAL REVISION 1)
public:
QQuickWebEngineSettings *settings() const;
+ QQuickWebEngineProfile *defaultProfile() const;
};
QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 3497c16ad..1b95f86b4 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -37,12 +37,15 @@
#include "qquickwebengineview_p.h"
#include "qquickwebengineview_p_p.h"
+#include "browser_context_adapter.h"
#include "certificate_error_controller.h"
#include "javascript_dialog_controller.h"
#include "qquickwebenginehistory_p.h"
#include "qquickwebengineloadrequest_p.h"
#include "qquickwebenginenavigationrequest_p.h"
#include "qquickwebenginenewviewrequest_p.h"
+#include "qquickwebengineprofile_p.h"
+#include "qquickwebengineprofile_p_p.h"
#include "qquickwebenginesettings_p.h"
#include "qquickwebenginesettings_p_p.h"
#include "render_widget_host_view_qt_delegate_quick.h"
@@ -73,10 +76,11 @@ static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *obje
}
QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
- : adapter(new WebContentsAdapter)
+ : adapter(0)
, e(new QQuickWebEngineViewExperimental(this))
, v(new QQuickWebEngineViewport(this))
, m_history(new QQuickWebEngineHistory(this))
+ , m_profile(QQuickWebEngineProfile::defaultProfile())
, m_settings(new QQuickWebEngineSettings)
, contextMenuExtraItems(0)
, loadProgress(0)
@@ -217,6 +221,11 @@ void QQuickWebEngineViewPrivate::allowCertificateError(const QExplicitlySharedDa
Q_UNUSED(errorController);
}
+void QQuickWebEngineViewPrivate::runGeolocationPermissionRequest(const QUrl &url)
+{
+ Q_EMIT e->featurePermissionRequested(url, QQuickWebEngineViewExperimental::Geolocation);
+}
+
void QQuickWebEngineViewPrivate::runFileChooser(FileChooserMode mode, const QString &defaultFileName, const QStringList &acceptedMimeTypes)
{
ui()->showFilePicker(mode, defaultFileName, acceptedMimeTypes, adapter);
@@ -343,9 +352,11 @@ void QQuickWebEngineViewPrivate::adoptNewWindow(WebContentsAdapter *newWebConten
switch (disposition) {
case WebContentsAdapterClient::NewForegroundTabDisposition:
- case WebContentsAdapterClient::NewBackgroundTabDisposition:
request.m_destination = QQuickWebEngineView::NewViewInTab;
break;
+ case WebContentsAdapterClient::NewBackgroundTabDisposition:
+ request.m_destination = QQuickWebEngineView::NewViewInBackgroundTab;
+ break;
case WebContentsAdapterClient::NewPopupDisposition:
request.m_destination = QQuickWebEngineView::NewViewInDialog;
break;
@@ -356,7 +367,7 @@ void QQuickWebEngineViewPrivate::adoptNewWindow(WebContentsAdapter *newWebConten
Q_UNREACHABLE();
}
- emit e->newViewRequested(&request);
+ Q_EMIT e->newViewRequested(&request);
}
void QQuickWebEngineViewPrivate::close()
@@ -387,20 +398,34 @@ void QQuickWebEngineViewPrivate::runMediaAccessPermissionRequest(const QUrl &sec
return;
QQuickWebEngineViewExperimental::Feature feature;
if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture) && requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
- feature = QQuickWebEngineViewExperimental::MediaAudioVideoDevices;
+ feature = QQuickWebEngineViewExperimental::MediaAudioVideoCapture;
else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture))
- feature = QQuickWebEngineViewExperimental::MediaAudioDevices;
+ feature = QQuickWebEngineViewExperimental::MediaAudioCapture;
else // WebContentsAdapterClient::MediaVideoCapture
- feature = QQuickWebEngineViewExperimental::MediaVideoDevices;
+ feature = QQuickWebEngineViewExperimental::MediaVideoCapture;
Q_EMIT e->featurePermissionRequested(securityOrigin, feature);
}
+void QQuickWebEngineViewPrivate::runMouseLockPermissionRequest(const QUrl &securityOrigin)
+{
+
+ Q_UNUSED(securityOrigin);
+
+ // TODO: Add mouse lock support
+ adapter->grantMouseLockPermission(false);
+}
+
QObject *QQuickWebEngineViewPrivate::accessibilityParentObject()
{
Q_Q(QQuickWebEngineView);
return q;
}
+BrowserContextAdapter *QQuickWebEngineViewPrivate::browserContextAdapter()
+{
+ return m_profile->d_ptr->browserContext();
+}
+
WebEngineSettings *QQuickWebEngineViewPrivate::webEngineSettings() const
{
return m_settings->d_func()->coreSettings.data();
@@ -493,7 +518,6 @@ QQuickWebEngineView::QQuickWebEngineView(QQuickItem *parent)
{
Q_D(QQuickWebEngineView);
d->e->q_ptr = d->q_ptr = this;
- d->adapter->initialize(d);
this->setActiveFocusOnTab(true);
this->setFlag(QQuickItem::ItemIsFocusScope);
@@ -505,10 +529,21 @@ QQuickWebEngineView::~QQuickWebEngineView()
{
}
+void QQuickWebEngineViewPrivate::ensureContentsAdapter()
+{
+ if (!adapter) {
+ adapter = new WebContentsAdapter();
+ adapter->initialize(this);
+ adapter->enableInspector(inspectable);
+ if (explicitUrl.isValid())
+ adapter->load(explicitUrl);
+ }
+}
+
QUrl QQuickWebEngineView::url() const
{
Q_D(const QQuickWebEngineView);
- return d->explicitUrl.isValid() ? d->explicitUrl : d->adapter->activeUrl();
+ return d->explicitUrl.isValid() ? d->explicitUrl : (d->adapter ? d->adapter->activeUrl() : QUrl());
}
void QQuickWebEngineView::setUrl(const QUrl& url)
@@ -518,7 +553,10 @@ void QQuickWebEngineView::setUrl(const QUrl& url)
Q_D(QQuickWebEngineView);
d->explicitUrl = url;
- d->adapter->load(url);
+ if (d->adapter)
+ d->adapter->load(url);
+ if (!qmlEngine(this))
+ d->ensureContentsAdapter();
}
QUrl QQuickWebEngineView::icon() const
@@ -530,33 +568,83 @@ QUrl QQuickWebEngineView::icon() const
void QQuickWebEngineView::loadHtml(const QString &html, const QUrl &baseUrl)
{
Q_D(QQuickWebEngineView);
- d->adapter->setContent(html.toUtf8(), QStringLiteral("text/html;charset=UTF-8"), baseUrl);
+ d->explicitUrl = QUrl();
+ if (!qmlEngine(this))
+ d->ensureContentsAdapter();
+ if (d->adapter)
+ d->adapter->setContent(html.toUtf8(), QStringLiteral("text/html;charset=UTF-8"), baseUrl);
}
void QQuickWebEngineView::goBack()
{
Q_D(QQuickWebEngineView);
+ if (!d->adapter)
+ return;
d->adapter->navigateToOffset(-1);
}
void QQuickWebEngineView::goForward()
{
Q_D(QQuickWebEngineView);
+ if (!d->adapter)
+ return;
d->adapter->navigateToOffset(1);
}
void QQuickWebEngineView::reload()
{
Q_D(QQuickWebEngineView);
+ if (!d->adapter)
+ return;
d->adapter->reload();
}
void QQuickWebEngineView::stop()
{
Q_D(QQuickWebEngineView);
+ if (!d->adapter)
+ return;
d->adapter->stop();
}
+void QQuickWebEngineView::setZoomFactor(qreal arg)
+{
+ Q_D(QQuickWebEngineView);
+ if (!d->adapter)
+ return;
+ qreal oldFactor = d->adapter->currentZoomFactor();
+ d->adapter->setZoomFactor(arg);
+ if (qFuzzyCompare(oldFactor, d->adapter->currentZoomFactor()))
+ return;
+
+ emit zoomFactorChanged(arg);
+}
+
+QQuickWebEngineProfile *QQuickWebEngineView::profile() const
+{
+ Q_D(const QQuickWebEngineView);
+ return d->m_profile;
+}
+
+void QQuickWebEngineView::setProfile(QQuickWebEngineProfile *profile)
+{
+ Q_D(QQuickWebEngineView);
+ d->setProfile(profile);
+}
+
+void QQuickWebEngineViewPrivate::setProfile(QQuickWebEngineProfile *profile)
+{
+ m_profile = profile;
+ if (adapter && adapter->browserContext() != browserContextAdapter()->browserContext()) {
+ // When the profile changes we need to create a new WebContentAdapter and reload the active URL.
+ QUrl activeUrl = adapter->activeUrl();
+ adapter = 0;
+ ensureContentsAdapter();
+ if (!explicitUrl.isValid() && activeUrl.isValid())
+ adapter->load(activeUrl);
+ }
+}
+
void QQuickWebEngineViewPrivate::didRunJavaScript(quint64 requestId, const QVariant &result)
{
Q_Q(QQuickWebEngineView);
@@ -589,24 +677,32 @@ int QQuickWebEngineView::loadProgress() const
QString QQuickWebEngineView::title() const
{
Q_D(const QQuickWebEngineView);
+ if (!d->adapter)
+ return QString();
return d->adapter->pageTitle();
}
bool QQuickWebEngineView::canGoBack() const
{
Q_D(const QQuickWebEngineView);
+ if (!d->adapter)
+ return false;
return d->adapter->canGoBack();
}
bool QQuickWebEngineView::canGoForward() const
{
Q_D(const QQuickWebEngineView);
+ if (!d->adapter)
+ return false;
return d->adapter->canGoForward();
}
void QQuickWebEngineView::runJavaScript(const QString &script, const QJSValue &callback)
{
Q_D(QQuickWebEngineView);
+ if (!d->adapter)
+ return;
if (!callback.isUndefined()) {
quint64 requestId = d_ptr->adapter->runJavaScriptCallbackResult(script);
d->m_callbacks.insert(requestId, callback);
@@ -620,6 +716,14 @@ QQuickWebEngineViewExperimental *QQuickWebEngineView::experimental() const
return d->e.data();
}
+qreal QQuickWebEngineView::zoomFactor() const
+{
+ Q_D(const QQuickWebEngineView);
+ if (!d->adapter)
+ return 1.0;
+ return d->adapter->currentZoomFactor();
+}
+
bool QQuickWebEngineViewExperimental::inspectable() const
{
Q_D(const QQuickWebEngineView);
@@ -630,6 +734,8 @@ void QQuickWebEngineViewExperimental::setInspectable(bool enable)
{
Q_D(QQuickWebEngineView);
d->inspectable = enable;
+ if (!d->adapter)
+ return;
d->adapter->enableInspector(enable);
}
@@ -664,17 +770,20 @@ QQuickWebEngineSettings *QQuickWebEngineViewExperimental::settings() const
void QQuickWebEngineViewExperimental::findText(const QString &subString, FindFlags options, const QJSValue &callback)
{
+ Q_D(QQuickWebEngineView);
+ if (!d->adapter)
+ return;
if (subString.isEmpty()) {
- d_ptr->adapter->stopFinding();
+ d->adapter->stopFinding();
if (!callback.isUndefined()) {
QJSValueList args;
args.append(QJSValue(0));
const_cast<QJSValue&>(callback).call(args);
}
} else {
- quint64 requestId = d_ptr->adapter->findText(subString, options & FindCaseSensitively, options & FindBackward);
+ quint64 requestId = d->adapter->findText(subString, options & FindCaseSensitively, options & FindBackward);
if (!callback.isUndefined())
- d_ptr->m_callbacks.insert(requestId, callback);
+ d->m_callbacks.insert(requestId, callback);
}
}
@@ -685,27 +794,35 @@ QQuickWebEngineHistory *QQuickWebEngineViewExperimental::navigationHistory() con
void QQuickWebEngineViewExperimental::grantFeaturePermission(const QUrl &securityOrigin, QQuickWebEngineViewExperimental::Feature feature, bool granted)
{
- if (!granted && feature >= MediaAudioDevices && feature <= MediaAudioVideoDevices) {
+ if (!d_ptr->adapter)
+ return;
+ if (!granted && feature >= MediaAudioCapture && feature <= MediaAudioVideoCapture) {
d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaNone);
return;
}
switch (feature) {
- case MediaAudioDevices:
+ case MediaAudioCapture:
d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaAudioCapture);
break;
- case MediaVideoDevices:
+ case MediaVideoCapture:
d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaVideoCapture);
break;
- case MediaAudioVideoDevices:
- d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaRequestFlags(WebContentsAdapterClient::MediaAudioCapture
- | WebContentsAdapterClient::MediaVideoCapture));
+ case MediaAudioVideoCapture:
+ d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaRequestFlags(WebContentsAdapterClient::MediaAudioCapture | WebContentsAdapterClient::MediaVideoCapture));
+ break;
+ case Geolocation:
+ d_ptr->adapter->runGeolocationRequestCallback(securityOrigin, granted);
break;
+ default:
+ Q_UNREACHABLE();
}
}
void QQuickWebEngineViewExperimental::goBackTo(int index)
{
+ if (!d_ptr->adapter)
+ return;
int count = d_ptr->adapter->currentNavigationEntryIndex();
if (index < 0 || index >= count)
return;
@@ -715,6 +832,8 @@ void QQuickWebEngineViewExperimental::goBackTo(int index)
void QQuickWebEngineViewExperimental::goForwardTo(int index)
{
+ if (!d_ptr->adapter)
+ return;
int count = d_ptr->adapter->navigationEntryCount() - d_ptr->adapter->currentNavigationEntryIndex() - 1;
if (index < 0 || index >= count)
return;
@@ -734,7 +853,7 @@ void QQuickWebEngineView::geometryChanged(const QRectF &newGeometry, const QRect
void QQuickWebEngineView::itemChange(ItemChange change, const ItemChangeData &value)
{
Q_D(QQuickWebEngineView);
- if (change == ItemSceneChange || change == ItemVisibleHasChanged) {
+ if (d->adapter && (change == ItemSceneChange || change == ItemVisibleHasChanged)) {
if (window() && isVisible())
d->adapter->wasShown();
else
@@ -743,6 +862,13 @@ void QQuickWebEngineView::itemChange(ItemChange change, const ItemChangeData &va
QQuickItem::itemChange(change, value);
}
+void QQuickWebEngineView::componentComplete()
+{
+ Q_D(QQuickWebEngineView);
+ QQuickItem::componentComplete();
+ d->ensureContentsAdapter();
+}
+
QQuickWebEngineViewExperimental::QQuickWebEngineViewExperimental(QQuickWebEngineViewPrivate *viewPrivate)
: q_ptr(0)
, d_ptr(viewPrivate)
@@ -774,6 +900,8 @@ void QQuickWebEngineViewport::setDevicePixelRatio(qreal devicePixelRatio)
if (d->devicePixelRatio == devicePixelRatio)
return;
d->setDevicePixelRatio(devicePixelRatio);
+ if (!d->adapter)
+ return;
d->adapter->dpiScaleChanged();
Q_EMIT devicePixelRatioChanged();
}
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index 22713ee22..f3ef133ae 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -42,10 +42,11 @@
QT_BEGIN_NAMESPACE
-class QQuickWebEngineViewExperimental;
-class QQuickWebEngineViewPrivate;
class QQuickWebEngineLoadRequest;
class QQuickWebEngineNavigationRequest;
+class QQuickWebEngineProfile;
+class QQuickWebEngineViewExperimental;
+class QQuickWebEngineViewPrivate;
class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem {
Q_OBJECT
@@ -56,6 +57,8 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem {
Q_PROPERTY(QString title READ title NOTIFY titleChanged)
Q_PROPERTY(bool canGoBack READ canGoBack NOTIFY urlChanged)
Q_PROPERTY(bool canGoForward READ canGoForward NOTIFY urlChanged)
+ Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor NOTIFY zoomFactorChanged)
+ Q_PROPERTY(QQuickWebEngineProfile *profile READ profile WRITE setProfile FINAL)
Q_ENUMS(NavigationRequestAction);
Q_ENUMS(NavigationType);
Q_ENUMS(LoadStatus);
@@ -75,6 +78,7 @@ public:
QString title() const;
bool canGoBack() const;
bool canGoForward() const;
+ qreal zoomFactor() const;
QQuickWebEngineViewExperimental *experimental() const;
@@ -116,7 +120,8 @@ public:
enum NewViewDestination {
NewViewInWindow,
NewViewInTab,
- NewViewInDialog
+ NewViewInDialog,
+ NewViewInBackgroundTab
};
// must match WebContentsAdapterClient::JavaScriptConsoleMessageLevel
@@ -126,6 +131,12 @@ public:
ErrorMessageLevel
};
+ // QmlParserStatus
+ virtual void componentComplete() Q_DECL_OVERRIDE;
+
+ QQuickWebEngineProfile *profile() const;
+ void setProfile(QQuickWebEngineProfile *);
+
public Q_SLOTS:
void runJavaScript(const QString&, const QJSValue & = QJSValue());
void loadHtml(const QString &html, const QUrl &baseUrl = QUrl());
@@ -133,6 +144,7 @@ public Q_SLOTS:
void goForward();
void reload();
void stop();
+ void setZoomFactor(qreal arg);
Q_SIGNALS:
void titleChanged();
@@ -143,6 +155,7 @@ Q_SIGNALS:
void linkHovered(const QUrl &hoveredUrl);
void navigationRequested(QQuickWebEngineNavigationRequest *request);
void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID);
+ void zoomFactorChanged(qreal arg);
protected:
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index 6662f1f02..f773b3d28 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -88,9 +88,10 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineViewExperimental : public QObjec
public:
enum Feature {
- MediaAudioDevices,
- MediaVideoDevices,
- MediaAudioVideoDevices
+ MediaAudioCapture,
+ MediaVideoCapture,
+ MediaAudioVideoCapture,
+ Geolocation
};
enum FindFlag {
@@ -175,17 +176,24 @@ public:
virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE;
virtual void authenticationRequired(const QUrl&, const QString&, bool, const QString&, QString*, QString*) Q_DECL_OVERRIDE { }
virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) Q_DECL_OVERRIDE;
+ virtual void runMouseLockPermissionRequest(const QUrl &securityOrigin) Q_DECL_OVERRIDE;
virtual QObject *accessibilityParentObject() Q_DECL_OVERRIDE;
virtual WebEngineSettings *webEngineSettings() const Q_DECL_OVERRIDE;
virtual void allowCertificateError(const QExplicitlySharedDataPointer<CertificateErrorController> &errorController);
+ virtual void runGeolocationPermissionRequest(QUrl const&) Q_DECL_OVERRIDE;
+
+ virtual BrowserContextAdapter *browserContextAdapter() Q_DECL_OVERRIDE;
void setDevicePixelRatio(qreal);
void adoptWebContents(WebContentsAdapter *webContents);
+ void setProfile(QQuickWebEngineProfile *profile);
+ void ensureContentsAdapter();
QExplicitlySharedDataPointer<WebContentsAdapter> adapter;
QScopedPointer<QQuickWebEngineViewExperimental> e;
QScopedPointer<QQuickWebEngineViewport> v;
QScopedPointer<QQuickWebEngineHistory> m_history;
+ QQuickWebEngineProfile *m_profile;
QScopedPointer<QQuickWebEngineSettings> m_settings;
QQmlComponent *contextMenuExtraItems;
QUrl explicitUrl;
diff --git a/src/webengine/plugin/experimental/plugin.cpp b/src/webengine/plugin/experimental/plugin.cpp
index 883ebc598..93f0cb7f0 100644
--- a/src/webengine/plugin/experimental/plugin.cpp
+++ b/src/webengine/plugin/experimental/plugin.cpp
@@ -36,6 +36,7 @@
#include <QtQml/qqmlextensionplugin.h>
+#include "qquickwebenginedownloaditem_p.h"
#include "qquickwebenginehistory_p.h"
#include "qquickwebenginesettings_p.h"
#include "qquickwebenginesingleton_p.h"
@@ -80,6 +81,8 @@ public:
QObject::tr("Cannot create a separate instance of NavigationHistory"));
qmlRegisterUncreatableType<QQuickWebEngineSettings>(uri, 1, 0, "WebEngineSettings",
QObject::tr("Cannot create a separate instance of WebEngineSettings"));
+ qmlRegisterUncreatableType<QQuickWebEngineDownloadItem>(uri, 1, 0, "WebEngineDownloadItem",
+ QObject::tr("Cannot create a separate instance of WebEngineDownloadItem"));
qmlRegisterSingletonType<QQuickWebEngineSingleton>(uri, 1, 0, "WebEngine", webEngineSingletonProvider);
}
};
diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp
index 60e401301..5d7bf2d36 100644
--- a/src/webengine/plugin/plugin.cpp
+++ b/src/webengine/plugin/plugin.cpp
@@ -39,6 +39,7 @@
#include "qquickwebengineloadrequest_p.h"
#include "qquickwebenginenavigationrequest_p.h"
#include "qquickwebenginenewviewrequest_p.h"
+#include "qquickwebengineprofile_p.h"
#include "qquickwebengineview_p.h"
#include "qtwebengineversion.h"
@@ -58,6 +59,7 @@ public:
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtWebEngine"));
qmlRegisterType<QQuickWebEngineView>(uri, 1, 0, "WebEngineView");
+ qmlRegisterType<QQuickWebEngineProfile>(uri, 1, 1, "WebEngineProfile");
qmlRegisterUncreatableType<QQuickWebEngineLoadRequest>(uri, 1, 0, "WebEngineLoadRequest", QObject::tr("Cannot create separate instance of WebEngineLoadRequest"));
qmlRegisterUncreatableType<QQuickWebEngineNewViewRequest>(uri, 1, 0, "WebEngineNewViewRequest", QObject::tr("Cannot create separate instance of WebEngineNewViewRequest"));
qmlRegisterUncreatableType<QQuickWebEngineNavigationRequest>(uri, 1, 0, "WebEngineNavigationRequest", QObject::tr("Cannot create separate instance of WebEngineNavigationRequest"));
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
index 7c04cb8c0..663232eda 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
@@ -43,6 +43,8 @@
#include <QQuickWindow>
#include <QVariant>
#include <QWindow>
+#include <private/qquickwindow_p.h>
+#include <private/qsgcontext_p.h>
RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(RenderWidgetHostViewQtDelegateClient *client, bool isPopup)
: m_client(client)
@@ -103,6 +105,16 @@ bool RenderWidgetHostViewQtDelegateQuick::hasKeyboardFocus()
return hasFocus();
}
+void RenderWidgetHostViewQtDelegateQuick::lockMouse()
+{
+ grabMouse();
+}
+
+void RenderWidgetHostViewQtDelegateQuick::unlockMouse()
+{
+ ungrabMouse();
+}
+
void RenderWidgetHostViewQtDelegateQuick::show()
{
setVisible(true);
@@ -123,6 +135,23 @@ QWindow* RenderWidgetHostViewQtDelegateQuick::window() const
return QQuickItem::window();
}
+QSGTexture *RenderWidgetHostViewQtDelegateQuick::createTextureFromImage(const QImage &image)
+{
+ return QQuickItem::window()->createTextureFromImage(image, QQuickWindow::TextureCanUseAtlas);
+}
+
+QSGLayer *RenderWidgetHostViewQtDelegateQuick::createLayer()
+{
+ QSGRenderContext *renderContext = QQuickWindowPrivate::get(QQuickItem::window())->context;
+ return renderContext->sceneGraphContext()->createLayer(renderContext);
+}
+
+QSGImageNode *RenderWidgetHostViewQtDelegateQuick::createImageNode()
+{
+ QSGRenderContext *renderContext = QQuickWindowPrivate::get(QQuickItem::window())->context;
+ return renderContext->sceneGraphContext()->createImageNode();
+}
+
void RenderWidgetHostViewQtDelegateQuick::update()
{
QQuickItem::update();
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.h b/src/webengine/render_widget_host_view_qt_delegate_quick.h
index ddc581289..305c14957 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.h
@@ -53,10 +53,15 @@ public:
virtual QRectF contentsRect() const Q_DECL_OVERRIDE;
virtual void setKeyboardFocus() Q_DECL_OVERRIDE;
virtual bool hasKeyboardFocus() Q_DECL_OVERRIDE;
+ virtual void lockMouse() Q_DECL_OVERRIDE;
+ virtual void unlockMouse() Q_DECL_OVERRIDE;
virtual void show() Q_DECL_OVERRIDE;
virtual void hide() Q_DECL_OVERRIDE;
virtual bool isVisible() const Q_DECL_OVERRIDE;
virtual QWindow* window() const Q_DECL_OVERRIDE;
+ virtual QSGTexture *createTextureFromImage(const QImage &) Q_DECL_OVERRIDE;
+ virtual QSGLayer *createLayer() Q_DECL_OVERRIDE;
+ virtual QSGImageNode *createImageNode() Q_DECL_OVERRIDE;
virtual void update() Q_DECL_OVERRIDE;
virtual void updateCursor(const QCursor &) Q_DECL_OVERRIDE;
virtual void resize(int width, int height) Q_DECL_OVERRIDE;
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
index da8d3d806..6a0e416e0 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
@@ -95,6 +95,21 @@ QWindow *RenderWidgetHostViewQtDelegateQuickWindow::window() const
return const_cast<RenderWidgetHostViewQtDelegateQuickWindow*>(this);
}
+QSGTexture *RenderWidgetHostViewQtDelegateQuickWindow::createTextureFromImage(const QImage &image)
+{
+ return m_realDelegate->createTextureFromImage(image);
+}
+
+QSGLayer *RenderWidgetHostViewQtDelegateQuickWindow::createLayer()
+{
+ return m_realDelegate->createLayer();
+}
+
+QSGImageNode *RenderWidgetHostViewQtDelegateQuickWindow::createImageNode()
+{
+ return m_realDelegate->createImageNode();
+}
+
void RenderWidgetHostViewQtDelegateQuickWindow::update()
{
QQuickWindow::update();
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
index eeab4a79a..d3e81e497 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
@@ -56,10 +56,15 @@ public:
virtual QRectF contentsRect() const Q_DECL_OVERRIDE;
virtual void setKeyboardFocus() Q_DECL_OVERRIDE {}
virtual bool hasKeyboardFocus() Q_DECL_OVERRIDE { return false; }
+ virtual void lockMouse() Q_DECL_OVERRIDE {}
+ virtual void unlockMouse() Q_DECL_OVERRIDE {}
virtual void show() Q_DECL_OVERRIDE;
virtual void hide() Q_DECL_OVERRIDE;
virtual bool isVisible() const Q_DECL_OVERRIDE;
virtual QWindow* window() const Q_DECL_OVERRIDE;
+ virtual QSGTexture *createTextureFromImage(const QImage &) Q_DECL_OVERRIDE;
+ virtual QSGLayer *createLayer() Q_DECL_OVERRIDE;
+ virtual QSGImageNode *createImageNode() Q_DECL_OVERRIDE;
virtual void update() Q_DECL_OVERRIDE;
virtual void updateCursor(const QCursor &) Q_DECL_OVERRIDE;
virtual void resize(int width, int height) Q_DECL_OVERRIDE;
diff --git a/src/webengine/webengine.pro b/src/webengine/webengine.pro
index 4c4606690..15514e457 100644
--- a/src/webengine/webengine.pro
+++ b/src/webengine/webengine.pro
@@ -4,17 +4,19 @@ TARGET = QtWebEngine
DEFINES += QT_BUILD_WEBENGINE_LIB
QT += qml quick
-QT_PRIVATE += webenginecore quick-private
+QT_PRIVATE += webenginecore quick-private gui-private core-private
QMAKE_DOCS = $$PWD/doc/qtwebengine.qdocconf
INCLUDEPATH += $$PWD api ../core
SOURCES = \
+ api/qquickwebenginedownloaditem.cpp \
api/qquickwebenginehistory.cpp \
api/qquickwebengineloadrequest.cpp \
api/qquickwebenginenavigationrequest.cpp \
api/qquickwebenginenewviewrequest.cpp \
+ api/qquickwebengineprofile.cpp \
api/qquickwebenginesettings.cpp \
api/qquickwebenginesingleton.cpp \
api/qquickwebengineview.cpp \
@@ -26,10 +28,14 @@ SOURCES = \
HEADERS = \
api/qtwebengineglobal.h \
api/qtwebengineglobal_p.h \
+ api/qquickwebenginedownloaditem_p.h \
+ api/qquickwebenginedownloaditem_p_p.h \
api/qquickwebenginehistory_p.h \
api/qquickwebengineloadrequest_p.h \
api/qquickwebenginenavigationrequest_p.h \
api/qquickwebenginenewviewrequest_p.h \
+ api/qquickwebengineprofile_p.h \
+ api/qquickwebengineprofile_p_p.h \
api/qquickwebenginesettings_p.h \
api/qquickwebenginesettings_p_p.h \
api/qquickwebenginesingleton_p.h \
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 72b16f28b..eafcf114c 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -23,10 +23,13 @@
#include "qwebenginepage.h"
#include "qwebenginepage_p.h"
+#include "browser_context_adapter.h"
#include "certificate_error_controller.h"
#include "javascript_dialog_controller.h"
#include "qwebenginehistory.h"
#include "qwebenginehistory_p.h"
+#include "qwebengineprofile.h"
+#include "qwebengineprofile_p.h"
#include "qwebenginesettings.h"
#include "qwebenginesettings_p.h"
#include "qwebengineview.h"
@@ -166,9 +169,10 @@ void CallbackDirectory::CallbackSharedDataPointer::doDeref()
}
}
-QWebEnginePagePrivate::QWebEnginePagePrivate()
+QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
: adapter(new WebContentsAdapter)
, history(new QWebEngineHistory(new QWebEngineHistoryPrivate(this)))
+ , profile(_profile ? _profile : QWebEngineProfile::defaultProfile())
, settings(new QWebEngineSettings)
, view(0)
, isLoading(false)
@@ -342,6 +346,18 @@ void QWebEnginePagePrivate::runMediaAccessPermissionRequest(const QUrl &security
Q_EMIT q->featurePermissionRequested(securityOrigin, requestedFeature);
}
+void QWebEnginePagePrivate::runGeolocationPermissionRequest(const QUrl &securityOrigin)
+{
+ Q_Q(QWebEnginePage);
+ Q_EMIT q->featurePermissionRequested(securityOrigin, QWebEnginePage::Geolocation);
+}
+
+void QWebEnginePagePrivate::runMouseLockPermissionRequest(const QUrl &securityOrigin)
+{
+ Q_Q(QWebEnginePage);
+ Q_EMIT q->featurePermissionRequested(securityOrigin, QWebEnginePage::MouseLock);
+}
+
QObject *QWebEnginePagePrivate::accessibilityParentObject()
{
return view;
@@ -410,9 +426,31 @@ void QWebEnginePagePrivate::recreateFromSerializedHistory(QDataStream &input)
}
}
+BrowserContextAdapter *QWebEnginePagePrivate::browserContextAdapter()
+{
+ return profile->d_ptr->browserContext();
+}
+
QWebEnginePage::QWebEnginePage(QObject* parent)
: QObject(parent)
- , d_ptr(new QWebEnginePagePrivate)
+ , d_ptr(new QWebEnginePagePrivate())
+{
+ Q_D(QWebEnginePage);
+ d->q_ptr = this;
+ d->adapter->initialize(d);
+}
+
+/*!
+ Constructs an empty QWebEnginePage in the QWebEngineProfile \a profile with parent \a parent.
+
+ If the profile is not the default profile the caller must ensure the profile is alive for as
+ long as the page is.
+
+ \since 5.5
+*/
+QWebEnginePage::QWebEnginePage(QWebEngineProfile *profile, QObject* parent)
+ : QObject(parent)
+ , d_ptr(new QWebEnginePagePrivate(profile))
{
Q_D(QWebEnginePage);
d->q_ptr = this;
@@ -448,6 +486,16 @@ QWidget *QWebEnginePage::view() const
return d->view;
}
+/*!
+ Returns the QWebEngineProfile the page belongs to.
+ \since 5.5
+*/
+QWebEngineProfile *QWebEnginePage::profile() const
+{
+ Q_D(const QWebEnginePage);
+ return d->profile;
+}
+
bool QWebEnginePage::hasSelection() const
{
return !selectedText().isEmpty();
@@ -624,6 +672,13 @@ bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData
return true;
}
+void QWebEnginePagePrivate::navigationRequested(int navigationType, const QUrl &url, int &navigationRequestAction, bool isMainFrame)
+{
+ Q_Q(QWebEnginePage);
+ bool accepted = q->acceptNavigationRequest(url, static_cast<QWebEnginePage::NavigationType>(navigationType), isMainFrame);
+ navigationRequestAction = accepted ? WebContentsAdapterClient::AcceptRequest : WebContentsAdapterClient::IgnoreRequest;
+}
+
void QWebEnginePagePrivate::javascriptDialog(QSharedPointer<JavaScriptDialogController> controller)
{
Q_Q(QWebEnginePage);
@@ -743,6 +798,8 @@ QMenu *QWebEnginePage::createStandardContextMenu()
void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEnginePage::Feature feature, QWebEnginePage::PermissionPolicy policy)
{
Q_D(QWebEnginePage);
+ if (policy == PermissionUnknown)
+ return;
WebContentsAdapterClient::MediaRequestFlags flags = WebContentsAdapterClient::MediaNone;
switch (feature) {
case MediaAudioVideoCapture:
@@ -761,6 +818,16 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine
}
d->adapter->grantMediaAccessPermission(securityOrigin, flags);
}
+ d->adapter->grantMediaAccessPermission(securityOrigin, flags);
+ break;
+ case QWebEnginePage::Geolocation:
+ d->adapter->runGeolocationRequestCallback(securityOrigin, (policy == PermissionGrantedByUser) ? true : false);
+ break;
+ case MouseLock:
+ if (policy == PermissionGrantedByUser)
+ d->adapter->grantMouseLockPermission(true);
+ else
+ d->adapter->grantMouseLockPermission(false);
break;
default:
break;
@@ -945,6 +1012,14 @@ bool QWebEnginePage::certificateError(const QWebEngineCertificateError &)
return false;
}
+bool QWebEnginePage::acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
+{
+ Q_UNUSED(url);
+ Q_UNUSED(type);
+ Q_UNUSED(isMainFrame);
+ return true;
+}
+
QT_END_NAMESPACE
#include "moc_qwebenginepage.cpp"
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index 7856b8243..4b9208117 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -50,8 +50,9 @@ QT_BEGIN_NAMESPACE
class QMenu;
class QWebEngineHistory;
class QWebEnginePage;
-class QWebEngineSettings;
class QWebEnginePagePrivate;
+class QWebEngineProfile;
+class QWebEngineSettings;
namespace QtWebEnginePrivate {
@@ -136,6 +137,16 @@ public:
PermissionDeniedByUser
};
+ // must match WebContentsAdapterClient::NavigationType
+ enum NavigationType {
+ NavigationTypeLinkClicked,
+ NavigationTypeTyped,
+ NavigationTypeFormSubmitted,
+ NavigationTypeBackForward,
+ NavigationTypeReload,
+ NavigationTypeOther
+ };
+
enum Feature {
#ifndef Q_QDOC
Notifications = 0,
@@ -143,7 +154,8 @@ public:
#endif
MediaAudioCapture = 2,
MediaVideoCapture,
- MediaAudioVideoCapture
+ MediaAudioVideoCapture,
+ MouseLock
};
// Ex-QWebFrame enum
@@ -161,6 +173,7 @@ public:
};
explicit QWebEnginePage(QObject *parent = 0);
+ QWebEnginePage(QWebEngineProfile *profile, QObject *parent = 0);
~QWebEnginePage();
QWebEngineHistory *history() const;
@@ -170,6 +183,8 @@ public:
bool hasSelection() const;
QString selectedText() const;
+ QWebEngineProfile *profile() const;
+
#ifndef QT_NO_ACTION
QAction *action(WebAction action) const;
#endif
@@ -248,6 +263,7 @@ protected:
virtual bool javaScriptPrompt(const QUrl &securityOrigin, const QString& msg, const QString& defaultValue, QString* result);
virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID);
virtual bool certificateError(const QWebEngineCertificateError &certificateError);
+ virtual bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame);
private:
Q_DECLARE_PRIVATE(QWebEnginePage);
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 54129229f..a11c44ded 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -49,6 +49,7 @@ class WebContentsAdapter;
QT_BEGIN_NAMESPACE
class QWebEngineHistory;
class QWebEnginePage;
+class QWebEngineProfile;
class QWebEngineSettings;
class QWebEngineView;
@@ -101,7 +102,7 @@ public:
Q_DECLARE_PUBLIC(QWebEnginePage)
QWebEnginePage *q_ptr;
- QWebEnginePagePrivate();
+ QWebEnginePagePrivate(QWebEngineProfile *profile = 0);
~QWebEnginePagePrivate();
virtual RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client) Q_DECL_OVERRIDE;
@@ -122,7 +123,7 @@ public:
virtual void adoptNewWindow(WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &initialGeometry) Q_DECL_OVERRIDE;
virtual void close() Q_DECL_OVERRIDE;
virtual bool contextMenuRequested(const WebEngineContextMenuData &data) Q_DECL_OVERRIDE;
- virtual void navigationRequested(int, const QUrl &, int &, bool) Q_DECL_OVERRIDE { }
+ virtual void navigationRequested(int navigationType, const QUrl &url, int &navigationRequestAction, bool isMainFrame) Q_DECL_OVERRIDE;
virtual void requestFullScreen(bool) Q_DECL_OVERRIDE { }
virtual bool isFullScreen() const Q_DECL_OVERRIDE { return false; }
virtual void javascriptDialog(QSharedPointer<JavaScriptDialogController>) Q_DECL_OVERRIDE;
@@ -135,10 +136,14 @@ public:
virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE;
virtual void authenticationRequired(const QUrl &requestUrl, const QString &realm, bool isProxy, const QString &challengingHost, QString *outUser, QString *outPassword) Q_DECL_OVERRIDE;
virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) Q_DECL_OVERRIDE;
+ virtual void runGeolocationPermissionRequest(const QUrl &securityOrigin) Q_DECL_OVERRIDE;
+ virtual void runMouseLockPermissionRequest(const QUrl &securityOrigin) Q_DECL_OVERRIDE;
virtual QObject *accessibilityParentObject() Q_DECL_OVERRIDE;
virtual WebEngineSettings *webEngineSettings() const Q_DECL_OVERRIDE;
virtual void allowCertificateError(const QExplicitlySharedDataPointer<CertificateErrorController> &controller) Q_DECL_OVERRIDE;
+ virtual BrowserContextAdapter *browserContextAdapter() Q_DECL_OVERRIDE;
+
void updateAction(QWebEnginePage::WebAction) const;
void updateNavigationActions();
void _q_webActionTriggered(bool checked);
@@ -148,6 +153,7 @@ public:
QExplicitlySharedDataPointer<WebContentsAdapter> adapter;
QWebEngineHistory *history;
+ QWebEngineProfile *profile;
QWebEngineSettings *settings;
QWebEngineView *view;
QSize viewportSize;
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
new file mode 100644
index 000000000..9929ee657
--- /dev/null
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -0,0 +1,352 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwebengineprofile.h"
+
+#include "qwebenginepage.h"
+#include "qwebengineprofile_p.h"
+
+#include "browser_context_adapter.h"
+#include "web_engine_visited_links_manager.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWebEngineProfile
+ \brief The QWebEngineProfile class provides a web-engine profile shared by multiple pages.
+ \since 5.5
+
+ \inmodule QtWebEngineWidgets
+
+ QWebEngineProfile contains settings and history shared by all QWebEnginePages that belong
+ to the profile.
+
+ A default profile is built-in that all web pages not specifically created with another profile
+ belongs to.
+*/
+
+/*!
+ \enum QWebEngineProfile::HttpCacheType
+
+ This enum describes the HTTP cache types QtWebEngine can be configured to use.
+
+ \value MemoryHttpCache Use a in-memory cache. This is the only setting possible if off-the-record is set or no cache path is available.
+ \value DiskHttpCache Use a disk cache. This is the default.
+*/
+
+/*!
+ \enum QWebEngineProfile::PersistentCookiesPolicy
+
+ This enum describes policy for cookie persistency.
+
+ \value NoPersistentCookies Both session and persistent cookies are stored in memory. This is the only setting possible if off-the-record is set or no persistent data path is available.
+ \value AllowPersistentCookies Cookies marked persistent are save and restored from disk, session cookies are only stored to disk for crash recovery. This is the default setting.
+ \value ForcePersistentCookies Both session and persistent cookies are save and restored from disk.
+*/
+
+QWebEngineProfilePrivate::QWebEngineProfilePrivate(BrowserContextAdapter* browserContext, bool ownsContext)
+ : m_browserContext(browserContext)
+{
+ if (ownsContext)
+ m_browserContextRef = browserContext;
+}
+
+QWebEngineProfilePrivate::~QWebEngineProfilePrivate()
+{
+}
+
+/*!
+ Constructs a new off-the-record profile.
+
+ An off-the-record profile leaves no record on the local machine, and has no persistent data or cache.
+ Thus, the HTTP cache can only be in memory and the cookies only be non-persistent, trying to change
+ these settings will have no effect.
+
+ \sa isOffTheRecord()
+*/
+QWebEngineProfile::QWebEngineProfile(QObject *parent)
+ : QObject(parent)
+ , d_ptr(new QWebEngineProfilePrivate(new BrowserContextAdapter(true), true))
+{
+}
+
+/*!
+ Constructs a new profile with storage name \a storageName.
+
+ The storage name must be unique.
+
+ A disk-based QWebEngineProfile should be destroyed on or before application exit, otherwise the cache
+ and persistent data may not be fully flushed to disk.
+
+ \sa storageName()
+*/
+QWebEngineProfile::QWebEngineProfile(const QString &storageName, QObject *parent)
+ : QObject(parent)
+ , d_ptr(new QWebEngineProfilePrivate(new BrowserContextAdapter(storageName), true))
+{
+}
+
+/*! \internal
+*/
+QWebEngineProfile::QWebEngineProfile(QWebEngineProfilePrivate *privatePtr)
+ : d_ptr(privatePtr)
+{
+}
+
+/*! \internal
+*/
+QWebEngineProfile::~QWebEngineProfile()
+{
+}
+
+/*!
+ Returns the storage name for the profile.
+
+ The storage name is used to give each profile that uses the disk separate subdirectories for persistent data and cache.
+*/
+QString QWebEngineProfile::storageName() const
+{
+ const Q_D(QWebEngineProfile);
+ return d->browserContext()->storageName();
+}
+
+/*!
+ Returns true if this is an off-the-record profile that leaves no record on the computer.
+
+ This will force cookies and HTTP cache to be in memory, but also force all other normally
+ persistent data to be stored in memory.
+*/
+bool QWebEngineProfile::isOffTheRecord() const
+{
+ const Q_D(QWebEngineProfile);
+ return d->browserContext()->isOffTheRecord();
+}
+
+/*!
+ Returns the path used to store persistent data for the browser and web content.
+
+ Persistent data includes persistent cookies, HTML5 local storage and visited links.
+
+ By default this is below QStandardPaths::writableLocation(QStandardPaths::DataLocation) in a storage name specific directory.
+
+ \sa setPersistentStoragePath(), storageName(), QStandardPaths::writableLocation()
+*/
+QString QWebEngineProfile::persistentStoragePath() const
+{
+ const Q_D(QWebEngineProfile);
+ return d->browserContext()->dataPath();
+}
+
+/*!
+ Overrides the default path used to store persistent web engine data.
+
+ If set to the null string, the default path is restored.
+
+ \sa persistentStoragePath()
+*/
+void QWebEngineProfile::setPersistentStoragePath(const QString &path)
+{
+ const Q_D(QWebEngineProfile);
+ d->browserContext()->setDataPath(path);
+}
+
+/*!
+ Returns the path used for caches.
+
+ By default this is below QStandardPaths::writableLocation(QStandardPaths::CacheLocation) in a storage name specific directory.
+
+ \sa setCachePath(), storageName(), QStandardPaths::writableLocation()
+*/
+QString QWebEngineProfile::cachePath() const
+{
+ const Q_D(QWebEngineProfile);
+ return d->browserContext()->cachePath();
+}
+
+/*!
+ Overrides the default path used for disk caches.
+
+ If set to the null string, the default path is restored.
+
+ \sa cachePath()
+*/
+void QWebEngineProfile::setCachePath(const QString &path)
+{
+ Q_D(QWebEngineProfile);
+ d->browserContext()->setCachePath(path);
+}
+
+/*!
+ Returns the user-agent string send with HTTP to identify the browser.
+
+ \sa setHttpUserAgent()
+*/
+QString QWebEngineProfile::httpUserAgent() const
+{
+ const Q_D(QWebEngineProfile);
+ return d->browserContext()->httpUserAgent();
+}
+
+/*!
+ Overrides the default user-agent string, setting it to \a userAgent.
+
+ \sa httpUserAgent()
+*/
+void QWebEngineProfile::setHttpUserAgent(const QString &userAgent)
+{
+ Q_D(QWebEngineProfile);
+ d->browserContext()->setHttpUserAgent(userAgent);
+}
+
+/*!
+ Returns the type of HTTP cache used.
+
+ If the profile is off-the-record MemoryHttpCache is returned.
+
+ \sa setHttpCacheType(), cachePath()
+*/
+QWebEngineProfile::HttpCacheType QWebEngineProfile::httpCacheType() const
+{
+ const Q_D(QWebEngineProfile);
+ return QWebEngineProfile::HttpCacheType(d->browserContext()->httpCacheType());
+}
+
+/*!
+ Sets the HTTP cache type to \a httpCacheType.
+
+ \sa httpCacheType(), setCachePath()
+*/
+void QWebEngineProfile::setHttpCacheType(QWebEngineProfile::HttpCacheType httpCacheType)
+{
+ Q_D(QWebEngineProfile);
+ d->browserContext()->setHttpCacheType(BrowserContextAdapter::HttpCacheType(httpCacheType));
+}
+
+/*!
+ Returns the current policy for persistent cookies.
+
+ If the profile is off-the-record NoPersistentCookies is returned.
+
+ \sa setPersistentCookiesPolicy()
+*/
+QWebEngineProfile::PersistentCookiesPolicy QWebEngineProfile::persistentCookiesPolicy() const
+{
+ const Q_D(QWebEngineProfile);
+ return QWebEngineProfile::PersistentCookiesPolicy(d->browserContext()->persistentCookiesPolicy());
+}
+
+/*!
+ Sets the policy for persistent cookies to \a newPersistentCookiesPolicy.
+
+ \sa persistentCookiesPolicy()
+*/
+void QWebEngineProfile::setPersistentCookiesPolicy(QWebEngineProfile::PersistentCookiesPolicy newPersistentCookiesPolicy)
+{
+ Q_D(QWebEngineProfile);
+ d->browserContext()->setPersistentCookiesPolicy(BrowserContextAdapter::PersistentCookiesPolicy(newPersistentCookiesPolicy));
+}
+
+/*!
+ Returns the maximum size of the HTTP size.
+
+ Will return 0 if the size is automatically controlled by QtWebEngine.
+
+ \sa setHttpCacheMaximumSize(), httpCacheType()
+*/
+int QWebEngineProfile::httpCacheMaximumSize() const
+{
+ const Q_D(QWebEngineProfile);
+ return d->browserContext()->httpCacheMaxSize();
+}
+
+/*!
+ Sets the maximum size of the HTTP cache to \a maxSize.
+
+ Setting it to 0 means the size will be controlled automatically by QtWebEngine.
+
+ \sa httpCacheMaximumSize(), setHttpCacheType()
+*/
+void QWebEngineProfile::setHttpCacheMaximumSize(int maxSize)
+{
+ Q_D(QWebEngineProfile);
+ d->browserContext()->setHttpCacheMaxSize(maxSize);
+}
+
+/*!
+ Clears all links from the visited links database.
+
+ \sa clearVisitedLinks()
+*/
+void QWebEngineProfile::clearAllVisitedLinks()
+{
+ Q_D(QWebEngineProfile);
+ d->browserContext()->visitedLinksManager()->deleteAllVisitedLinkData();
+}
+
+/*!
+ Clears the links in \a urls from the visited links database.
+
+ \sa clearAllVisitedLinks()
+*/
+void QWebEngineProfile::clearVisitedLinks(const QList<QUrl> &urls)
+{
+ Q_D(QWebEngineProfile);
+ d->browserContext()->visitedLinksManager()->deleteVisitedLinkDataForUrls(urls);
+}
+
+/*!
+ Returns true if \a url is considered a visited link by this profile.
+*/
+bool QWebEngineProfile::visitedLinksContainsUrl(const QUrl &url) const
+{
+ Q_D(const QWebEngineProfile);
+ return d->browserContext()->visitedLinksManager()->containsUrl(url);
+}
+
+/*!
+ Returns the default profile.
+
+ The default profile uses the storage name "Default".
+
+ \sa storageName()
+*/
+QWebEngineProfile *QWebEngineProfile::defaultProfile()
+{
+ static QWebEngineProfile profile(new QWebEngineProfilePrivate(BrowserContextAdapter::defaultContext(), false));
+ return &profile;
+}
+
+QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebengineprofile.h b/src/webenginewidgets/api/qwebengineprofile.h
new file mode 100644
index 000000000..0536d711f
--- /dev/null
+++ b/src/webenginewidgets/api/qwebengineprofile.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBENGINEPROFILE_H
+#define QWEBENGINEPROFILE_H
+
+#include "qtwebenginewidgetsglobal.h"
+
+#include <QObject>
+#include <QScopedPointer>
+#include <QString>
+
+QT_BEGIN_NAMESPACE
+
+class QObject;
+class QUrl;
+class QWebEnginePage;
+class QWebEnginePagePrivate;
+class QWebEngineProfilePrivate;
+
+class QWEBENGINEWIDGETS_EXPORT QWebEngineProfile : public QObject {
+ Q_OBJECT
+public:
+ explicit QWebEngineProfile(QObject *parent = 0);
+ explicit QWebEngineProfile(const QString &name, QObject *parent = 0);
+ virtual ~QWebEngineProfile();
+
+ enum HttpCacheType {
+ MemoryHttpCache,
+ DiskHttpCache
+ };
+
+ enum PersistentCookiesPolicy {
+ NoPersistentCookies,
+ AllowPersistentCookies,
+ ForcePersistentCookies
+ };
+
+ QString storageName() const;
+ bool isOffTheRecord() const;
+
+ QString persistentStoragePath() const;
+ void setPersistentStoragePath(const QString &path);
+
+ QString cachePath() const;
+ void setCachePath(const QString &path);
+
+ QString httpUserAgent() const;
+ void setHttpUserAgent(const QString &userAgent);
+
+ HttpCacheType httpCacheType() const;
+ void setHttpCacheType(QWebEngineProfile::HttpCacheType);
+
+ PersistentCookiesPolicy persistentCookiesPolicy() const;
+ void setPersistentCookiesPolicy(QWebEngineProfile::PersistentCookiesPolicy);
+
+ int httpCacheMaximumSize() const;
+ void setHttpCacheMaximumSize(int maxSize);
+
+ void clearAllVisitedLinks();
+ void clearVisitedLinks(const QList<QUrl> &urls);
+ bool visitedLinksContainsUrl(const QUrl &url) const;
+
+ static QWebEngineProfile *defaultProfile();
+
+private:
+ Q_DECLARE_PRIVATE(QWebEngineProfile);
+ QWebEngineProfile(QWebEngineProfilePrivate *);
+
+ friend class QWebEnginePagePrivate;
+ QScopedPointer<QWebEngineProfilePrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINEPROFILE_H
diff --git a/src/webenginewidgets/api/qwebengineprofile_p.h b/src/webenginewidgets/api/qwebengineprofile_p.h
new file mode 100644
index 000000000..3a08b6b1e
--- /dev/null
+++ b/src/webenginewidgets/api/qwebengineprofile_p.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBENGINEPROFILE_P_H
+#define QWEBENGINEPROFILE_P_H
+
+class BrowserContextAdapter;
+
+QT_BEGIN_NAMESPACE
+
+class QWebEngineSettings;
+
+class QWebEngineProfilePrivate {
+public:
+ QWebEngineProfilePrivate(BrowserContextAdapter* browserContext, bool ownsContext);
+ ~QWebEngineProfilePrivate();
+
+ BrowserContextAdapter *browserContext() const { return m_browserContext; }
+
+private:
+ BrowserContextAdapter *m_browserContext;
+ QExplicitlySharedDataPointer<BrowserContextAdapter> m_browserContextRef;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINEPROFILE_P_H
diff --git a/src/webenginewidgets/api/qwebenginesettings.cpp b/src/webenginewidgets/api/qwebenginesettings.cpp
index 729a09f56..3a0f4fced 100644
--- a/src/webenginewidgets/api/qwebenginesettings.cpp
+++ b/src/webenginewidgets/api/qwebenginesettings.cpp
@@ -39,7 +39,7 @@
#include <QDebug>
-QT_USE_NAMESPACE
+QT_BEGIN_NAMESPACE
static WebEngineSettings::Attribute toWebEngineAttribute(QWebEngineSettings::WebAttribute attribute) {
switch (attribute) {
@@ -74,7 +74,21 @@ static WebEngineSettings::Attribute toWebEngineAttribute(QWebEngineSettings::Web
}
}
-Q_GLOBAL_STATIC(QList<QWebEngineSettingsPrivate*>, allSettings);
+Q_GLOBAL_STATIC(QList<QWebEngineSettingsPrivate*>, allSettings)
+
+class QWebEngineGlobalSettings {
+ QWebEngineSettings globalSettings;
+public:
+ QWebEngineGlobalSettings() {
+ // globalSettings shouldn't be in that list.
+ allSettings->removeAll(globalSettings.d_func());
+ globalSettings.d_func()->coreSettings->initDefaults();
+ }
+
+ QWebEngineSettings *data() { return &globalSettings; }
+};
+
+Q_GLOBAL_STATIC(QWebEngineGlobalSettings, globalInstance)
QWebEngineSettingsPrivate::QWebEngineSettingsPrivate()
: coreSettings(new WebEngineSettings(this))
@@ -92,25 +106,13 @@ void QWebEngineSettingsPrivate::apply()
}
}
-void QWebEngineSettingsPrivate::initDefaults()
-{
- coreSettings->initDefaults();
-}
-
WebEngineSettings *QWebEngineSettingsPrivate::fallbackSettings() const {
return QWebEngineSettings::globalSettings()->d_func()->coreSettings.data();
}
QWebEngineSettings *QWebEngineSettings::globalSettings()
{
- static QWebEngineSettings* globalSettings = 0;
- if (!globalSettings) {
- globalSettings = new QWebEngineSettings;
- // globalSettings shouldn't be in that list.
- allSettings->removeAll(globalSettings->d_func());
- globalSettings->d_func()->initDefaults();
- }
- return globalSettings;
+ return globalInstance()->data();
}
Q_STATIC_ASSERT_X(static_cast<int>(WebEngineSettings::StandardFont) == static_cast<int>(QWebEngineSettings::StandardFont), "The enum values must match");
@@ -215,3 +217,5 @@ void QWebEngineSettings::resetAttribute(QWebEngineSettings::WebAttribute attr)
{
setAttribute(attr, globalSettings()->testAttribute(attr));
}
+
+QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebenginesettings.h b/src/webenginewidgets/api/qwebenginesettings.h
index d9f57a935..29825f5a4 100644
--- a/src/webenginewidgets/api/qwebenginesettings.h
+++ b/src/webenginewidgets/api/qwebenginesettings.h
@@ -31,6 +31,7 @@ class QIcon;
class QPixmap;
class QUrl;
class QWebEngineSettingsPrivate;
+class QWebEngineGlobalSettings;
class QWEBENGINEWIDGETS_EXPORT QWebEngineSettings {
public:
@@ -87,6 +88,7 @@ private:
Q_DECLARE_PRIVATE(QWebEngineSettings);
QScopedPointer<QWebEngineSettingsPrivate> d_ptr;
friend class QWebEnginePagePrivate;
+ friend class QWebEngineGlobalSettings;
QWebEngineSettings();
~QWebEngineSettings();
diff --git a/src/webenginewidgets/api/qwebenginesettings_p.h b/src/webenginewidgets/api/qwebenginesettings_p.h
index 830e8b360..12464fa02 100644
--- a/src/webenginewidgets/api/qwebenginesettings_p.h
+++ b/src/webenginewidgets/api/qwebenginesettings_p.h
@@ -48,7 +48,6 @@ class QWebEngineSettingsPrivate : public WebEngineSettingsDelegate {
public:
QWebEngineSettingsPrivate();
- void initDefaults();
void apply() Q_DECL_OVERRIDE;
WebEngineSettings *fallbackSettings() const Q_DECL_OVERRIDE;
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index e89b10ab8..af435d170 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -147,6 +147,21 @@
*/
/*!
+ \enum QWebEnginePage::NavigationType
+
+ This enum describes the type of a navigation request.
+
+ \value NavigationTypeLinkClicked The navigation request resulted from a clicked link.
+ \value NavigationTypeTyped The navigation request resulted from an explicitly loaded url.
+ \value NavigationTypeFormSubmitted The navigation request resulted from a form submission.
+ \value NavigationTypeBackForward The navigation request resulted from a back/forward action.
+ \value NavigationTypeReload The navigation request resulted from a reload action.
+ \value NavigationTypeOther The navigation request was triggered by other means not covered by the above.
+
+ \sa acceptNavigationRequest()
+*/
+
+/*!
\enum QWebEnginePage::Feature
This enum describes the platform feature access categories that the user may be asked to grant or deny access to.
@@ -209,6 +224,15 @@
*/
/*!
+ \fn bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
+ This function is called whenever there is a request to navigate to a specified \a url by means of the specified navigation type \atype.
+ The \a isMainFrame argument marks if the request corresponds to the main frame, or a sub frame.
+ If the request is accepted Chromium will continue to load the page, else the request will be ignored.
+ The default implementation accepts the navigation request.
+*/
+
+
+/*!
\fn void QWebEnginePage::javaScriptAlert(const QUrl &securityOrigin, const QString& msg)
This function is called whenever a JavaScript program running in a frame affiliated with \a securityOrigin calls the alert() function with
the message \a msg.
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
index c4a32d685..3880e4197 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -44,9 +44,11 @@
#include <QOpenGLContext>
#include <QResizeEvent>
#include <QSGAbstractRenderer>
-#include <QSGEngine>
#include <QSGNode>
#include <QWindow>
+#include <private/qsgcontext_p.h>
+#include <private/qsgengine_p.h>
+
static const int MaxTooltipLength = 1024;
@@ -119,6 +121,16 @@ bool RenderWidgetHostViewQtDelegateWidget::hasKeyboardFocus()
return hasFocus();
}
+void RenderWidgetHostViewQtDelegateWidget::lockMouse()
+{
+ grabMouse();
+}
+
+void RenderWidgetHostViewQtDelegateWidget::unlockMouse()
+{
+ releaseMouse();
+}
+
void RenderWidgetHostViewQtDelegateWidget::show()
{
// Check if we're attached to a QWebEngineView, we don't
@@ -143,6 +155,22 @@ QWindow* RenderWidgetHostViewQtDelegateWidget::window() const
return root ? root->windowHandle() : 0;
}
+QSGTexture *RenderWidgetHostViewQtDelegateWidget::createTextureFromImage(const QImage &image)
+{
+ return m_sgEngine->createTextureFromImage(image, QSGEngine::TextureCanUseAtlas);
+}
+
+QSGLayer *RenderWidgetHostViewQtDelegateWidget::createLayer()
+{
+ QSGEnginePrivate *enginePrivate = QSGEnginePrivate::get(m_sgEngine.data());
+ return enginePrivate->sgContext->createLayer(enginePrivate->sgRenderContext.data());
+}
+
+QSGImageNode *RenderWidgetHostViewQtDelegateWidget::createImageNode()
+{
+ return QSGEnginePrivate::get(m_sgEngine.data())->sgContext->createImageNode();
+}
+
void RenderWidgetHostViewQtDelegateWidget::update()
{
#if (QT_VERSION < QT_VERSION_CHECK(5, 4, 0))
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
index 0b553d8eb..8fc189124 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
@@ -61,10 +61,15 @@ public:
virtual QRectF contentsRect() const Q_DECL_OVERRIDE;
virtual void setKeyboardFocus() Q_DECL_OVERRIDE;
virtual bool hasKeyboardFocus() Q_DECL_OVERRIDE;
+ virtual void lockMouse() Q_DECL_OVERRIDE;
+ virtual void unlockMouse() Q_DECL_OVERRIDE;
virtual void show() Q_DECL_OVERRIDE;
virtual void hide() Q_DECL_OVERRIDE;
virtual bool isVisible() const Q_DECL_OVERRIDE;
virtual QWindow* window() const Q_DECL_OVERRIDE;
+ virtual QSGTexture *createTextureFromImage(const QImage &) Q_DECL_OVERRIDE;
+ virtual QSGLayer *createLayer() Q_DECL_OVERRIDE;
+ virtual QSGImageNode *createImageNode() Q_DECL_OVERRIDE;
virtual void update() Q_DECL_OVERRIDE;
virtual void updateCursor(const QCursor &) Q_DECL_OVERRIDE;
virtual void resize(int width, int height) Q_DECL_OVERRIDE;
diff --git a/src/webenginewidgets/webenginewidgets.pro b/src/webenginewidgets/webenginewidgets.pro
index 4da888baa..638535bbc 100644
--- a/src/webenginewidgets/webenginewidgets.pro
+++ b/src/webenginewidgets/webenginewidgets.pro
@@ -4,7 +4,7 @@ TARGET = QtWebEngineWidgets
DEFINES += QT_BUILD_WEBENGINEWIDGETS_LIB
QT += webengine widgets network quick
-QT_PRIVATE += webenginecore
+QT_PRIVATE += webenginecore quick-private gui-private core-private
QMAKE_DOCS = $$PWD/doc/qtwebenginewidgets.qdocconf
@@ -15,8 +15,9 @@ SOURCES = \
api/qwebenginecertificateerror.cpp \
api/qwebenginehistory.cpp \
api/qwebenginepage.cpp \
+ api/qwebengineprofile.cpp \
api/qwebenginesettings.cpp \
- api/qwebengineview.cpp\
+ api/qwebengineview.cpp \
render_widget_host_view_qt_delegate_widget.cpp
HEADERS = \
@@ -25,6 +26,8 @@ HEADERS = \
api/qwebenginehistory.h \
api/qwebenginepage.h \
api/qwebenginepage_p.h \
+ api/qwebengineprofile.h \
+ api/qwebengineprofile_p.h \
api/qwebenginesettings.h \
api/qwebenginesettings_p.h \
api/qwebengineview.h \
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index f7cffb8b1..28a837260 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -48,6 +48,7 @@
#include <private/qquickwebengineview_p.h>
#include <private/qquickwebengineloadrequest_p.h>
#include <private/qquickwebenginenavigationrequest_p.h>
+#include <private/qquickwebengineprofile_p.h>
class tst_publicapi : public QObject {
Q_OBJECT
@@ -59,6 +60,7 @@ static QList<const QMetaObject *> typesToCheck = QList<const QMetaObject *>()
<< &QQuickWebEngineView::staticMetaObject
<< &QQuickWebEngineLoadRequest::staticMetaObject
<< &QQuickWebEngineNavigationRequest::staticMetaObject
+ << &QQuickWebEngineProfile::staticMetaObject
;
static QList<const char *> knownEnumNames = QList<const char *>();
@@ -90,6 +92,7 @@ static QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.NewViewInWindow --> NewViewDestination"
<< "QQuickWebEngineView.NewViewInTab --> NewViewDestination"
<< "QQuickWebEngineView.NewViewInDialog --> NewViewDestination"
+ << "QQuickWebEngineView.NewViewInBackgroundTab --> NewViewDestination"
<< "QQuickWebEngineView.InfoMessageLevel --> JavaScriptConsoleMessageLevel"
<< "QQuickWebEngineView.WarningMessageLevel --> JavaScriptConsoleMessageLevel"
<< "QQuickWebEngineView.ErrorMessageLevel --> JavaScriptConsoleMessageLevel"
@@ -117,6 +120,10 @@ static QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.goForward() --> void"
<< "QQuickWebEngineView.stop() --> void"
<< "QQuickWebEngineView.reload() --> void"
+ << "QQuickWebEngineView.zoomFactor --> double"
+ << "QQuickWebEngineView.zoomFactorChanged(double) --> void"
+ << "QQuickWebEngineView.setZoomFactor(double) --> void"
+ << "QQuickWebEngineView.profile --> QQuickWebEngineProfile*"
<< "QQuickWebEngineLoadRequest.url --> QUrl"
<< "QQuickWebEngineLoadRequest.status --> QQuickWebEngineView::LoadStatus"
<< "QQuickWebEngineLoadRequest.errorString --> QString"
@@ -127,6 +134,27 @@ static QStringList expectedAPI = QStringList()
<< "QQuickWebEngineNavigationRequest.action --> QQuickWebEngineView::NavigationRequestAction"
<< "QQuickWebEngineNavigationRequest.navigationType --> QQuickWebEngineView::NavigationType"
<< "QQuickWebEngineNavigationRequest.actionChanged() --> void"
+ << "QQuickWebEngineProfile.MemoryHttpCache --> HttpCacheType"
+ << "QQuickWebEngineProfile.DiskHttpCache --> HttpCacheType"
+ << "QQuickWebEngineProfile.NoPersistentCookies --> PersistentCookiesPolicy"
+ << "QQuickWebEngineProfile.AllowPersistentCookies --> PersistentCookiesPolicy"
+ << "QQuickWebEngineProfile.ForcePersistentCookies --> PersistentCookiesPolicy"
+ << "QQuickWebEngineProfile.storageName --> QString"
+ << "QQuickWebEngineProfile.offTheRecord --> bool"
+ << "QQuickWebEngineProfile.persistentStoragePath --> QString"
+ << "QQuickWebEngineProfile.cachePath --> QString"
+ << "QQuickWebEngineProfile.httpUserAgent --> QString"
+ << "QQuickWebEngineProfile.httpCacheType --> HttpCacheType"
+ << "QQuickWebEngineProfile.persistentCookiesPolicy --> PersistentCookiesPolicy"
+ << "QQuickWebEngineProfile.httpCacheMaxSize --> int"
+ << "QQuickWebEngineProfile.storageNameChanged() --> void"
+ << "QQuickWebEngineProfile.offTheRecordChanged() --> void"
+ << "QQuickWebEngineProfile.persistentStoragePathChanged() --> void"
+ << "QQuickWebEngineProfile.cachePathChanged() --> void"
+ << "QQuickWebEngineProfile.httpUserAgentChanged() --> void"
+ << "QQuickWebEngineProfile.httpCacheTypeChanged() --> void"
+ << "QQuickWebEngineProfile.persistentCookiesPolicyChanged() --> void"
+ << "QQuickWebEngineProfile.httpCacheMaxSizeChanged() --> void"
;
static bool isCheckedEnum(const QByteArray &typeName)
diff --git a/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml b/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml
new file mode 100644
index 000000000..f9b95ac19
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Quick Controls module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.3
+import QtTest 1.0
+import QtWebEngine 1.0
+
+Item {
+width: 300
+height: 400
+ TextInput {
+ id: textInput
+ anchors {
+ top: parent.top
+ left: parent.left
+ right: parent.right
+ }
+ focus: true
+ text: Qt.resolvedUrl("test1.html")
+ onEditingFinished: webEngineView.url = text
+ }
+
+ TestWebEngineView {
+ id: webEngineView
+ anchors {
+ top: textInput.bottom
+ left: parent.left
+ right: parent.right
+ bottom: parent.bottom
+ }
+
+ TestCase {
+ name: "WebEngineViewLoadRecursionCrash"
+ when:windowShown
+
+ function test_QTBUG_42929() {
+ textInput.forceActiveFocus()
+ keyClick(Qt.Key_Return)
+ verify(webEngineView.waitForLoadSucceeded())
+ textInput.text = "about:blank"
+ textInput.forceActiveFocus()
+ keyClick(Qt.Key_Return)
+ verify(webEngineView.waitForLoadSucceeded())
+ textInput.text = Qt.resolvedUrl("test4.html")
+ textInput.forceActiveFocus()
+ // Don't crash now
+ keyClick(Qt.Key_Return)
+ verify(webEngineView.waitForLoadSucceeded())
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/qmltests.pro b/tests/auto/quick/qmltests/qmltests.pro
index b40ef3b8c..33a864cf1 100644
--- a/tests/auto/quick/qmltests/qmltests.pro
+++ b/tests/auto/quick/qmltests/qmltests.pro
@@ -23,6 +23,7 @@ OTHER_FILES += \
$$PWD/data/tst_loadHtml.qml \
$$PWD/data/tst_loadProgress.qml \
$$PWD/data/tst_loadProgressSignal.qml \
+ $$PWD/data/tst_loadRecursionCrash.qml \
$$PWD/data/tst_loadUrl.qml \
$$PWD/data/tst_navigationHistory.qml \
$$PWD/data/tst_navigationRequested.qml \
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 6fb46057d..85939a686 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -107,11 +107,11 @@ private Q_SLOTS:
void contextMenuCopy();
void contextMenuPopulatedOnce();
void acceptNavigationRequest();
+ void acceptNavigationRequestNavigationType();
void geolocationRequestJS();
void loadFinished();
void actionStates();
void popupFormSubmission();
- void acceptNavigationRequestWithNewWindow();
void userStyleSheet();
void userStyleSheetFromLocalFileUrl();
void userStyleSheetFromQrcUrl();
@@ -133,8 +133,6 @@ private Q_SLOTS:
void textEditing();
void backActionUpdate();
void frameAt();
- void requestCache();
- void loadCachedPage();
void protectBindingsRuntimeObjectsFromCollector();
void localURLSchemes();
void testOptionalJSObjects();
@@ -240,7 +238,6 @@ void tst_QWebEnginePage::cleanupTestCase()
cleanupFiles(); // Be nice
}
-#if defined(QWEBENGINEPAGE_ACCEPTNAVIGATIONREQUEST)
class NavigationRequestOverride : public QWebEnginePage
{
public:
@@ -248,21 +245,18 @@ public:
bool m_acceptNavigationRequest;
protected:
- virtual bool acceptNavigationRequest(QWebEngineFrame* frame, const QNetworkRequest &request, QWebEnginePage::NavigationType type) {
- Q_UNUSED(frame);
- Q_UNUSED(request);
+ virtual bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
+ {
+ Q_UNUSED(url);
Q_UNUSED(type);
+ Q_UNUSED(isMainFrame);
return m_acceptNavigationRequest;
}
};
-#endif
void tst_QWebEnginePage::acceptNavigationRequest()
{
-#if !defined(QWEBENGINEPAGE_ACCEPTNAVIGATIONREQUEST)
- QSKIP("QWEBENGINEPAGE_ACCEPTNAVIGATIONREQUEST");
-#else
QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
NavigationRequestOverride* newPage = new NavigationRequestOverride(m_view, false);
@@ -278,11 +272,10 @@ void tst_QWebEnginePage::acceptNavigationRequest()
evaluateJavaScriptSync(m_view->page(), "tstform.submit();");
QTRY_COMPARE(loadSpy.count(), 2);
- QCOMPARE(m_view->page()->toPlainText(), QString("foo?"));
+ QCOMPARE(toPlainTextSync(m_view->page()), QString("foo?"));
// Restore default page
m_view->setPage(0);
-#endif
}
#if defined(QWEBENGINEPAGE_SETFEATUREPERMISSION)
@@ -439,23 +432,22 @@ public:
connect(this, SIGNAL(geometryChangeRequested(QRect)), this, SLOT(slotGeometryChangeRequested(QRect)));
}
-#if defined(QWEBENGINEPAGE_ACCEPTNAVIGATIONREQUEST)
struct Navigation {
- QWebEngineFrame *frame;
- QNetworkRequest request;
NavigationType type;
+ QUrl url;
+ bool isMainFrame;
};
QList<Navigation> navigations;
- virtual bool acceptNavigationRequest(QWebEngineFrame* frame, const QNetworkRequest &request, NavigationType type) {
+ virtual bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
+ {
Navigation n;
- n.frame = frame;
- n.request = request;
+ n.url = url;
n.type = type;
+ n.isMainFrame = isMainFrame;
navigations.append(n);
return true;
}
-#endif
QList<TestPage*> createdWindows;
virtual QWebEnginePage* createWindow(WebWindowType) {
@@ -471,6 +463,42 @@ private Q_SLOTS:
}
};
+void tst_QWebEnginePage::acceptNavigationRequestNavigationType()
+{
+
+ TestPage page;
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+
+ page.load(QUrl("qrc:///resources/script.html"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(page.navigations.count(), 1);
+
+ page.load(QUrl("qrc:///resources/content.html"));
+ QTRY_COMPARE(loadSpy.count(), 2);
+ QTRY_COMPARE(page.navigations.count(), 2);
+
+ page.triggerAction(QWebEnginePage::Stop);
+ QVERIFY(page.history()->canGoBack());
+ page.triggerAction(QWebEnginePage::Back);
+
+ QTRY_COMPARE(loadSpy.count(), 3);
+ QTRY_COMPARE(page.navigations.count(), 3);
+
+ page.triggerAction(QWebEnginePage::Reload);
+ QTRY_COMPARE(loadSpy.count(), 4);
+ QTRY_COMPARE(page.navigations.count(), 4);
+
+ QList<QWebEnginePage::NavigationType> expectedList;
+ expectedList << QWebEnginePage::NavigationTypeTyped
+ << QWebEnginePage::NavigationTypeTyped
+ << QWebEnginePage::NavigationTypeBackForward
+ << QWebEnginePage::NavigationTypeReload;
+ QVERIFY(expectedList.count() == page.navigations.count());
+ for (int i = 0; i < expectedList.count(); ++i) {
+ QCOMPARE(page.navigations[i].type, expectedList[i]);
+ }
+}
+
void tst_QWebEnginePage::popupFormSubmission()
{
TestPage page;
@@ -491,38 +519,6 @@ void tst_QWebEnginePage::popupFormSubmission()
QVERIFY(url.contains("?foo=bar"));
}
-void tst_QWebEnginePage::acceptNavigationRequestWithNewWindow()
-{
-#if !defined(QWEBENGINESETTINGS)
- QSKIP("QWEBENGINESETTINGS");
-#else
- TestPage* page = new TestPage(m_view);
- page->settings()->setAttribute(QWebEngineSettings::LinksIncludedInFocusChain, true);
- m_page = page;
- m_view->setPage(m_page);
-
- m_view->setUrl(QString("data:text/html,<a href=\"data:text/html,Reached\" target=\"_blank\">Click me</a>"));
- QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool))));
-
- QFocusEvent fe(QEvent::FocusIn);
- m_page->event(&fe);
-
- QVERIFY(m_page->focusNextPrevChild(/*next*/ true));
-
- QKeyEvent keyEnter(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
- m_page->event(&keyEnter);
-
- QCOMPARE(page->navigations.count(), 2);
-
- TestPage::Navigation n = page->navigations.at(1);
- QVERIFY(!n.frame);
- QCOMPARE(n.request.url().toString(), QString("data:text/html,Reached"));
- QVERIFY(n.type == QWebEnginePage::NavigationTypeLinkClicked);
-
- QCOMPARE(page->createdWindows.count(), 1);
-#endif
-}
-
class TestNetworkManager : public QNetworkAccessManager
{
public:
@@ -1606,72 +1602,6 @@ void tst_QWebEnginePage::textEditing()
#endif
}
-void tst_QWebEnginePage::requestCache()
-{
-#if !defined(ACCEPTNAVIGATIONREQUEST)
- QSKIP("ACCEPTNAVIGATIONREQUEST");
-#else
- TestPage page;
- QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
-
- page.setUrl(QString("data:text/html,<a href=\"data:text/html,Reached\" target=\"_blank\">Click me</a>"));
- QTRY_COMPARE(loadSpy.count(), 1);
- QTRY_COMPARE(page.navigations.count(), 1);
-
- page.setUrl(QString("data:text/html,<a href=\"data:text/html,Reached\" target=\"_blank\">Click me2</a>"));
- QTRY_COMPARE(loadSpy.count(), 2);
- QTRY_COMPARE(page.navigations.count(), 2);
-
- page.triggerAction(QWebEnginePage::Stop);
- QVERIFY(page.history()->canGoBack());
- page.triggerAction(QWebEnginePage::Back);
-
- QTRY_COMPARE(loadSpy.count(), 3);
- QTRY_COMPARE(page.navigations.count(), 3);
- QCOMPARE(page.navigations.at(0).request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(),
- (int)QNetworkRequest::PreferNetwork);
- QCOMPARE(page.navigations.at(1).request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(),
- (int)QNetworkRequest::PreferNetwork);
- QCOMPARE(page.navigations.at(2).request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(),
- (int)QNetworkRequest::PreferCache);
-#endif
-}
-
-void tst_QWebEnginePage::loadCachedPage()
-{
-#if !defined(QWEBENGINESETTINGS)
- QSKIP("QWEBENGINESETTINGS");
-#else
- TestPage page;
- QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
- page.settings()->setMaximumPagesInCache(3);
-
- page.load(QUrl("data:text/html,This is first page"));
-
- QTRY_COMPARE(loadSpy.count(), 1);
- QTRY_COMPARE(page.navigations.count(), 1);
-
- QUrl firstPageUrl = page.url();
- page.load(QUrl("data:text/html,This is second page"));
-
- QTRY_COMPARE(loadSpy.count(), 2);
- QTRY_COMPARE(page.navigations.count(), 2);
-
- page.triggerAction(QWebEnginePage::Stop);
- QVERIFY(page.history()->canGoBack());
-
- QSignalSpy urlSpy(&page, SIGNAL(urlChanged(QUrl)));
- QVERIFY(urlSpy.isValid());
-
- page.triggerAction(QWebEnginePage::Back);
- ::waitForSignal(&page, SIGNAL(urlChanged(QUrl)));
- QCOMPARE(urlSpy.size(), 1);
-
- QList<QVariant> arguments1 = urlSpy.takeFirst();
- QCOMPARE(arguments1.at(0).toUrl(), firstPageUrl);
-#endif
-}
-
void tst_QWebEnginePage::backActionUpdate()
{
QWebEngineView view;
diff --git a/tests/quicktestbrowser/DownloadView.qml b/tests/quicktestbrowser/DownloadView.qml
new file mode 100644
index 000000000..4475e183f
--- /dev/null
+++ b/tests/quicktestbrowser/DownloadView.qml
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+import QtWebEngine 1.0
+import QtWebEngine.experimental 1.0
+import QtQuick.Layouts 1.0
+
+Rectangle {
+ id: downloadView
+ color: "lightgray"
+
+ ListModel {
+ id: downloadModel
+ property var downloads: []
+ }
+
+ function append(download) {
+ downloadModel.append(download)
+ downloadModel.downloads.push(download)
+ }
+
+ Component {
+ id: downloadItemDelegate
+
+ Rectangle {
+ width: listView.width
+ height: childrenRect.height
+ anchors.margins: 10
+ radius: 3
+ color: "transparent"
+ border.color: "black"
+ Rectangle {
+ id: progressBar
+
+ property int progress: downloadModel.downloads[index] ? downloadModel.downloads[index].progress : 0
+
+ radius: 3
+ color: width == listView.width ? "green" : "#2b74c7"
+ width: listView.width / 100 * progress
+ height: cancelButton.height
+
+ Behavior on width {
+ SmoothedAnimation { duration: 100 }
+ }
+ }
+ Rectangle {
+ anchors {
+ left: parent.left
+ right: parent.right
+ leftMargin: 20
+ }
+ Label {
+ id: label
+ text: path
+ anchors {
+ verticalCenter: cancelButton.verticalCenter
+ left: parent.left
+ right: cancelButton.left
+ }
+ }
+ Button {
+ id: cancelButton
+ anchors.right: parent.right
+ iconSource: "icons/process-stop.png"
+ onClicked: {
+ var download = downloadModel.downloads[index]
+
+ download.cancel()
+
+ downloadModel.downloads = downloadModel.downloads.filter(function (el) {
+ return el.id !== download.id;
+ });
+ downloadModel.remove(index)
+ }
+ }
+ }
+ }
+
+ }
+ ListView {
+ id: listView
+ anchors {
+ topMargin: 10
+ top: parent.top
+ bottom: parent.bottom
+ horizontalCenter: parent.horizontalCenter
+ }
+ width: parent.width - 20
+ spacing: 5
+
+ model: downloadModel
+ delegate: downloadItemDelegate
+
+ Text {
+ visible: !listView.count
+ horizontalAlignment: Text.AlignHCenter
+ height: 30
+ anchors {
+ top: parent.top
+ left: parent.left
+ right: parent.right
+ }
+ font.pixelSize: 20
+ text: "No active downloads."
+ }
+
+ Rectangle {
+ color: "gray"
+ anchors {
+ bottom: parent.bottom
+ left: parent.left
+ right: parent.right
+ }
+ height: 30
+ Button {
+ id: okButton
+ text: "OK"
+ anchors.centerIn: parent
+ onClicked: {
+ downloadView.visible = false
+ }
+ }
+ }
+ }
+}
diff --git a/tests/quicktestbrowser/FeaturePermissionBar.qml b/tests/quicktestbrowser/FeaturePermissionBar.qml
index dd2e0f714..68ad43195 100644
--- a/tests/quicktestbrowser/FeaturePermissionBar.qml
+++ b/tests/quicktestbrowser/FeaturePermissionBar.qml
@@ -69,12 +69,14 @@ Rectangle {
Layout.fillWidth: true
function textForFeature(feature) {
- if (feature === WebEngineViewExperimental.MediaAudioDevices)
+ if (feature === WebEngineViewExperimental.MediaAudioCapture)
return "your microphone"
- if (feature === WebEngineViewExperimental.MediaVideoDevices)
+ if (feature === WebEngineViewExperimental.MediaVideoCapture)
return "your camera"
- if (feature === WebEngineViewExperimental.MediaAudioVideoDevices)
+ if (feature === WebEngineViewExperimental.MediaAudioVideoCapture)
return "your camera and microphone"
+ if (feature === WebEngineViewExperimental.Geolocation)
+ return "your position"
}
}
diff --git a/tests/quicktestbrowser/ZoomController.qml b/tests/quicktestbrowser/ZoomController.qml
new file mode 100644
index 000000000..a714ed2a9
--- /dev/null
+++ b/tests/quicktestbrowser/ZoomController.qml
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.3
+import QtQuick.Controls 1.2
+import QtQuick.Layouts 1.1
+
+Rectangle {
+ property alias zoomFactor: slider.value ;
+ function zoomIn() {
+ visible = true
+ visibilityTimer.restart()
+ zoomFactor = zoomFactor + 0.25;
+ }
+ function zoomOut() {
+ visible = true
+ visibilityTimer.restart()
+ zoomFactor = zoomFactor - 0.25;
+ }
+ function reset() { zoomFactor = 1.0 }
+
+ width: 220
+ height: 30
+ color: palette.window
+ visible: false
+ radius: 4
+
+ SystemPalette {
+ id: palette
+ }
+ Timer {
+ id: visibilityTimer
+ interval: 3000
+ repeat: false
+ onTriggered: zoomController.visible = false
+ }
+
+ RowLayout {
+ anchors.margins: 4
+ anchors.fill: parent
+ ToolButton {
+ id: plusButton
+ text: '+'
+ onClicked: zoomIn()
+ }
+ ToolButton {
+ text: '\u2014'
+ id: minusButton
+ onClicked: zoomOut()
+ }
+ Slider {
+ id: slider
+ maximumValue: 5.0
+ minimumValue: 0.25
+ Layout.fillWidth: true;
+ stepSize: 0.05
+ value: 1
+ onValueChanged: visibilityTimer.restart()
+ }
+ Button {
+ text: "Reset"
+ onClicked: reset()
+ }
+ }
+}
diff --git a/tests/quicktestbrowser/quicktestbrowser.pro b/tests/quicktestbrowser/quicktestbrowser.pro
index ac8fe74b3..1da197590 100644
--- a/tests/quicktestbrowser/quicktestbrowser.pro
+++ b/tests/quicktestbrowser/quicktestbrowser.pro
@@ -10,6 +10,7 @@ SOURCES = quickwindow.cpp \
OTHER_FILES += ButtonWithMenu.qml \
ContextMenuExtras.qml \
+ DownloadView.qml \
FeaturePermissionBar.qml \
quickwindow.qml
diff --git a/tests/quicktestbrowser/quickwindow.qml b/tests/quicktestbrowser/quickwindow.qml
index 6a5ef3187..d840ac7d0 100644
--- a/tests/quicktestbrowser/quickwindow.qml
+++ b/tests/quicktestbrowser/quickwindow.qml
@@ -39,7 +39,7 @@
****************************************************************************/
import QtQuick 2.1
-import QtWebEngine 1.0
+import QtWebEngine 1.1
import QtWebEngine.experimental 1.0
import QtQuick.Controls 1.0
@@ -73,6 +73,21 @@ ApplicationWindow {
property alias errorPageEnabled: errorPageEnabled.checked;
}
+ WebEngineProfile {
+ id: testProfile
+ storageName: "Test"
+ httpCacheType: httpDiskCacheEnabled.checked ? WebEngineProfile.DiskHttpCache : WebEngineProfile.MemoryHttpCache;
+ onDownloadStarted: {
+ downloadView.visible = true
+ downloadView.append(download)
+ }
+ }
+
+ WebEngineProfile {
+ id: otrProfile
+ offTheRecord: true
+ }
+
// Make sure the Qt.WindowFullscreenButtonHint is set on Mac.
Component.onCompleted: flags = flags | Qt.WindowFullscreenButtonHint
@@ -81,6 +96,12 @@ ApplicationWindow {
StyleItem { id: styleItem }
property bool platformIsMac: styleItem.style == "mac"
+ Action {
+ shortcut: "Ctrl+D"
+ onTriggered: {
+ downloadView.visible = !downloadView.visible
+ }
+ }
Action {
id: focus
@@ -122,6 +143,18 @@ ApplicationWindow {
browserWindow.showNormal()
}
}
+ Action {
+ shortcut: "Ctrl+0"
+ onTriggered: zoomController.reset()
+ }
+ Action {
+ shortcut: "Ctrl+-"
+ onTriggered: zoomController.zoomOut()
+ }
+ Action {
+ shortcut: "Ctrl+="
+ onTriggered: zoomController.zoomIn()
+ }
Menu {
id: backHistoryMenu
@@ -223,6 +256,18 @@ ApplicationWindow {
checked: WebEngine.settings.errorPageEnabled
onCheckedChanged: WebEngine.settings.errorPageEnabled = checked
}
+ MenuItem {
+ id: offTheRecordEnabled
+ text: "Off The Record"
+ checkable: true
+ checked: false
+ }
+ MenuItem {
+ id: httpDiskCacheEnabled
+ text: "HTTP Disk Cache"
+ checkable: true
+ checked: (testProfile.httpCacheType == WebEngineProfile.DiskHttpCache)
+ }
}
}
}
@@ -300,6 +345,7 @@ ApplicationWindow {
WebEngineView {
id: webEngineView
+ profile: offTheRecordEnabled.checked ? otrProfile : testProfile
anchors {
fill: parent
@@ -342,7 +388,7 @@ ApplicationWindow {
var tab = tabs.createEmptyTab()
request.openIn(tab.item.webView)
} else if (request.destination == WebEngineView.NewViewInDialog) {
- var dialog = dialogComponent.createObject()
+ var dialog = dialogComponent.createObject(webEngineView)
request.openIn(dialog.webView)
} else {
var component = Qt.createComponent("quickwindow.qml")
@@ -399,4 +445,23 @@ ApplicationWindow {
}
}
}
+
+ DownloadView {
+ id: downloadView
+ visible: false
+ anchors.fill: parent
+ }
+
+ ZoomController {
+ id: zoomController
+ y: parent.mapFromItem(currentWebView, 0 , 0).y - 4
+ anchors.right: parent.right
+ width: (parent.width > 800) ? parent.width * 0.25 : 220
+ anchors.rightMargin: (parent.width > 400) ? 100 : 0
+ }
+ Binding {
+ target: currentWebView
+ property: "zoomFactor"
+ value: zoomController.zoomFactor
+ }
}
diff --git a/tests/quicktestbrowser/resources.qrc b/tests/quicktestbrowser/resources.qrc
index cdc3d2304..3c9fd5dd7 100644
--- a/tests/quicktestbrowser/resources.qrc
+++ b/tests/quicktestbrowser/resources.qrc
@@ -4,6 +4,8 @@
<file>ContextMenuExtras.qml</file>
<file>FeaturePermissionBar.qml</file>
<file>ButtonWithMenu.qml</file>
+ <file>DownloadView.qml</file>
+ <file>ZoomController.qml</file>
</qresource>
<qresource prefix="icons">
<!-- To the risk of this breaking more often, do not duplicate the resources since this application won't be deployed -->
diff --git a/tests/quicktestbrowser/util.h b/tests/quicktestbrowser/util.h
index bad41d6a7..85db8c25b 100644
--- a/tests/quicktestbrowser/util.h
+++ b/tests/quicktestbrowser/util.h
@@ -50,7 +50,7 @@ QUrl urlFromUserInput(const QString& userInput)
{
QFileInfo fileInfo(userInput);
if (fileInfo.exists())
- return QUrl(fileInfo.absoluteFilePath());
+ return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
return QUrl::fromUserInput(userInput);
}
diff --git a/tools/qmake/mkspecs/features/functions.prf b/tools/qmake/mkspecs/features/functions.prf
index 4c2547d57..338a9ec27 100644
--- a/tools/qmake/mkspecs/features/functions.prf
+++ b/tools/qmake/mkspecs/features/functions.prf
@@ -73,7 +73,7 @@ defineReplace(findMocables) {
for (file, input): \
infiles += $$absolute_path($$file, $$_PRO_FILE_PWD_)
mocables = $$system("python $$QTWEBENGINE_ROOT/tools/buildscripts/find-mocables $$infiles")
- mocables = $$replace(mocables, $$_PRO_FILE_PWD_/, '')
+ mocables = $$replace(mocables, $$re_escape($${_PRO_FILE_PWD_}/), '')
return($$mocables)
}
@@ -87,8 +87,10 @@ defineReplace(findIncludedMocFiles) {
defineReplace(mocOutput) {
out = $$1
# The order is important, since the output of the second replace would end up accidentaly transformed by the first one
- out = $$replace(out, ^(.*)($$join(QMAKE_EXT_CPP,|)), $${QMAKE_CPP_MOD_MOC}\\1$${QMAKE_EXT_CPP_MOC})
- out = $$replace(out, ^(.*)($$join(QMAKE_EXT_H,|)), $${QMAKE_H_MOD_MOC}\\1$${first(QMAKE_EXT_CPP)})
+ for(ext, $$list($${QMAKE_EXT_CPP})): \
+ out = $$replace(out, ^(.*)($$re_escape($${ext})), $${QMAKE_CPP_MOD_MOC}\\1$${QMAKE_EXT_CPP_MOC})
+ for(ext, $$list($${QMAKE_EXT_H})): \
+ out = $$replace(out, ^(.*)($$re_escape($${ext})), $${QMAKE_H_MOD_MOC}\\1$${first(QMAKE_EXT_CPP)})
return($$out)
}
diff --git a/tools/scripts/take_snapshot.py b/tools/scripts/take_snapshot.py
index 3696b9a7a..3db3bac6c 100755
--- a/tools/scripts/take_snapshot.py
+++ b/tools/scripts/take_snapshot.py
@@ -61,6 +61,7 @@ def isInGitBlacklist(file_path):
False
if ( '.gitignore' in file_path
or '.gitmodules' in file_path
+ or '.gitattributes' in file_path
or '.DEPS' in file_path ):
return True
@@ -108,13 +109,17 @@ def isInChromiumBlacklist(file_path):
not file_path.endswith('version.py') and
not file_path.endswith('.grd') and
not file_path.endswith('.grdp') and
- not file_path.endswith('.json'))
+ not file_path.endswith('.json') and
+ not file_path.endswith('chrome_version.rc.version'))
or file_path.startswith('chrome_frame')
or file_path.startswith('chromeos')
or file_path.startswith('cloud_print')
or (file_path.startswith('components') and
not file_path.startswith('components/tracing') and
- not file_path.startswith('components/visitedlink'))
+ not file_path.startswith('components/visitedlink') and
+ not file_path.startswith('components/error_page') and
+ not file_path.endswith('.grdp') and
+ not 'components_strings' in file_path)
or file_path.startswith('content/public/android/java')
or file_path.startswith('content/shell')
or file_path.startswith('courgette')
@@ -157,9 +162,11 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('third_party/cros_dbus_cplusplus')
or file_path.startswith('third_party/cros_system_api')
or file_path.startswith('third_party/cygwin')
+ or file_path.startswith('third_party/cython')
or file_path.startswith('third_party/elfutils')
or file_path.startswith('third_party/eyesfree')
or file_path.startswith('third_party/findbugs')
+ or file_path.startswith('third_party/google_input_tools')
or file_path.startswith('third_party/gperf')
or file_path.startswith('third_party/gnu_binutils')
or file_path.startswith('third_party/gtk+')
@@ -173,6 +180,7 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('third_party/instrumented_libraries')
or file_path.startswith('third_party/jarjar')
or file_path.startswith('third_party/jsr-305/src')
+ or file_path.startswith('third_party/junit')
or file_path.startswith('third_party/libphonenumber')
or file_path.startswith('third_party/libaddressinput')
or file_path.startswith('third_party/libc++')
@@ -182,6 +190,7 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('third_party/markdown')
or file_path.startswith('third_party/mingw-w64')
or file_path.startswith('third_party/nacl_sdk_binaries')
+ or file_path.startswith('third_party/polymer')
or file_path.startswith('third_party/pdfsqueeze')
or file_path.startswith('third_party/pefile')
or file_path.startswith('third_party/perl')
@@ -248,7 +257,7 @@ def clearDirectory(directory):
os.chdir(directory)
print 'clearing the directory:' + directory
for direntry in os.listdir(directory):
- if not direntry == '.git':
+ if not direntry == '.git' and os.path.isdir(direntry):
print 'clearing:' + direntry
shutil.rmtree(direntry)
os.chdir(currentDir)
@@ -304,6 +313,12 @@ if not commandNotFound:
if commandNotFound or dos2unixVersion < StrictVersion('6.0.6'):
raise Exception("You need dos2unix version 6.0.6 minimum.")
+os.chdir(third_party)
+ignore_case_setting = subprocess.Popen(['git', 'config', '--get', 'core.ignorecase'], stdout=subprocess.PIPE).communicate()[0]
+if 'true' in ignore_case_setting:
+ raise Exception("Your 3rdparty repository is configured to ignore case. "
+ "A snapshot created with these settings would cause problems on case sensitive file systems.")
+
clearDirectory(third_party)
exportNinja()