summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/webengine/quicknanobrowser/quickwindow.qml4
-rw-r--r--examples/webengine/quicknanobrowser/util.h2
-rw-r--r--examples/webenginewidgets/browser/browsermainwindow.cpp4
-rw-r--r--examples/webenginewidgets/browser/browsermainwindow.h2
-rw-r--r--examples/webenginewidgets/browser/data/defaultbookmarks.xbel11
-rw-r--r--examples/webenginewidgets/browser/featurepermissionbar.cpp6
-rw-r--r--examples/webenginewidgets/browser/settings.cpp2
-rw-r--r--examples/webenginewidgets/browser/webview.cpp5
m---------src/3rdparty0
-rw-r--r--src/core/browser_context_adapter.cpp14
-rw-r--r--src/core/browser_context_adapter.h3
-rw-r--r--src/core/browser_context_qt.cpp9
-rw-r--r--src/core/browser_context_qt.h1
-rw-r--r--src/core/content_browser_client_qt.cpp17
-rw-r--r--src/core/content_browser_client_qt.h7
-rw-r--r--src/core/gyp_run.pro3
-rw-r--r--src/core/network_delegate_qt.cpp3
-rw-r--r--src/core/renderer/content_renderer_client_qt.cpp57
-rw-r--r--src/core/renderer/content_renderer_client_qt.h6
-rw-r--r--src/core/resource_bundle_qt.cpp9
-rw-r--r--src/core/type_conversion.h4
-rw-r--r--src/core/url_request_context_getter_qt.cpp9
-rw-r--r--src/core/url_request_context_getter_qt.h5
-rw-r--r--src/core/web_contents_adapter.cpp4
-rw-r--r--src/core/web_engine_context.cpp1
-rw-r--r--src/core/web_engine_settings.cpp2
-rw-r--r--src/core/web_engine_settings.h1
-rw-r--r--src/webengine/api/qquickwebenginesettings.cpp15
-rw-r--r--src/webengine/api/qquickwebenginesettings_p.h4
-rw-r--r--src/webengine/api/qquickwebengineview.cpp5
-rw-r--r--src/webengine/api/qquickwebengineview_p.h4
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h1
-rw-r--r--src/webengine/api/qtwebengineglobal.cpp17
-rw-r--r--src/webengine/plugin/plugins.qmltypes164
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp24
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h16
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h2
-rw-r--r--src/webenginewidgets/api/qwebenginesettings.cpp2
-rw-r--r--src/webenginewidgets/api/qwebenginesettings.h3
-rw-r--r--src/webenginewidgets/doc/snippets/qtwebengine_qwebengineview_snippet.cpp8
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc8
-rw-r--r--src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc1
-rw-r--r--tests/auto/quick/html/basic_page.html6
-rw-r--r--tests/auto/quick/html/basic_page2.html1
-rw-r--r--tests/auto/quick/html/direct-image-compositing.html66
-rw-r--r--tests/auto/quick/html/inputmethod.html11
-rw-r--r--tests/auto/quick/html/resources/simple_image.pngbin0 -> 10585 bytes
-rw-r--r--tests/auto/quick/html/scroll.html29
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadUrl.qml4
-rw-r--r--tests/auto/quick/qmltests/qmltests.pro2
-rw-r--r--tests/auto/quick/qquickwebengineview/qquickwebengineview.pro6
-rw-r--r--tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp422
-rw-r--r--tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp17
-rw-r--r--tests/auto/quick/quick.pro1
-rw-r--r--tests/auto/quick/shared/testwindow.h59
-rw-r--r--tests/auto/quick/shared/util.h125
-rw-r--r--tests/auto/quick/tests.pri4
-rw-r--r--tests/auto/widgets/qwebengineframe/tst_qwebengineframe.cpp45
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp72
-rw-r--r--tests/quicktestbrowser/quickwindow.qml8
-rwxr-xr-xtools/buildscripts/repack_locales.py10
-rw-r--r--tools/qmake/mkspecs/features/functions.prf44
62 files changed, 1240 insertions, 157 deletions
diff --git a/examples/webengine/quicknanobrowser/quickwindow.qml b/examples/webengine/quicknanobrowser/quickwindow.qml
index c73951046..b954629fb 100644
--- a/examples/webengine/quicknanobrowser/quickwindow.qml
+++ b/examples/webengine/quicknanobrowser/quickwindow.qml
@@ -51,8 +51,8 @@ ApplicationWindow {
function load(url) { currentWebView.url = url }
property Item currentWebView: tabs.currentIndex < tabs.count ? tabs.getTab(tabs.currentIndex).item : null
- height: 600
- width: 800
+ width: 1300
+ height: 900
visible: true
title: currentWebView && currentWebView.title
diff --git a/examples/webengine/quicknanobrowser/util.h b/examples/webengine/quicknanobrowser/util.h
index 85db8c25b..ca0f5f1d5 100644
--- a/examples/webengine/quicknanobrowser/util.h
+++ b/examples/webengine/quicknanobrowser/util.h
@@ -66,7 +66,7 @@ QUrl startupUrl()
if (ret.isValid())
return ret;
}
- return QUrl(QStringLiteral("http://qt-project.org/"));
+ return QUrl(QStringLiteral("http://qt.io/"));
}
diff --git a/examples/webenginewidgets/browser/browsermainwindow.cpp b/examples/webenginewidgets/browser/browsermainwindow.cpp
index 587e66490..cce603cff 100644
--- a/examples/webenginewidgets/browser/browsermainwindow.cpp
+++ b/examples/webenginewidgets/browser/browsermainwindow.cpp
@@ -88,6 +88,8 @@ InvokeWrapper<Arg, R, C> invoke(R *receiver, void (C::*memberFun)(Arg))
return wrapper;
}
+const char *BrowserMainWindow::defaultHome = "http://qt.io/";
+
BrowserMainWindow::BrowserMainWindow(QWidget *parent, Qt::WindowFlags flags)
: QMainWindow(parent, flags)
, m_tabWidget(new TabWidget(this))
@@ -825,7 +827,7 @@ void BrowserMainWindow::slotHome()
{
QSettings settings;
settings.beginGroup(QLatin1String("MainWindow"));
- QString home = settings.value(QLatin1String("home"), QLatin1String("http://qt-project.org/")).toString();
+ QString home = settings.value(QLatin1String("home"), QLatin1String(defaultHome)).toString();
loadPage(home);
}
diff --git a/examples/webenginewidgets/browser/browsermainwindow.h b/examples/webenginewidgets/browser/browsermainwindow.h
index 6743d8e79..da767e35e 100644
--- a/examples/webenginewidgets/browser/browsermainwindow.h
+++ b/examples/webenginewidgets/browser/browsermainwindow.h
@@ -70,6 +70,8 @@ public:
~BrowserMainWindow();
QSize sizeHint() const;
+ static const char *defaultHome;
+
public:
TabWidget *tabWidget() const;
WebView *currentTab() const;
diff --git a/examples/webenginewidgets/browser/data/defaultbookmarks.xbel b/examples/webenginewidgets/browser/data/defaultbookmarks.xbel
index 7a95e36b3..a981d2de2 100644
--- a/examples/webenginewidgets/browser/data/defaultbookmarks.xbel
+++ b/examples/webenginewidgets/browser/data/defaultbookmarks.xbel
@@ -3,18 +3,12 @@
<xbel version="1.0">
<folder folded="yes">
<title>Bookmarks Bar</title>
- <bookmark href="http://qt-project.org/">
+ <bookmark href="http://qt.io/">
<title>Qt Home Page</title>
</bookmark>
- <bookmark href="http://webkit.org/">
- <title>WebKit.org</title>
- </bookmark>
<bookmark href="http://qt-project.org/doc/">
<title>Qt Documentation</title>
</bookmark>
- <bookmark href="http://qt-project.org/quarterly/">
- <title>Qt Quarterly</title>
- </bookmark>
<bookmark href="http://planet.qt-project.org/">
<title>Qt Blog</title>
</bookmark>
@@ -27,6 +21,9 @@
<bookmark href="http://qt-project.org/wiki/OnlineCommunities/">
<title>Online Communities</title>
</bookmark>
+ <bookmark href="http://www.chromium.org/">
+ <title>The Chromium Projects</title>
+ </bookmark>
<bookmark href="http://xkcd.com/">
<title>xkcd</title>
</bookmark>
diff --git a/examples/webenginewidgets/browser/featurepermissionbar.cpp b/examples/webenginewidgets/browser/featurepermissionbar.cpp
index 2cc9907bd..98f19ad1f 100644
--- a/examples/webenginewidgets/browser/featurepermissionbar.cpp
+++ b/examples/webenginewidgets/browser/featurepermissionbar.cpp
@@ -56,11 +56,11 @@ static QString textForPermissionType(QWebEnginePage::Feature type)
return QObject::tr("desktop notifications");
case QWebEnginePage::Geolocation:
return QObject::tr("your position");
- case QWebEnginePage::MediaAudioDevices:
+ case QWebEnginePage::MediaAudioCapture:
return QObject::tr("your microphone");
- case QWebEnginePage::MediaVideoDevices:
+ case QWebEnginePage::MediaVideoCapture:
return QObject::tr("your camera");
- case QWebEnginePage::MediaAudioVideoDevices:
+ case QWebEnginePage::MediaAudioVideoCapture:
return QObject::tr("your camera and microphone");
default:
Q_UNREACHABLE();
diff --git a/examples/webenginewidgets/browser/settings.cpp b/examples/webenginewidgets/browser/settings.cpp
index d89c49353..835e7a9b5 100644
--- a/examples/webenginewidgets/browser/settings.cpp
+++ b/examples/webenginewidgets/browser/settings.cpp
@@ -95,7 +95,7 @@ void SettingsDialog::loadFromSettings()
{
QSettings settings;
settings.beginGroup(QLatin1String("MainWindow"));
- QString defaultHome = QLatin1String("http://qt-project.org/");
+ const QString defaultHome = QLatin1String(BrowserMainWindow::defaultHome);
homeLineEdit->setText(settings.value(QLatin1String("home"), defaultHome).toString());
settings.endGroup();
diff --git a/examples/webenginewidgets/browser/webview.cpp b/examples/webenginewidgets/browser/webview.cpp
index 07027fe3a..9b42f2ab2 100644
--- a/examples/webenginewidgets/browser/webview.cpp
+++ b/examples/webenginewidgets/browser/webview.cpp
@@ -113,7 +113,10 @@ bool WebPage::certificateError(const QWebEngineCertificateError &error)
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Warning);
msgBox.setText(error.errorDescription());
- msgBox.setInformativeText(tr("If you wish so, you may continue with an unverified certicate. Accepting an unverified certicate means you may not be connected with the host you tried to connect to.\nDo you wish to override the security check and continue?"));
+ msgBox.setInformativeText(tr("If you wish so, you may continue with an unverified certificate. "
+ "Accepting an unverified certificate means "
+ "you may not be connected with the host you tried to connect to.\n"
+ "Do you wish to override the security check and continue?"));
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgBox.setDefaultButton(QMessageBox::No);
return msgBox.exec() == QMessageBox::Yes;
diff --git a/src/3rdparty b/src/3rdparty
-Subproject 2c3ccc7994980d954ec0188ea3fa3d27424ef32
+Subproject 0dcd4e35086a90f643bb721fad1ef786f5fff8b
diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp
index 2d56dcff7..b06515c2f 100644
--- a/src/core/browser_context_adapter.cpp
+++ b/src/core/browser_context_adapter.cpp
@@ -78,12 +78,24 @@ BrowserContextAdapter* BrowserContextAdapter::offTheRecordContext()
return WebEngineContext::current()->offTheRecordBrowserContext();
}
-QString BrowserContextAdapter::path() const
+QString BrowserContextAdapter::dataPath() 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 dataLocation;
}
+
+QString BrowserContextAdapter::cachePath() 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 cacheLocation;
+}
diff --git a/src/core/browser_context_adapter.h b/src/core/browser_context_adapter.h
index 99022f98d..362ab79ee 100644
--- a/src/core/browser_context_adapter.h
+++ b/src/core/browser_context_adapter.h
@@ -58,7 +58,8 @@ public:
BrowserContextQt *browserContext();
bool isOffTheRecord() const { return m_offTheRecord; }
- QString path() const;
+ QString dataPath() const;
+ QString cachePath() const;
protected:
explicit BrowserContextAdapter(bool offTheRecord = false);
diff --git a/src/core/browser_context_qt.cpp b/src/core/browser_context_qt.cpp
index 4c17171d4..8dc4a3da2 100644
--- a/src/core/browser_context_qt.cpp
+++ b/src/core/browser_context_qt.cpp
@@ -62,7 +62,12 @@ BrowserContextQt::~BrowserContextQt()
base::FilePath BrowserContextQt::GetPath() const
{
- return base::FilePath(toFilePathString(m_adapter->path()));
+ return base::FilePath(toFilePathString(m_adapter->dataPath()));
+}
+
+base::FilePath BrowserContextQt::GetCachePath() const
+{
+ return base::FilePath(toFilePathString(m_adapter->cachePath()));
}
bool BrowserContextQt::IsOffTheRecord() const
@@ -123,7 +128,7 @@ content::PushMessagingService *BrowserContextQt::GetPushMessagingService()
net::URLRequestContextGetter *BrowserContextQt::CreateRequestContext(content::ProtocolHandlerMap *protocol_handlers)
{
- url_request_getter_ = new URLRequestContextGetterQt(GetPath(), 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());
return url_request_getter_.get();
}
diff --git a/src/core/browser_context_qt.h b/src/core/browser_context_qt.h
index 4e18c1a4a..634db6f3f 100644
--- a/src/core/browser_context_qt.h
+++ b/src/core/browser_context_qt.h
@@ -53,6 +53,7 @@ public:
virtual ~BrowserContextQt();
virtual base::FilePath GetPath() const Q_DECL_OVERRIDE;
+ base::FilePath GetCachePath() const;
virtual bool IsOffTheRecord() const Q_DECL_OVERRIDE;
virtual net::URLRequestContextGetter *GetRequestContext() Q_DECL_OVERRIDE;
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index f10dd7500..2aca88d6a 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -371,3 +371,20 @@ void ContentBrowserClientQt::AllowCertificateError(int render_process_id, int re
QExplicitlySharedDataPointer<CertificateErrorController> errorController(new CertificateErrorController(new CertificateErrorControllerPrivate(cert_error, ssl_info, request_url, resource_type, overridable, strict_enforcement, callback)));
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)
+{
+ 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);
+}
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index 3a70e2427..ed328d1bf 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -90,6 +90,13 @@ 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;
virtual net::URLRequestContextGetter *CreateRequestContext(content::BrowserContext *content_browser_context, content::ProtocolHandlerMap *protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptorss) Q_DECL_OVERRIDE;
diff --git a/src/core/gyp_run.pro b/src/core/gyp_run.pro
index f79972a2e..137b600b9 100644
--- a/src/core/gyp_run.pro
+++ b/src/core/gyp_run.pro
@@ -61,6 +61,7 @@ cross_compile {
!isEmpty(MARMV) {
MARMV = $$split(MARMV,)
MARMV = $$member(MARMV, 0)
+ lessThan(MARMV, 6): error("$$MARCH architecture is not supported")
GYP_ARGS += "-D arm_version=\"$$MARMV\""
}
@@ -69,7 +70,7 @@ cross_compile {
# If the toolchain does not explicitly specify to use NEON instructions
# we use arm_neon_optional for ARMv7 and newer and let chromium decide
# about the mfpu option.
- contains(MFPU, "neon"): GYP_ARGS += "-D arm_fpu=\"$$MFPU\" -D arm_neon=1"
+ contains(MFPU, "neon")|contains(MFPU, "neon-vfpv4"): GYP_ARGS += "-D arm_fpu=\"$$MFPU\" -D arm_neon=1"
else:!lessThan(MARMV, 7): GYP_ARGS += "-D arm_neon=0 -D arm_neon_optional=1"
else: GYP_ARGS += "-D arm_fpu=\"$$MFPU\" -D arm_neon=0 -D arm_neon_optional=0"
}
diff --git a/src/core/network_delegate_qt.cpp b/src/core/network_delegate_qt.cpp
index 81ab4b6bc..f14d2cb39 100644
--- a/src/core/network_delegate_qt.cpp
+++ b/src/core/network_delegate_qt.cpp
@@ -130,6 +130,9 @@ void NetworkDelegateQt::CompleteURLRequestOnIOThread(net::URLRequest *request,
if (!m_activeRequests.contains(request))
return;
+ if (request->status().status() == net::URLRequestStatus::CANCELED)
+ return;
+
int error = net::OK;
switch (navigationRequestAction) {
case WebContentsAdapterClient::AcceptRequest:
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
index 6d4315b64..bfc5c389f 100644
--- a/src/core/renderer/content_renderer_client_qt.cpp
+++ b/src/core/renderer/content_renderer_client_qt.cpp
@@ -39,6 +39,7 @@
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/localized_error.h"
#include "components/visitedlink/renderer/visitedlink_slave.h"
+#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
#include "net/base/net_errors.h"
@@ -46,6 +47,7 @@
#include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/webui/jstemplate_builder.h"
+#include "webkit/common/webpreferences.h"
#include "renderer/qt_render_view_observer.h"
@@ -84,37 +86,40 @@ bool ContentRendererClientQt::HasErrorPage(int httpStatusCode, std::string *erro
return true;
}
+bool ContentRendererClientQt::ShouldSuppressErrorPage(content::RenderFrame *frame, const GURL &)
+{
+ return !(frame->GetWebkitPreferences().enable_error_page);
+}
+
// To tap into the chromium localized strings. Ripped from the chrome layer (highly simplified).
-void ContentRendererClientQt::GetNavigationErrorStrings(content::RenderView* render_view, blink::WebFrame *frame, const blink::WebURLRequest &failed_request, const blink::WebURLError &error, std::string *error_html, base::string16 *error_description)
+void ContentRendererClientQt::GetNavigationErrorStrings(content::RenderView* renderView, blink::WebFrame *frame, const blink::WebURLRequest &failedRequest, const blink::WebURLError &error, std::string *errorHtml, base::string16 *errorDescription)
{
Q_UNUSED(frame)
-
- const bool isPost = EqualsASCII(failed_request.httpMethod(), "POST");
-
- if (error_html) {
- // Use a local error page.
- int resource_id;
- base::DictionaryValue error_strings;
-
- const std::string locale = content::RenderThread::Get()->GetLocale();
- // TODO(elproxy): We could potentially get better diagnostics here by first calling NetErrorHelper::GetErrorStringsForDnsProbe
- LocalizedError::GetStrings(error.reason, error.domain.utf8(),
- error.unreachableURL, isPost, error.staleCopyInCache && !isPost,
- locale, render_view->GetAcceptLanguages(), scoped_ptr<LocalizedError::ErrorPageParams>(),
- &error_strings);
- resource_id = IDR_NET_ERROR_HTML;
-
-
- const base::StringPiece template_html(ui::ResourceBundle::GetSharedInstance().GetRawDataResource(resource_id));
- if (template_html.empty())
- NOTREACHED() << "unable to load template. ID: " << resource_id;
- else // "t" is the id of the templates root node.
- *error_html = webui::GetTemplatesHtml(template_html, &error_strings, "t");
+ const bool isPost = EqualsASCII(failedRequest.httpMethod(), "POST");
+
+ if (errorHtml) {
+ // Use a local error page.
+ int resourceId;
+ base::DictionaryValue errorStrings;
+
+ const std::string locale = content::RenderThread::Get()->GetLocale();
+ // TODO(elproxy): We could potentially get better diagnostics here by first calling
+ // NetErrorHelper::GetErrorStringsForDnsProbe, but that one is harder to untangle.
+ LocalizedError::GetStrings(error.reason, error.domain.utf8(), error.unreachableURL, isPost
+ , error.staleCopyInCache && !isPost, locale, renderView->GetAcceptLanguages()
+ , scoped_ptr<LocalizedError::ErrorPageParams>(), &errorStrings);
+ resourceId = IDR_NET_ERROR_HTML;
+
+
+ const base::StringPiece template_html(ui::ResourceBundle::GetSharedInstance().GetRawDataResource(resourceId));
+ if (template_html.empty())
+ NOTREACHED() << "unable to load template. ID: " << resourceId;
+ else // "t" is the id of the templates root node.
+ *errorHtml = webui::GetTemplatesHtml(template_html, &errorStrings, "t");
}
- if (error_description) {
- *error_description = LocalizedError::GetErrorDetails(error, isPost);
- }
+ if (errorDescription)
+ *errorDescription = LocalizedError::GetErrorDetails(error, isPost);
}
unsigned long long ContentRendererClientQt::VisitedLinkHash(const char *canonicalUrl, size_t length)
diff --git a/src/core/renderer/content_renderer_client_qt.h b/src/core/renderer/content_renderer_client_qt.h
index 386495e20..4e3c70cf8 100644
--- a/src/core/renderer/content_renderer_client_qt.h
+++ b/src/core/renderer/content_renderer_client_qt.h
@@ -50,10 +50,10 @@ public:
virtual void RenderThreadStarted() Q_DECL_OVERRIDE;
virtual void RenderViewCreated(content::RenderView *render_view) Q_DECL_OVERRIDE;
- virtual bool ShouldSuppressErrorPage(content::RenderFrame *, const GURL &) Q_DECL_OVERRIDE { return false; }
+ virtual bool ShouldSuppressErrorPage(content::RenderFrame *, const GURL &) Q_DECL_OVERRIDE;
virtual bool HasErrorPage(int httpStatusCode, std::string *errorDomain) Q_DECL_OVERRIDE;
- virtual void GetNavigationErrorStrings(content::RenderView* render_view, blink::WebFrame* frame, const blink::WebURLRequest& failed_request
- , const blink::WebURLError& error, std::string* error_html, base::string16* error_description) Q_DECL_OVERRIDE;
+ virtual void GetNavigationErrorStrings(content::RenderView* renderView, blink::WebFrame* frame, const blink::WebURLRequest& failedRequest
+ , const blink::WebURLError& error, std::string* errorHtml, base::string16* errorDescription) Q_DECL_OVERRIDE;
virtual unsigned long long VisitedLinkHash(const char *canonicalUrl, size_t length) Q_DECL_OVERRIDE;
virtual bool IsLinkVisited(unsigned long long linkHash) Q_DECL_OVERRIDE;
diff --git a/src/core/resource_bundle_qt.cpp b/src/core/resource_bundle_qt.cpp
index 2487cdbd1..d69ae05e1 100644
--- a/src/core/resource_bundle_qt.cpp
+++ b/src/core/resource_bundle_qt.cpp
@@ -47,15 +47,6 @@ void ResourceBundle::LoadCommonResources()
AddDataPackFromPath(WebEngineLibraryInfo::getPath(QT_RESOURCES_PAK), SCALE_FACTOR_100P);
}
-// As GetLocaleFilePath is excluded for Mac in resource_bundle.cc,
-// we have to add a replacement for it using the inverted logic.
-#if defined(OS_MACOSX)
-base::FilePath ResourceBundle::GetLocaleFilePath(const std::string& /*app_locale*/, bool /*test_file_exists*/)
-{
- return base::FilePath();
-}
-#endif
-
gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id, ImageRTL rtl)
{
LOG(WARNING) << "Unable to load image with id " << resource_id;
diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h
index 8d33b5ffa..9d9cdd675 100644
--- a/src/core/type_conversion.h
+++ b/src/core/type_conversion.h
@@ -121,11 +121,13 @@ inline QColor toQt(const SkColor &c)
inline QMatrix4x4 toQt(const SkMatrix44 &m)
{
- return QMatrix4x4(
+ QMatrix4x4 qtMatrix(
m.get(0, 0), m.get(0, 1), m.get(0, 2), m.get(0, 3),
m.get(1, 0), m.get(1, 1), m.get(1, 2), m.get(1, 3),
m.get(2, 0), m.get(2, 1), m.get(2, 2), m.get(2, 3),
m.get(3, 0), m.get(3, 1), m.get(3, 2), m.get(3, 3));
+ qtMatrix.optimize();
+ return qtMatrix;
}
inline QDateTime toQt(base::Time time)
diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp
index 8d44d0ad1..8ec600a85 100644
--- a/src/core/url_request_context_getter_qt.cpp
+++ b/src/core/url_request_context_getter_qt.cpp
@@ -69,9 +69,10 @@ static const char kQrcSchemeQt[] = "qrc";
using content::BrowserThread;
-URLRequestContextGetterQt::URLRequestContextGetterQt(const base::FilePath &basePath, content::ProtocolHandlerMap *protocolHandlers)
+URLRequestContextGetterQt::URLRequestContextGetterQt(const base::FilePath &dataPath, const base::FilePath &cachePath, content::ProtocolHandlerMap *protocolHandlers)
: m_ignoreCertificateErrors(false)
- , m_basePath(basePath)
+ , m_dataPath(dataPath)
+ , m_cachePath(cachePath)
{
std::swap(m_protocolHandlers, *protocolHandlers);
@@ -93,7 +94,7 @@ net::URLRequestContext *URLRequestContextGetterQt::GetURLRequestContext()
m_urlRequestContext->set_network_delegate(m_networkDelegate.get());
- base::FilePath cookiesPath = m_basePath.Append(FILE_PATH_LITERAL("Cookies"));
+ 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);
@@ -119,7 +120,7 @@ net::URLRequestContext *URLRequestContextGetterQt::GetURLRequestContext()
net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get()));
m_storage->set_http_server_properties(scoped_ptr<net::HttpServerProperties>(new net::HttpServerPropertiesImpl));
- base::FilePath cache_path = m_basePath.Append(FILE_PATH_LITERAL("Cache"));
+ base::FilePath cache_path = m_cachePath.Append(FILE_PATH_LITERAL("Cache"));
net::HttpCache::DefaultBackend* main_backend =
new net::HttpCache::DefaultBackend(
net::DISK_CACHE,
diff --git a/src/core/url_request_context_getter_qt.h b/src/core/url_request_context_getter_qt.h
index 50335291e..6c9ac6d59 100644
--- a/src/core/url_request_context_getter_qt.h
+++ b/src/core/url_request_context_getter_qt.h
@@ -58,7 +58,7 @@ class ProxyConfigService;
class URLRequestContextGetterQt : public net::URLRequestContextGetter {
public:
- explicit URLRequestContextGetterQt(const base::FilePath &, content::ProtocolHandlerMap *protocolHandlers);
+ explicit URLRequestContextGetterQt(const base::FilePath &, const base::FilePath &, content::ProtocolHandlerMap *protocolHandlers);
virtual net::URLRequestContext *GetURLRequestContext() Q_DECL_OVERRIDE;
virtual scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() const Q_DECL_OVERRIDE;
@@ -67,7 +67,8 @@ private:
virtual ~URLRequestContextGetterQt() {}
bool m_ignoreCertificateErrors;
- base::FilePath m_basePath;
+ base::FilePath m_dataPath;
+ base::FilePath m_cachePath;
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 0f71bbbee..dd9f800db 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -448,7 +448,7 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT
QUrl WebContentsAdapter::activeUrl() const
{
Q_D(const WebContentsAdapter);
- return toQt(d->webContents->GetVisibleURL());
+ return toQt(d->webContents->GetLastCommittedURL());
}
QUrl WebContentsAdapter::requestedUrl() const
@@ -612,6 +612,8 @@ void WebContentsAdapter::serializeNavigationHistory(QDataStream &output)
void WebContentsAdapter::setZoomFactor(qreal factor)
{
Q_D(WebContentsAdapter);
+ if (factor < content::kMinimumZoomFactor || factor > content::kMaximumZoomFactor)
+ return;
content::HostZoomMap::SetZoomLevel(d->webContents.get(), content::ZoomFactorToZoomLevel(static_cast<double>(factor)));
}
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index c2e2da740..d4659f0be 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -147,6 +147,7 @@ WebEngineContext::WebEngineContext()
parsedCommandLine->AppendSwitch(switches::kEnableDelegatedRenderer);
parsedCommandLine->AppendSwitch(switches::kEnableThreadedCompositing);
parsedCommandLine->AppendSwitch(switches::kInProcessGPU);
+ parsedCommandLine->AppendSwitch(switches::kDisableDesktopNotifications);
#if defined(OS_WIN)
parsedCommandLine->AppendSwitch(switches::kDisableD3D11);
diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp
index 03f746f41..9b070d3b2 100644
--- a/src/core/web_engine_settings.cpp
+++ b/src/core/web_engine_settings.cpp
@@ -213,6 +213,7 @@ void WebEngineSettings::initDefaults()
m_attributes.insert(LocalContentCanAccessFileUrls, true);
m_attributes.insert(HyperlinkAuditingEnabled, false);
m_attributes.insert(ScrollAnimatorEnabled, false);
+ m_attributes.insert(ErrorPageEnabled, true);
// Default fonts
QFont defaultFont;
@@ -276,6 +277,7 @@ void WebEngineSettings::applySettingsToWebPreferences(WebPreferences *prefs)
prefs->allow_file_access_from_file_urls = testAttribute(LocalContentCanAccessFileUrls);
prefs->hyperlink_auditing_enabled = testAttribute(HyperlinkAuditingEnabled);
prefs->enable_scroll_animator = testAttribute(ScrollAnimatorEnabled);
+ prefs->enable_error_page = testAttribute(ErrorPageEnabled);
// Fonts settings.
prefs->standard_font_family_map[webkit_glue::kCommonScript] = toString16(fontFamily(StandardFont));
diff --git a/src/core/web_engine_settings.h b/src/core/web_engine_settings.h
index b8d661fcc..c098f8ef4 100644
--- a/src/core/web_engine_settings.h
+++ b/src/core/web_engine_settings.h
@@ -74,6 +74,7 @@ public:
LocalContentCanAccessFileUrls,
HyperlinkAuditingEnabled,
ScrollAnimatorEnabled,
+ ErrorPageEnabled,
};
// Must match the values from the public API in qwebenginesettings.h.
diff --git a/src/webengine/api/qquickwebenginesettings.cpp b/src/webengine/api/qquickwebenginesettings.cpp
index aa6290aa8..7f36bad5e 100644
--- a/src/webengine/api/qquickwebenginesettings.cpp
+++ b/src/webengine/api/qquickwebenginesettings.cpp
@@ -140,6 +140,12 @@ bool QQuickWebEngineSettings::hyperlinkAuditingEnabled() const
return d->coreSettings->testAttribute(WebEngineSettings::HyperlinkAuditingEnabled);
}
+bool QQuickWebEngineSettings::errorPageEnabled() const
+{
+ Q_D(const QQuickWebEngineSettings);
+ return d->coreSettings->testAttribute(WebEngineSettings::ErrorPageEnabled);
+}
+
QString QQuickWebEngineSettings::defaultTextEncoding() const
{
Q_D(const QQuickWebEngineSettings);
@@ -239,6 +245,15 @@ void QQuickWebEngineSettings::setHyperlinkAuditingEnabled(bool on)
Q_EMIT hyperlinkAuditingEnabledChanged(on);
}
+void QQuickWebEngineSettings::setErrorPageEnabled(bool on)
+{
+ Q_D(QQuickWebEngineSettings);
+ bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::ErrorPageEnabled);
+ d->coreSettings->setAttribute(WebEngineSettings::ErrorPageEnabled, on);
+ if (wasOn ^ on)
+ Q_EMIT errorPageEnabledChanged(on);
+}
+
void QQuickWebEngineSettings::setDefaultTextEncoding(QString encoding)
{
Q_D(QQuickWebEngineSettings);
diff --git a/src/webengine/api/qquickwebenginesettings_p.h b/src/webengine/api/qquickwebenginesettings_p.h
index 0fa44ef44..4a7c2f834 100644
--- a/src/webengine/api/qquickwebenginesettings_p.h
+++ b/src/webengine/api/qquickwebenginesettings_p.h
@@ -57,6 +57,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineSettings : public QObject {
Q_PROPERTY(bool spatialNavigationEnabled READ spatialNavigationEnabled WRITE setSpatialNavigationEnabled NOTIFY spatialNavigationEnabledChanged)
Q_PROPERTY(bool localContentCanAccessFileUrls READ localContentCanAccessFileUrls WRITE setLocalContentCanAccessFileUrls NOTIFY localContentCanAccessFileUrlsChanged)
Q_PROPERTY(bool hyperlinkAuditingEnabled READ hyperlinkAuditingEnabled WRITE setHyperlinkAuditingEnabled NOTIFY hyperlinkAuditingEnabledChanged)
+ Q_PROPERTY(bool errorPageEnabled READ errorPageEnabled WRITE setErrorPageEnabled NOTIFY errorPageEnabledChanged)
Q_PROPERTY(QString defaultTextEncoding READ defaultTextEncoding WRITE setDefaultTextEncoding NOTIFY defaultTextEncodingChanged)
public:
@@ -74,6 +75,7 @@ public:
bool spatialNavigationEnabled() const;
bool localContentCanAccessFileUrls() const;
bool hyperlinkAuditingEnabled() const;
+ bool errorPageEnabled() const;
QString defaultTextEncoding() const;
void setAutoLoadImages(bool on);
@@ -86,6 +88,7 @@ public:
void setSpatialNavigationEnabled(bool on);
void setLocalContentCanAccessFileUrls(bool on);
void setHyperlinkAuditingEnabled(bool on);
+ void setErrorPageEnabled(bool on);
void setDefaultTextEncoding(QString encoding);
signals:
@@ -99,6 +102,7 @@ signals:
void spatialNavigationEnabledChanged(bool on);
void localContentCanAccessFileUrlsChanged(bool on);
void hyperlinkAuditingEnabledChanged(bool on);
+ void errorPageEnabledChanged(bool on);
void defaultTextEncodingChanged(QString encoding);
private:
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index ce53d4f8a..3a6b8cb21 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -242,6 +242,7 @@ void QQuickWebEngineViewPrivate::urlChanged(const QUrl &url)
{
Q_Q(QQuickWebEngineView);
Q_UNUSED(url);
+ explicitUrl = QUrl();
Q_EMIT q->urlChanged();
}
@@ -310,6 +311,7 @@ void QQuickWebEngineViewPrivate::loadFinished(bool success, const QUrl &url, int
return;
}
if (success) {
+ explicitUrl = QUrl();
QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus);
Q_EMIT q->loadingChanged(&loadRequest);
return;
@@ -514,7 +516,7 @@ QQuickWebEngineView::~QQuickWebEngineView()
QUrl QQuickWebEngineView::url() const
{
Q_D(const QQuickWebEngineView);
- return d->adapter->activeUrl();
+ return d->explicitUrl.isValid() ? d->explicitUrl : d->adapter->activeUrl();
}
void QQuickWebEngineView::setUrl(const QUrl& url)
@@ -523,6 +525,7 @@ void QQuickWebEngineView::setUrl(const QUrl& url)
return;
Q_D(QQuickWebEngineView);
+ d->explicitUrl = url;
d->adapter->load(url);
}
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index e2871a79e..9f6493022 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -54,8 +54,8 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem {
Q_PROPERTY(bool loading READ isLoading NOTIFY loadingChanged)
Q_PROPERTY(int loadProgress READ loadProgress NOTIFY loadProgressChanged)
Q_PROPERTY(QString title READ title NOTIFY titleChanged)
- Q_PROPERTY(bool canGoBack READ canGoBack NOTIFY loadingChanged)
- Q_PROPERTY(bool canGoForward READ canGoForward NOTIFY loadingChanged)
+ 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_ENUMS(NavigationRequestAction);
Q_ENUMS(NavigationType);
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index a89de5556..c7ea6575e 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -190,6 +190,7 @@ public:
QScopedPointer<QQuickWebEngineHistory> m_history;
QScopedPointer<QQuickWebEngineSettings> m_settings;
QQmlComponent *contextMenuExtraItems;
+ QUrl explicitUrl;
QUrl icon;
int loadProgress;
bool inspectable;
diff --git a/src/webengine/api/qtwebengineglobal.cpp b/src/webengine/api/qtwebengineglobal.cpp
index ea119bba6..b179da2fe 100644
--- a/src/webengine/api/qtwebengineglobal.cpp
+++ b/src/webengine/api/qtwebengineglobal.cpp
@@ -43,6 +43,7 @@
QT_BEGIN_NAMESPACE
Q_GUI_EXPORT void qt_gl_set_global_share_context(QOpenGLContext *context);
+Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
namespace QtWebEngine {
@@ -54,8 +55,20 @@ static void deleteShareContext()
shareContext = 0;
}
+// ### Qt 6: unify this logic and Qt::AA_ShareOpenGLContexts.
+// QtWebEngine::initialize was introduced first and meant to be called
+// after the QGuiApplication creation, when AA_ShareOpenGLContexts fills
+// the same need but the flag has to be set earlier.
void initialize()
{
+#ifdef Q_OS_WIN32
+ qputenv("QT_D3DCREATE_MULTITHREADED", "1");
+#endif
+
+ // No need to override the shared context if QApplication already set one (e.g with Qt::AA_ShareOpenGLContexts).
+ if (qt_gl_global_share_context())
+ return;
+
QCoreApplication *app = QCoreApplication::instance();
if (!app) {
qFatal("QWebEngine(Widgets)::initialize() must be called after the construction of the application object.");
@@ -69,10 +82,6 @@ void initialize()
if (shareContext)
return;
-#ifdef Q_OS_WIN32
- qputenv("QT_D3DCREATE_MULTITHREADED", "1");
-#endif
-
shareContext = new QOpenGLContext;
shareContext->create();
qAddPostRoutine(deleteShareContext);
diff --git a/src/webengine/plugin/plugins.qmltypes b/src/webengine/plugin/plugins.qmltypes
new file mode 100644
index 000000000..cebf986d2
--- /dev/null
+++ b/src/webengine/plugin/plugins.qmltypes
@@ -0,0 +1,164 @@
+import QtQuick.tooling 1.1
+
+// This file describes the plugin-supplied types contained in the library.
+// It is used for QML tooling purposes only.
+//
+// This file was auto-generated by:
+// 'qmlplugindump -noinstantiate -nonrelocatable QtWebEngine 1.0'
+
+Module {
+ Component {
+ name: "QQuickWebEngineLoadRequest"
+ prototype: "QObject"
+ exports: ["QtWebEngine/WebEngineLoadRequest 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Property { name: "url"; type: "QUrl"; isReadonly: true }
+ Property { name: "status"; type: "QQuickWebEngineView::LoadStatus"; isReadonly: true }
+ Property { name: "errorString"; type: "string"; isReadonly: true }
+ Property { name: "errorDomain"; type: "QQuickWebEngineView::ErrorDomain"; isReadonly: true }
+ Property { name: "errorCode"; type: "int"; isReadonly: true }
+ }
+ Component {
+ name: "QQuickWebEngineNavigationRequest"
+ prototype: "QObject"
+ exports: ["QtWebEngine/WebEngineNavigationRequest 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Property { name: "url"; type: "QUrl"; isReadonly: true }
+ Property { name: "isMainFrame"; type: "bool"; isReadonly: true }
+ Property { name: "action"; type: "QQuickWebEngineView::NavigationRequestAction" }
+ Property {
+ name: "navigationType"
+ type: "QQuickWebEngineView::NavigationType"
+ isReadonly: true
+ }
+ }
+ Component {
+ name: "QQuickWebEngineNewViewRequest"
+ prototype: "QObject"
+ exports: ["QtWebEngine/WebEngineNewViewRequest 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Property {
+ name: "destination"
+ type: "QQuickWebEngineView::NewViewDestination"
+ isReadonly: true
+ }
+ Property { name: "userInitiated"; type: "bool"; isReadonly: true }
+ Method {
+ name: "openIn"
+ Parameter { name: "view"; type: "QQuickWebEngineView"; isPointer: true }
+ }
+ }
+ Component {
+ name: "QQuickWebEngineView"
+ defaultProperty: "data"
+ prototype: "QQuickItem"
+ exports: ["QtWebEngine/WebEngineView 1.0"]
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "NavigationRequestAction"
+ values: {
+ "AcceptRequest": 0,
+ "IgnoreRequest": 255
+ }
+ }
+ Enum {
+ name: "NavigationType"
+ values: {
+ "LinkClickedNavigation": 0,
+ "TypedNavigation": 1,
+ "FormSubmittedNavigation": 2,
+ "BackForwardNavigation": 3,
+ "ReloadNavigation": 4,
+ "OtherNavigation": 5
+ }
+ }
+ Enum {
+ name: "LoadStatus"
+ values: {
+ "LoadStartedStatus": 0,
+ "LoadStoppedStatus": 1,
+ "LoadSucceededStatus": 2,
+ "LoadFailedStatus": 3
+ }
+ }
+ Enum {
+ name: "ErrorDomain"
+ values: {
+ "NoErrorDomain": 0,
+ "InternalErrorDomain": 1,
+ "ConnectionErrorDomain": 2,
+ "CertificateErrorDomain": 3,
+ "HttpErrorDomain": 4,
+ "FtpErrorDomain": 5,
+ "DnsErrorDomain": 6
+ }
+ }
+ Enum {
+ name: "NewViewDestination"
+ values: {
+ "NewViewInWindow": 0,
+ "NewViewInTab": 1,
+ "NewViewInDialog": 2
+ }
+ }
+ Enum {
+ name: "JavaScriptConsoleMessageLevel"
+ values: {
+ "InfoMessageLevel": 0,
+ "WarningMessageLevel": 1,
+ "ErrorMessageLevel": 2
+ }
+ }
+ Property { name: "url"; type: "QUrl" }
+ Property { name: "icon"; type: "QUrl"; isReadonly: true }
+ Property { name: "loading"; type: "bool"; isReadonly: true }
+ Property { name: "loadProgress"; type: "int"; isReadonly: true }
+ Property { name: "title"; type: "string"; isReadonly: true }
+ Property { name: "canGoBack"; type: "bool"; isReadonly: true }
+ Property { name: "canGoForward"; type: "bool"; isReadonly: true }
+ Signal {
+ name: "loadingChanged"
+ Parameter { name: "loadRequest"; type: "QQuickWebEngineLoadRequest"; isPointer: true }
+ }
+ Signal {
+ name: "linkHovered"
+ Parameter { name: "hoveredUrl"; type: "QUrl" }
+ }
+ Signal {
+ name: "navigationRequested"
+ Parameter { name: "request"; type: "QQuickWebEngineNavigationRequest"; isPointer: true }
+ }
+ Signal {
+ name: "javaScriptConsoleMessage"
+ Parameter { name: "level"; type: "JavaScriptConsoleMessageLevel" }
+ Parameter { name: "message"; type: "string" }
+ Parameter { name: "lineNumber"; type: "int" }
+ Parameter { name: "sourceID"; type: "string" }
+ }
+ Method {
+ name: "runJavaScript"
+ Parameter { type: "string" }
+ Parameter { type: "QJSValue" }
+ }
+ Method {
+ name: "runJavaScript"
+ Parameter { type: "string" }
+ }
+ Method {
+ name: "loadHtml"
+ Parameter { name: "html"; type: "string" }
+ Parameter { name: "baseUrl"; type: "QUrl" }
+ }
+ Method {
+ name: "loadHtml"
+ Parameter { name: "html"; type: "string" }
+ }
+ Method { name: "goBack" }
+ Method { name: "goForward" }
+ Method { name: "reload" }
+ Method { name: "stop" }
+ }
+}
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 9b0636696..e3ab2ec0d 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -197,7 +197,7 @@ void QWebEnginePagePrivate::titleChanged(const QString &title)
void QWebEnginePagePrivate::urlChanged(const QUrl &url)
{
Q_Q(QWebEnginePage);
- m_explicitUrl = QUrl();
+ explicitUrl = QUrl();
Q_EMIT q->urlChanged(url);
}
@@ -257,7 +257,7 @@ void QWebEnginePagePrivate::loadFinished(bool success, const QUrl &url, int erro
Q_UNUSED(errorDescription);
isLoading = false;
if (success)
- m_explicitUrl = QUrl();
+ explicitUrl = QUrl();
Q_EMIT q->loadFinished(success);
updateNavigationActions();
}
@@ -333,11 +333,11 @@ void QWebEnginePagePrivate::runMediaAccessPermissionRequest(const QUrl &security
Q_Q(QWebEnginePage);
QWebEnginePage::Feature requestedFeature;
if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture) && requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
- requestedFeature = QWebEnginePage::MediaAudioVideoDevices;
+ requestedFeature = QWebEnginePage::MediaAudioVideoCapture;
else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture))
- requestedFeature = QWebEnginePage::MediaAudioDevices;
+ requestedFeature = QWebEnginePage::MediaAudioCapture;
else if (requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
- requestedFeature = QWebEnginePage::MediaVideoDevices;
+ requestedFeature = QWebEnginePage::MediaVideoCapture;
else
return;
Q_EMIT q->featurePermissionRequested(securityOrigin, requestedFeature);
@@ -758,16 +758,16 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine
Q_D(QWebEnginePage);
WebContentsAdapterClient::MediaRequestFlags flags = WebContentsAdapterClient::MediaNone;
switch (feature) {
- case MediaAudioVideoDevices:
- case MediaAudioDevices:
- case MediaVideoDevices:
+ case MediaAudioVideoCapture:
+ case MediaAudioCapture:
+ case MediaVideoCapture:
if (policy != PermissionUnknown) {
if (policy == PermissionDeniedByUser)
flags = WebContentsAdapterClient::MediaNone;
else {
- if (feature == MediaAudioDevices)
+ if (feature == MediaAudioCapture)
flags = WebContentsAdapterClient::MediaAudioCapture;
- else if (feature == MediaVideoDevices)
+ else if (feature == MediaVideoCapture)
flags = WebContentsAdapterClient::MediaVideoCapture;
else
flags = WebContentsAdapterClient::MediaRequestFlags(WebContentsAdapterClient::MediaVideoCapture | WebContentsAdapterClient::MediaAudioCapture);
@@ -838,14 +838,14 @@ QString QWebEnginePage::title() const
void QWebEnginePage::setUrl(const QUrl &url)
{
Q_D(QWebEnginePage);
- d->m_explicitUrl = url;
+ d->explicitUrl = url;
load(url);
}
QUrl QWebEnginePage::url() const
{
Q_D(const QWebEnginePage);
- return d->m_explicitUrl.isValid() ? d->m_explicitUrl : d->adapter->activeUrl();
+ return d->explicitUrl.isValid() ? d->explicitUrl : d->adapter->activeUrl();
}
QUrl QWebEnginePage::requestedUrl() const
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index ecd8a5712..afb62ceda 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -122,7 +122,8 @@ public:
FindBackward = 1,
FindCaseSensitively = 2,
};
- Q_DECLARE_FLAGS(FindFlags, FindFlag)
+ Q_DECLARE_FLAGS(FindFlags, FindFlag);
+
enum WebWindowType {
WebBrowserWindow,
WebBrowserTab,
@@ -146,12 +147,15 @@ public:
};
enum Feature {
- Notifications,
- Geolocation,
- MediaAudioDevices,
- MediaVideoDevices,
- MediaAudioVideoDevices
+#ifndef Q_QDOC
+ Notifications = 0,
+ Geolocation = 1,
+#endif
+ MediaAudioCapture = 2,
+ MediaVideoCapture,
+ MediaAudioVideoCapture
};
+
// Ex-QWebFrame enum
enum FileSelectionMode {
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 57c44cacb..6424c3b0b 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -153,7 +153,7 @@ public:
QWebEngineSettings *settings;
QWebEngineView *view;
QSize viewportSize;
- QUrl m_explicitUrl;
+ QUrl explicitUrl;
WebEngineContextMenuData m_menuData;
bool isLoading;
diff --git a/src/webenginewidgets/api/qwebenginesettings.cpp b/src/webenginewidgets/api/qwebenginesettings.cpp
index 9ade311fc..729a09f56 100644
--- a/src/webenginewidgets/api/qwebenginesettings.cpp
+++ b/src/webenginewidgets/api/qwebenginesettings.cpp
@@ -67,6 +67,8 @@ static WebEngineSettings::Attribute toWebEngineAttribute(QWebEngineSettings::Web
return WebEngineSettings::HyperlinkAuditingEnabled;
case QWebEngineSettings::ScrollAnimatorEnabled:
return WebEngineSettings::ScrollAnimatorEnabled;
+ case QWebEngineSettings::ErrorPageEnabled:
+ return WebEngineSettings::ErrorPageEnabled;
default:
return WebEngineSettings::UnsupportedInCoreSettings;
}
diff --git a/src/webenginewidgets/api/qwebenginesettings.h b/src/webenginewidgets/api/qwebenginesettings.h
index 68c0a6031..d9f57a935 100644
--- a/src/webenginewidgets/api/qwebenginesettings.h
+++ b/src/webenginewidgets/api/qwebenginesettings.h
@@ -54,7 +54,8 @@ public:
SpatialNavigationEnabled,
LocalContentCanAccessFileUrls,
HyperlinkAuditingEnabled,
- ScrollAnimatorEnabled
+ ScrollAnimatorEnabled,
+ ErrorPageEnabled
};
enum FontSize {
diff --git a/src/webenginewidgets/doc/snippets/qtwebengine_qwebengineview_snippet.cpp b/src/webenginewidgets/doc/snippets/qtwebengine_qwebengineview_snippet.cpp
index 20edd73c6..57e4a7047 100644
--- a/src/webenginewidgets/doc/snippets/qtwebengine_qwebengineview_snippet.cpp
+++ b/src/webenginewidgets/doc/snippets/qtwebengine_qwebengineview_snippet.cpp
@@ -36,22 +36,22 @@ void wrapInFunction()
//! [2]
- view->triggerAction(QWebPage::Copy);
+ view->triggerPageAction(QWebEnginePage::Copy);
//! [2]
//! [3]
- view->page()->triggerPageAction(QWebPage::Stop);
+ view->page()->triggerAction(QWebEnginePage::Stop);
//! [3]
//! [4]
- view->page()->triggerPageAction(QWebPage::GoBack);
+ view->page()->triggerAction(QWebEnginePage::Back);
//! [4]
//! [5]
- view->page()->triggerPageAction(QWebPage::GoForward);
+ view->page()->triggerAction(QWebEnginePage::Forward);
//! [5]
//! [6]
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index e254e6753..af435d170 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -166,11 +166,9 @@
This enum describes the platform feature access categories that the user may be asked to grant or deny access to.
- \value Notifications Grants access to display notifications to the user.
- \value Geolocation The geographic location devices that may be available.
- \value MediaAudioDevices Audio devices such as speakers or microphones
- \value MediaVideoDevices Video devices, e.g. cameras
- \value MediaAudioVideoDevices Both Audio and Video devices.
+ \value MediaAudioCapture Audio capture devices such a microphones
+ \value MediaVideoCapture Video devices, e.g. cameras
+ \value MediaAudioVideoCapture Both Audio and Video capture devices.
\sa featurePermissionRequested(), featurePermissionRequestCanceled(), setFeaturePermission(), PermissionPolicy
diff --git a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
index 3c420b805..ca9f0ca95 100644
--- a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
@@ -115,6 +115,7 @@
about security origins and local vs. remote content see QWebEngineSecurityOrigin.
\value HyperlinkAuditingEnabled This setting enables support for the ping attribute for hyperlinks. It is disabled by default.
\value ScrollAnimatorEnabled This setting enables animated scrolling. It is disabled by default.
+ \value ErrorPageEnabled This setting enables built-in error pages of Chromium. It is enabled by default.
*/
/*!
diff --git a/tests/auto/quick/html/basic_page.html b/tests/auto/quick/html/basic_page.html
new file mode 100644
index 000000000..53726e4a6
--- /dev/null
+++ b/tests/auto/quick/html/basic_page.html
@@ -0,0 +1,6 @@
+<html>
+<head>
+<title> Basic Page </title>
+</head>
+<h1>Basic page</h1>
+</html>
diff --git a/tests/auto/quick/html/basic_page2.html b/tests/auto/quick/html/basic_page2.html
new file mode 100644
index 000000000..f8cff2969
--- /dev/null
+++ b/tests/auto/quick/html/basic_page2.html
@@ -0,0 +1 @@
+<h1>Basic page 2</h1>
diff --git a/tests/auto/quick/html/direct-image-compositing.html b/tests/auto/quick/html/direct-image-compositing.html
new file mode 100644
index 000000000..53a4ca137
--- /dev/null
+++ b/tests/auto/quick/html/direct-image-compositing.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <title>Testing direct image layer optimization</title>
+ <style type="text/css" media="screen">
+ img {
+ float: left;
+ width: 150px;
+ height: 150px;
+ }
+ img {
+ -webkit-transform: rotate3d(0, 0, 1, 0);
+ }
+ .test {
+ float: left;
+ height: 200px;
+ width: 260px;
+ }
+ </style>
+</head>
+<body>
+
+ <h1>Image optimization in layers</h1>
+
+ <p>
+ This test exercises direct compositing of images with hardware acceleration. The visual results
+ using ACCELERATED_COMPOSITING and regular TOT should be identical. Running this test manually with
+ the correct debug options will show which elements are directly composited. See
+ <a href="https://bugs.webkit.org/show_bug.cgi?id=23361">https://bugs.webkit.org/show_bug.cgi?id=23361</a>
+ </p>
+
+ <div class="test">
+ <img src="resources/simple_image.png">
+ Basic image - no style - can be directly composited
+ </div>
+
+ <div class="test">
+ <img src="resources/simple_image.png" style="border: 5px solid blue;">
+ 5px blue border - can NOT be directly composited
+ </div>
+
+ <div class="test">
+ <img src="resources/simple_image.png" style="margin: 5px 5px;">
+ margin - can NOT be directly composited
+ </div>
+
+ <div class="test">
+ <img src="resources/simple_image.png" style="background-color: grey;">
+ solid background - can be directly composited
+ </div>
+
+ <div class="test">
+ <img src="resources/simple_image.png" style="background: orange url(resources/simple_image.png) -50px -50px;">
+ background image - can NOT be directly composited
+ </div>
+
+ <div class="test">
+ <img src="resources/simple_image.png" style="-webkit-transform: rotate3d(0, 0, 1, 10deg);">
+ rotated but otherwise no style - can be directly composited
+ </div>
+
+</body>
+</html>
diff --git a/tests/auto/quick/html/inputmethod.html b/tests/auto/quick/html/inputmethod.html
new file mode 100644
index 000000000..dc9140f9d
--- /dev/null
+++ b/tests/auto/quick/html/inputmethod.html
@@ -0,0 +1,11 @@
+<html>
+<head>
+<title>Basic Page For Input Method Testing</title>
+</head>
+<body>
+<h1>Basic page</h1>
+<input id="inputField" />
+<input id="emailInputField" type="email" />
+<div id="editableDiv" contenteditable></div>
+</body>
+</html>
diff --git a/tests/auto/quick/html/resources/simple_image.png b/tests/auto/quick/html/resources/simple_image.png
new file mode 100644
index 000000000..4685399ca
--- /dev/null
+++ b/tests/auto/quick/html/resources/simple_image.png
Binary files differ
diff --git a/tests/auto/quick/html/scroll.html b/tests/auto/quick/html/scroll.html
new file mode 100644
index 000000000..ce2193b6c
--- /dev/null
+++ b/tests/auto/quick/html/scroll.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<meta name="viewport" content="width=200, height=500, user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1"/>
+<script type="text/javascript">
+function pageScroll() {
+ window.scrollBy(0,50); // horizontal and vertical scroll increments
+}
+</script>
+<style>
+ body {
+ background-color: blue;
+ margin: 50 50 50 50;
+ }
+ div {
+ font-color: white;
+ background-color: green;
+ width: 300px;
+ height: 1000px;
+ }
+</style>
+
+<head>
+<title>Scroll test </title>
+</head>
+<body onload="pageScroll()">
+<div>
+</div>
+</body>
+</html>
diff --git a/tests/auto/quick/qmltests/data/tst_loadUrl.qml b/tests/auto/quick/qmltests/data/tst_loadUrl.qml
index 41faa6bc3..5f51e9036 100644
--- a/tests/auto/quick/qmltests/data/tst_loadUrl.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadUrl.qml
@@ -125,7 +125,9 @@ TestWebEngineView {
var handleLoadFailed = function(loadRequest) {
if (loadRequest.status == WebEngineView.LoadFailedStatus) {
webEngineView.loadHtml("load failed", bogusSite)
- compare(webEngineView.url, bogusSite)
+ // Since the load did not succeed the active url is the
+ // url of the previous successful load.
+ compare(webEngineView.url, "about:blank")
compare(loadRequest.url, bogusSite)
}
}
diff --git a/tests/auto/quick/qmltests/qmltests.pro b/tests/auto/quick/qmltests/qmltests.pro
index b25878dc9..b40ef3b8c 100644
--- a/tests/auto/quick/qmltests/qmltests.pro
+++ b/tests/auto/quick/qmltests/qmltests.pro
@@ -4,8 +4,6 @@ QT += qmltest
IMPORTPATH += $$PWD/data
-INCLUDEPATH += $$PWD/../shared
-
OTHER_FILES += \
$$PWD/data/TestWebEngineView.qml \
$$PWD/data/favicon.html \
diff --git a/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro b/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro
new file mode 100644
index 000000000..826b47de7
--- /dev/null
+++ b/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro
@@ -0,0 +1,6 @@
+include(../tests.pri)
+
+exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc
+QT_PRIVATE += webengine-private
+
+HEADERS += ../shared/util.h
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
new file mode 100644
index 000000000..228a3e034
--- /dev/null
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -0,0 +1,422 @@
+/*
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "testwindow.h"
+#include "util.h"
+
+#include <QScopedPointer>
+#include <QtQml/QQmlEngine>
+#include <QtTest/QtTest>
+#include <private/qquickwebengineview_p.h>
+
+class tst_QQuickWebEngineView : public QObject {
+ Q_OBJECT
+public:
+ tst_QQuickWebEngineView();
+
+private Q_SLOTS:
+ void init();
+ void cleanup();
+
+ void navigationStatusAtStartup();
+ void stopEnabledAfterLoadStarted();
+ void baseUrl();
+ void loadEmptyUrl();
+ void loadEmptyPageViewVisible();
+ void loadEmptyPageViewHidden();
+ void loadNonexistentFileUrl();
+ void backAndForward();
+ void reload();
+ void stop();
+ void loadProgress();
+
+ void show();
+ void showWebEngineView();
+ void removeFromCanvas();
+ void multipleWebEngineViewWindows();
+ void multipleWebEngineViews();
+ void titleUpdate();
+ void transparentWebEngineViews();
+
+ void inputMethod();
+ void inputMethodHints();
+ void basicRenderingSanity();
+
+private:
+ inline QQuickWebEngineView *newWebEngineView();
+ inline QQuickWebEngineView *webEngineView() const;
+ void runJavaScript(const QString &script);
+ QScopedPointer<TestWindow> m_window;
+ QScopedPointer<QQmlComponent> m_component;
+};
+
+tst_QQuickWebEngineView::tst_QQuickWebEngineView()
+{
+ QtWebEngine::initialize();
+
+ static QQmlEngine *engine = new QQmlEngine(this);
+ m_component.reset(new QQmlComponent(engine, this));
+ m_component->setData(QByteArrayLiteral("import QtQuick 2.0\n"
+ "import QtWebEngine 1.0\n"
+ "WebEngineView {}")
+ , QUrl());
+}
+
+QQuickWebEngineView *tst_QQuickWebEngineView::newWebEngineView()
+{
+ QObject *viewInstance = m_component->create();
+ QQuickWebEngineView *webEngineView = qobject_cast<QQuickWebEngineView*>(viewInstance);
+ return webEngineView;
+}
+
+void tst_QQuickWebEngineView::init()
+{
+ m_window.reset(new TestWindow(newWebEngineView()));
+}
+
+void tst_QQuickWebEngineView::cleanup()
+{
+ m_window.reset();
+}
+
+inline QQuickWebEngineView *tst_QQuickWebEngineView::webEngineView() const
+{
+ return static_cast<QQuickWebEngineView*>(m_window->webEngineView.data());
+}
+
+void tst_QQuickWebEngineView::runJavaScript(const QString &script)
+{
+ webEngineView()->runJavaScript(script);
+}
+
+void tst_QQuickWebEngineView::navigationStatusAtStartup()
+{
+ QCOMPARE(webEngineView()->canGoBack(), false);
+
+ QCOMPARE(webEngineView()->canGoForward(), false);
+
+ QCOMPARE(webEngineView()->isLoading(), false);
+}
+
+void tst_QQuickWebEngineView::stopEnabledAfterLoadStarted()
+{
+ QCOMPARE(webEngineView()->isLoading(), false);
+
+ LoadStartedCatcher catcher(webEngineView());
+ webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")));
+ waitForSignal(&catcher, SIGNAL(finished()));
+
+ QCOMPARE(webEngineView()->isLoading(), true);
+
+ QVERIFY(waitForLoadSucceeded(webEngineView()));
+}
+
+void tst_QQuickWebEngineView::baseUrl()
+{
+ // Test the url is in a well defined state when instanciating the view, but before loading anything.
+ QVERIFY(webEngineView()->url().isEmpty());
+}
+
+void tst_QQuickWebEngineView::loadEmptyUrl()
+{
+ webEngineView()->setUrl(QUrl());
+ webEngineView()->setUrl(QUrl(QLatin1String("")));
+}
+
+void tst_QQuickWebEngineView::loadEmptyPageViewVisible()
+{
+ m_window->show();
+ loadEmptyPageViewHidden();
+}
+
+void tst_QQuickWebEngineView::loadEmptyPageViewHidden()
+{
+ QSignalSpy loadSpy(webEngineView(), SIGNAL(loadingChanged(QQuickWebEngineLoadRequest*)));
+
+ webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html")));
+ QVERIFY(waitForLoadSucceeded(webEngineView()));
+
+ QCOMPARE(loadSpy.size(), 2);
+}
+
+void tst_QQuickWebEngineView::loadNonexistentFileUrl()
+{
+ QSignalSpy loadSpy(webEngineView(), SIGNAL(loadingChanged(QQuickWebEngineLoadRequest*)));
+
+ webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/file_that_does_not_exist.html")));
+ QVERIFY(waitForLoadFailed(webEngineView()));
+
+ QCOMPARE(loadSpy.size(), 2);
+}
+
+void tst_QQuickWebEngineView::backAndForward()
+{
+ webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html")));
+ QVERIFY(waitForLoadSucceeded(webEngineView()));
+
+ QCOMPARE(webEngineView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html"));
+
+ webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/basic_page2.html")));
+ QVERIFY(waitForLoadSucceeded(webEngineView()));
+
+ QCOMPARE(webEngineView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "html/basic_page2.html"));
+
+ webEngineView()->goBack();
+ QVERIFY(waitForLoadSucceeded(webEngineView()));
+
+ QCOMPARE(webEngineView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html"));
+
+ webEngineView()->goForward();
+ QVERIFY(waitForLoadSucceeded(webEngineView()));
+
+ QCOMPARE(webEngineView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "html/basic_page2.html"));
+}
+
+void tst_QQuickWebEngineView::reload()
+{
+ webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html")));
+ QVERIFY(waitForLoadSucceeded(webEngineView()));
+
+ QCOMPARE(webEngineView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html"));
+
+ webEngineView()->reload();
+ QVERIFY(waitForLoadSucceeded(webEngineView()));
+
+ QCOMPARE(webEngineView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html"));
+}
+
+void tst_QQuickWebEngineView::stop()
+{
+ webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html")));
+ QVERIFY(waitForLoadSucceeded(webEngineView()));
+
+ QCOMPARE(webEngineView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html"));
+
+ webEngineView()->stop();
+}
+
+void tst_QQuickWebEngineView::loadProgress()
+{
+ QCOMPARE(webEngineView()->loadProgress(), 0);
+
+ webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html")));
+ QSignalSpy loadProgressChangedSpy(webEngineView(), SIGNAL(loadProgressChanged()));
+ QVERIFY(waitForLoadSucceeded(webEngineView()));
+
+ QVERIFY(loadProgressChangedSpy.count() >= 1);
+
+ QCOMPARE(webEngineView()->loadProgress(), 100);
+}
+
+void tst_QQuickWebEngineView::show()
+{
+ // This should not crash.
+ m_window->show();
+ QTest::qWait(200);
+ m_window->hide();
+}
+
+void tst_QQuickWebEngineView::showWebEngineView()
+{
+ webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/direct-image-compositing.html")));
+ QVERIFY(waitForLoadSucceeded(webEngineView()));
+ m_window->show();
+ // This should not crash.
+ webEngineView()->setVisible(true);
+ QTest::qWait(200);
+ webEngineView()->setVisible(false);
+ QTest::qWait(200);
+}
+
+void tst_QQuickWebEngineView::removeFromCanvas()
+{
+ showWebEngineView();
+
+ // This should not crash.
+ QQuickItem *parent = webEngineView()->parentItem();
+ QQuickItem noCanvasItem;
+ webEngineView()->setParentItem(&noCanvasItem);
+ QTest::qWait(200);
+ webEngineView()->setParentItem(parent);
+ webEngineView()->setVisible(true);
+ QTest::qWait(200);
+}
+
+void tst_QQuickWebEngineView::multipleWebEngineViewWindows()
+{
+ showWebEngineView();
+
+ // This should not crash.
+ QQuickWebEngineView *webEngineView1 = newWebEngineView();
+ QScopedPointer<TestWindow> window1(new TestWindow(webEngineView1));
+ QQuickWebEngineView *webEngineView2 = newWebEngineView();
+ QScopedPointer<TestWindow> window2(new TestWindow(webEngineView2));
+
+ webEngineView1->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/scroll.html")));
+ QVERIFY(waitForLoadSucceeded(webEngineView1));
+ window1->show();
+ webEngineView1->setVisible(true);
+
+ webEngineView2->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html")));
+ QVERIFY(waitForLoadSucceeded(webEngineView2));
+ window2->show();
+ webEngineView2->setVisible(true);
+ QTest::qWait(200);
+}
+
+void tst_QQuickWebEngineView::multipleWebEngineViews()
+{
+ showWebEngineView();
+
+ // This should not crash.
+ QScopedPointer<QQuickWebEngineView> webEngineView1(newWebEngineView());
+ webEngineView1->setParentItem(m_window->contentItem());
+ QScopedPointer<QQuickWebEngineView> webEngineView2(newWebEngineView());
+ webEngineView2->setParentItem(m_window->contentItem());
+
+ webEngineView1->setSize(QSizeF(300, 400));
+ webEngineView1->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/scroll.html")));
+ QVERIFY(waitForLoadSucceeded(webEngineView1.data()));
+ webEngineView1->setVisible(true);
+
+ webEngineView2->setSize(QSizeF(300, 400));
+ webEngineView2->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html")));
+ QVERIFY(waitForLoadSucceeded(webEngineView2.data()));
+ webEngineView2->setVisible(true);
+ QTest::qWait(200);
+}
+
+void tst_QQuickWebEngineView::basicRenderingSanity()
+{
+ showWebEngineView();
+
+ webEngineView()->setUrl(QUrl(QString::fromUtf8("data:text/html,<html><body bgcolor=\"#00ff00\"></body></html>")));
+ QVERIFY(waitForLoadSucceeded(webEngineView()));
+
+ // This should not crash.
+ webEngineView()->setVisible(true);
+ QTest::qWait(200);
+ QImage grabbedWindow = m_window->grabWindow();
+ QRgb testColor = qRgba(0, 0xff, 0, 0xff);
+ QVERIFY(grabbedWindow.pixel(10, 10) == testColor);
+ QVERIFY(grabbedWindow.pixel(100, 10) == testColor);
+ QVERIFY(grabbedWindow.pixel(10, 100) == testColor);
+ QVERIFY(grabbedWindow.pixel(100, 100) == testColor);
+}
+
+void tst_QQuickWebEngineView::titleUpdate()
+{
+ QSignalSpy titleSpy(webEngineView(), SIGNAL(titleChanged()));
+
+ // Load page with no title
+ webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/basic_page2.html")));
+ QVERIFY(waitForLoadSucceeded(webEngineView()));
+ QCOMPARE(titleSpy.size(), 1);
+
+ titleSpy.clear();
+
+ // No titleChanged signal for failed load
+ webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/file_that_does_not_exist.html")));
+ QVERIFY(waitForLoadFailed(webEngineView()));
+ QCOMPARE(titleSpy.size(), 0);
+
+}
+
+void tst_QQuickWebEngineView::transparentWebEngineViews()
+{
+
+ showWebEngineView();
+
+ // This should not crash.
+ QScopedPointer<QQuickWebEngineView> webEngineView1(newWebEngineView());
+ webEngineView1->setParentItem(m_window->contentItem());
+ QScopedPointer<QQuickWebEngineView> webEngineView2(newWebEngineView());
+ webEngineView2->setParentItem(m_window->contentItem());
+#if !defined(QQUICKWEBENGINEVIEW_EXPERIMENTAL_TRANSPARENTBACKGROUND)
+ QWARN("QQUICKWEBENGINEVIEW_EXPERIMENTAL_TRANSPARENTBACKGROUND");
+#else
+ QVERIFY(!webEngineView1->experimental()->transparentBackground());
+ webEngineView2->experimental()->setTransparentBackground(true);
+ QVERIFY(webEngineView2->experimental()->transparentBackground());
+#endif
+
+ webEngineView1->setSize(QSizeF(300, 400));
+ webEngineView1->loadHtml("<html><body bgcolor=\"red\"></body></html>");
+ QVERIFY(waitForLoadSucceeded(webEngineView1.data()));
+ webEngineView1->setVisible(true);
+
+ webEngineView2->setSize(QSizeF(300, 400));
+ webEngineView2->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")));
+ QVERIFY(waitForLoadSucceeded(webEngineView2.data()));
+ webEngineView2->setVisible(true);
+
+ QTest::qWait(200);
+ // FIXME: test actual rendering results; https://bugs.webkit.org/show_bug.cgi?id=80609.
+}
+
+void tst_QQuickWebEngineView::inputMethod()
+{
+#if !defined(QQUICKWEBENGINEVIEW_ITEMACCEPTSINPUTMETHOD)
+ QSKIP("QQUICKWEBENGINEVIEW_ITEMACCEPTSINPUTMETHOD");
+#else
+ QQuickWebEngineView *view = webEngineView();
+ view->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/inputmethod.html")));
+ QVERIFY(waitForLoadSucceeded(view));
+
+ QVERIFY(!view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
+ runJavaScript("document.getElementById('inputField').focus();");
+ QVERIFY(view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
+ runJavaScript("document.getElementById('inputField').blur();");
+ QVERIFY(!view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
+#endif
+}
+
+void tst_QQuickWebEngineView::inputMethodHints()
+{
+#if !defined(QQUICKWEBENGINEVIEW_ITEMACCEPTSINPUTMETHOD)
+ QSKIP("QQUICKWEBENGINEVIEW_ITEMACCEPTSINPUTMETHOD");
+#else
+ QQuickWebEngineView *view = webEngineView();
+
+ view->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/inputmethod.html")));
+ QVERIFY(waitForLoadSucceeded(view));
+
+ // Setting focus on an input element results in an element in its shadow tree becoming the focus node.
+ // Input hints should not be set from this shadow tree node but from the input element itself.
+ runJavaScript("document.getElementById('emailInputField').focus();");
+ QVERIFY(view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
+ QInputMethodQueryEvent query(Qt::ImHints);
+ QGuiApplication::sendEvent(view, &query);
+ Qt::InputMethodHints hints(query.value(Qt::ImHints).toUInt() & Qt::ImhExclusiveInputMask);
+ QCOMPARE(hints, Qt::ImhEmailCharactersOnly);
+
+ // The focus of an editable DIV is given directly to it, so no shadow root element
+ // is necessary. This tests the WebPage::editorState() method ability to get the
+ // right element without breaking.
+ runJavaScript("document.getElementById('editableDiv').focus();");
+ QVERIFY(view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
+ query = QInputMethodQueryEvent(Qt::ImHints);
+ QGuiApplication::sendEvent(view, &query);
+ hints = Qt::InputMethodHints(query.value(Qt::ImHints).toUInt());
+ QCOMPARE(hints, Qt::ImhNone);
+#endif
+}
+
+QTEST_MAIN(tst_QQuickWebEngineView)
+#include "tst_qquickwebengineview.moc"
diff --git a/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp b/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
index af57df7e0..b69cdd151 100644
--- a/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
+++ b/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include "util.h"
+
#include <QtTest/QtTest>
#include <QQmlContext>
#include <QQuickView>
@@ -99,21 +101,6 @@ static QImage get150x150GreenReferenceImage()
return reference;
}
-static inline bool waitForSignal(QObject *obj, const char *signal, int timeout = 10000)
-{
- QEventLoop loop;
- QObject::connect(obj, signal, &loop, SLOT(quit()));
- QTimer timer;
- QSignalSpy timeoutSpy(&timer, SIGNAL(timeout()));
- if (timeout > 0) {
- QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
- timer.setSingleShot(true);
- timer.start(timeout);
- }
- loop.exec();
- return timeoutSpy.isEmpty();
-}
-
tst_QQuickWebEngineViewGraphics::tst_QQuickWebEngineViewGraphics()
{
}
diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro
index e9f83181e..5c9bb72b5 100644
--- a/tests/auto/quick/quick.pro
+++ b/tests/auto/quick/quick.pro
@@ -3,4 +3,5 @@ TEMPLATE = subdirs
SUBDIRS += \
publicapi \
qmltests \
+ qquickwebengineview \
qquickwebengineviewgraphics
diff --git a/tests/auto/quick/shared/testwindow.h b/tests/auto/quick/shared/testwindow.h
new file mode 100644
index 000000000..f5181ee97
--- /dev/null
+++ b/tests/auto/quick/shared/testwindow.h
@@ -0,0 +1,59 @@
+/*
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef TESTWINDOW_H
+#define TESTWINDOW_H
+
+#if 0
+#pragma qt_no_master_include
+#endif
+
+#include <QResizeEvent>
+#include <QScopedPointer>
+#include <QtQuick/qquickitem.h>
+#include <QtQuick/qquickview.h>
+
+// TestWindow: Utility class to ignore QQuickView details.
+class TestWindow : public QQuickView {
+public:
+ inline TestWindow(QQuickItem *webEngineView);
+ QScopedPointer<QQuickItem> webEngineView;
+
+protected:
+ inline void resizeEvent(QResizeEvent*);
+};
+
+inline TestWindow::TestWindow(QQuickItem *webEngineView)
+ : webEngineView(webEngineView)
+{
+ Q_ASSERT(webEngineView);
+ webEngineView->setParentItem(contentItem());
+ resize(300, 400);
+}
+
+inline void TestWindow::resizeEvent(QResizeEvent *event)
+{
+ QQuickView::resizeEvent(event);
+ webEngineView->setX(0);
+ webEngineView->setY(0);
+ webEngineView->setWidth(event->size().width());
+ webEngineView->setHeight(event->size().height());
+}
+
+#endif /* TESTWINDOW_H */
diff --git a/tests/auto/quick/shared/util.h b/tests/auto/quick/shared/util.h
new file mode 100644
index 000000000..8f7a85f68
--- /dev/null
+++ b/tests/auto/quick/shared/util.h
@@ -0,0 +1,125 @@
+/*
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef UTIL_H
+#define UTIL_H
+
+#include <QEventLoop>
+#include <QSignalSpy>
+#include <QTimer>
+#include <QtTest/QtTest>
+#include <private/qquickwebengineview_p.h>
+#include <private/qquickwebengineloadrequest_p.h>
+
+#if !defined(TESTS_SOURCE_DIR)
+#define TESTS_SOURCE_DIR ""
+#endif
+
+class LoadSpy : public QEventLoop {
+ Q_OBJECT
+
+public:
+ LoadSpy(QQuickWebEngineView *webEngineView)
+ {
+ connect(webEngineView, SIGNAL(loadingChanged(QQuickWebEngineLoadRequest*)), SLOT(onLoadingChanged(QQuickWebEngineLoadRequest*)));
+ }
+
+ ~LoadSpy() { }
+
+Q_SIGNALS:
+ void loadSucceeded();
+ void loadFailed();
+
+private Q_SLOTS:
+ void onLoadingChanged(QQuickWebEngineLoadRequest *loadRequest)
+ {
+ if (loadRequest->status() == QQuickWebEngineView::LoadSucceededStatus)
+ emit loadSucceeded();
+ else if (loadRequest->status() == QQuickWebEngineView::LoadFailedStatus)
+ emit loadFailed();
+ }
+};
+
+class LoadStartedCatcher : public QObject {
+ Q_OBJECT
+
+public:
+ LoadStartedCatcher(QQuickWebEngineView *webEngineView)
+ : m_webEngineView(webEngineView)
+ {
+ connect(m_webEngineView, SIGNAL(loadingChanged(QQuickWebEngineLoadRequest*)), this, SLOT(onLoadingChanged(QQuickWebEngineLoadRequest*)));
+ }
+
+ virtual ~LoadStartedCatcher() { }
+
+public Q_SLOTS:
+ void onLoadingChanged(QQuickWebEngineLoadRequest *loadRequest)
+ {
+ if (loadRequest->status() == QQuickWebEngineView::LoadStartedStatus)
+ QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
+ }
+
+Q_SIGNALS:
+ void finished();
+
+private:
+ QQuickWebEngineView *m_webEngineView;
+};
+
+/**
+ * Starts an event loop that runs until the given signal is received.
+ * Optionally the event loop
+ * can return earlier on a timeout.
+ *
+ * \return \p true if the requested signal was received
+ * \p false on timeout
+ */
+inline bool waitForSignal(QObject *obj, const char *signal, int timeout = 10000)
+{
+ QEventLoop loop;
+ QObject::connect(obj, signal, &loop, SLOT(quit()));
+ QTimer timer;
+ QSignalSpy timeoutSpy(&timer, SIGNAL(timeout()));
+ if (timeout > 0) {
+ QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
+ timer.setSingleShot(true);
+ timer.start(timeout);
+ }
+ loop.exec();
+ return timeoutSpy.isEmpty();
+}
+
+inline bool waitForLoadSucceeded(QQuickWebEngineView *webEngineView, int timeout = 10000)
+{
+ LoadSpy loadSpy(webEngineView);
+ return waitForSignal(&loadSpy, SIGNAL(loadSucceeded()), timeout);
+}
+
+inline bool waitForLoadFailed(QQuickWebEngineView *webEngineView, int timeout = 10000)
+{
+ LoadSpy loadSpy(webEngineView);
+ return waitForSignal(&loadSpy, SIGNAL(loadFailed()), timeout);
+}
+
+inline bool waitForViewportReady(QQuickWebEngineView *webEngineView, int timeout = 10000)
+{
+ return waitForSignal(reinterpret_cast<QObject *>(webEngineView->experimental()), SIGNAL(loadVisuallyCommitted()), timeout);
+}
+
+#endif /* UTIL_H */
diff --git a/tests/auto/quick/tests.pri b/tests/auto/quick/tests.pri
index 932407e66..b637c29c1 100644
--- a/tests/auto/quick/tests.pri
+++ b/tests/auto/quick/tests.pri
@@ -7,7 +7,9 @@ VPATH += $$_PRO_FILE_PWD_
TARGET = tst_$$TARGET
SOURCES += $${TARGET}.cpp
-INCLUDEPATH += $$PWD
+INCLUDEPATH += \
+ $$PWD \
+ ../shared
QT += testlib network quick webengine
diff --git a/tests/auto/widgets/qwebengineframe/tst_qwebengineframe.cpp b/tests/auto/widgets/qwebengineframe/tst_qwebengineframe.cpp
index 4b18f8e7a..9901bcd76 100644
--- a/tests/auto/widgets/qwebengineframe/tst_qwebengineframe.cpp
+++ b/tests/auto/widgets/qwebengineframe/tst_qwebengineframe.cpp
@@ -32,6 +32,7 @@
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QTextCodec>
+#include <QWebEngineSettings>
#ifndef QT_NO_OPENSSL
#include <qsslerror.h>
#endif
@@ -124,6 +125,7 @@ void tst_QWebEngineFrame::init()
{
m_view = new QWebEngineView();
m_page = m_view->page();
+ m_page->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
}
void tst_QWebEngineFrame::cleanup()
@@ -347,7 +349,7 @@ void tst_QWebEngineFrame::requestedUrl()
void tst_QWebEngineFrame::requestedUrlAfterSetAndLoadFailures()
{
QWebEnginePage page;
-
+ page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
const QUrl first("http://abcdef.abcdef/");
@@ -365,7 +367,6 @@ void tst_QWebEngineFrame::requestedUrlAfterSetAndLoadFailures()
::waitForSignal(&page, SIGNAL(loadFinished(bool)));
QCOMPARE(spy.count(), 2);
QCOMPARE(page.url(), first);
- QEXPECT_FAIL("", "Slight change: The requestedUrl() function catches the error page's entry here thus it results the error page's requested url.", Continue);
QCOMPARE(page.requestedUrl(), second);
QVERIFY(!spy.at(1).first().toBool());
}
@@ -1369,15 +1370,19 @@ void tst_QWebEngineFrame::setUrlHistory()
QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
QCOMPARE(m_page->url(), aboutBlank);
QCOMPARE(m_page->requestedUrl(), QUrl());
- QCOMPARE(collectHistoryUrls(m_page->history()), QStringList());
+ // Chromium stores navigation entry for every successful loads. The load of the empty page is committed and stored as about:blank.
+ QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << aboutBlank.toString());
url = QUrl("http://non.existent/");
m_page->setUrl(url);
expectedLoadFinishedCount++;
QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
- QCOMPARE(m_page->url(), url);
- QCOMPARE(m_page->requestedUrl(), url);
- QCOMPARE(collectHistoryUrls(m_page->history()), QStringList());
+ // When error page is disabled in case of LoadFail the entry of the unavailable page is not stored.
+ // We expect the url of the previously loaded page here.
+ QCOMPARE(m_page->url(), aboutBlank);
+ QCOMPARE(m_page->requestedUrl(), QUrl());
+ // Since the entry of the unavailable page is not stored it will not available in the history.
+ QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << aboutBlank.toString());
url = QUrl("qrc:/test1.html");
m_page->setUrl(url);
@@ -1385,25 +1390,31 @@ void tst_QWebEngineFrame::setUrlHistory()
QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
QCOMPARE(m_page->url(), url);
QCOMPARE(m_page->requestedUrl(), url);
- QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << QStringLiteral("qrc:/test1.html"));
+ QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << aboutBlank.toString() << QStringLiteral("qrc:/test1.html"));
m_page->setUrl(QUrl());
expectedLoadFinishedCount++;
QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
QCOMPARE(m_page->url(), aboutBlank);
QCOMPARE(m_page->requestedUrl(), QUrl());
- QEXPECT_FAIL("", "Slight change: load(QUrl()) currently loads about:blank and nothing prevents it from being added to the history.", Continue);
- QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << QStringLiteral("qrc:/test1.html"));
+ // Chromium stores navigation entry for every successful loads. The load of the empty page is committed and stored as about:blank.
+ QCOMPARE(collectHistoryUrls(m_page->history()), QStringList()
+ << aboutBlank.toString()
+ << QStringLiteral("qrc:/test1.html")
+ << aboutBlank.toString());
- // Loading same page as current in history, so history count doesn't change.
url = QUrl("qrc:/test1.html");
m_page->setUrl(url);
expectedLoadFinishedCount++;
QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
QCOMPARE(m_page->url(), url);
QCOMPARE(m_page->requestedUrl(), url);
- QEXPECT_FAIL("", "Slight change: load(QUrl()) currently loads about:blank and nothing prevents it from being added to the history.", Continue);
- QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << QStringLiteral("qrc:/test1.html"));
+ // The history count DOES change since the about:blank is in the list.
+ QCOMPARE(collectHistoryUrls(m_page->history()), QStringList()
+ << aboutBlank.toString()
+ << QStringLiteral("qrc:/test1.html")
+ << aboutBlank.toString()
+ << QStringLiteral("qrc:/test1.html"));
url = QUrl("qrc:/test2.html");
m_page->setUrl(url);
@@ -1411,8 +1422,12 @@ void tst_QWebEngineFrame::setUrlHistory()
QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
QCOMPARE(m_page->url(), url);
QCOMPARE(m_page->requestedUrl(), url);
- QEXPECT_FAIL("", "Slight change: load(QUrl()) currently loads about:blank and nothing prevents it from being added to the history.", Continue);
- QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << QStringLiteral("qrc:/test1.html") << QStringLiteral("qrc:/test2.html"));
+ QCOMPARE(collectHistoryUrls(m_page->history()), QStringList()
+ << aboutBlank.toString()
+ << QStringLiteral("qrc:/test1.html")
+ << aboutBlank.toString()
+ << QStringLiteral("qrc:/test1.html")
+ << QStringLiteral("qrc:/test2.html"));
}
void tst_QWebEngineFrame::setUrlUsingStateObject()
@@ -1534,7 +1549,6 @@ void tst_QWebEngineFrame::setUrlThenLoads()
// Just after first load. URL didn't changed yet.
m_page->load(urlToLoad1);
- QEXPECT_FAIL("", "Slight change: url() will return the loaded URL immediately.", Continue);
QCOMPARE(m_page->url(), url);
QCOMPARE(m_page->requestedUrl(), urlToLoad1);
// baseUrlSync spins an event loop and this sometimes return the next result.
@@ -1551,7 +1565,6 @@ void tst_QWebEngineFrame::setUrlThenLoads()
// Just after second load. URL didn't changed yet.
m_page->load(urlToLoad2);
- QEXPECT_FAIL("", "Slight change: url() will return the loaded URL immediately.", Continue);
QCOMPARE(m_page->url(), urlToLoad1);
QCOMPARE(m_page->requestedUrl(), urlToLoad2);
QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad1));
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index f0a89d9aa..85939a686 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -191,6 +191,8 @@ private Q_SLOTS:
void macCopyUnicodeToClipboard();
#endif
+ void runJavaScript();
+
private:
QWebEngineView* m_view;
QWebEnginePage* m_page;
@@ -3563,14 +3565,14 @@ void tst_QWebEnginePage::getUserMediaRequest()
QVERIFY(evaluateJavaScriptSync(page, QStringLiteral("!!navigator.webkitGetUserMedia")).toBool());
evaluateJavaScriptSync(page, QStringLiteral("navigator.webkitGetUserMedia({audio: true}, function() {}, function(){})"));
- QTRY_VERIFY_WITH_TIMEOUT(page->gotFeatureRequest(QWebEnginePage::MediaAudioDevices), 100);
+ QTRY_VERIFY_WITH_TIMEOUT(page->gotFeatureRequest(QWebEnginePage::MediaAudioCapture), 100);
// Might end up failing due to the lack of physical media devices deeper in the content layer, so the JS callback is not guaranteed to be called,
// but at least we go through that code path, potentially uncovering failing assertions.
page->acceptPendingRequest();
page->runJavaScript(QStringLiteral("errorCallbackCalled = false;"));
evaluateJavaScriptSync(page, QStringLiteral("navigator.webkitGetUserMedia({audio: true, video: true}, function() {}, function(){errorCallbackCalled = true;})"));
- QTRY_VERIFY_WITH_TIMEOUT(page->gotFeatureRequest(QWebEnginePage::MediaAudioVideoDevices), 100);
+ QTRY_VERIFY_WITH_TIMEOUT(page->gotFeatureRequest(QWebEnginePage::MediaAudioVideoCapture), 100);
page->rejectPendingRequest(); // Should always end up calling the error callback in JS.
QTRY_VERIFY_WITH_TIMEOUT(evaluateJavaScriptSync(page, QStringLiteral("errorCallbackCalled;")).toBool(), 100);
delete page;
@@ -3666,5 +3668,71 @@ void tst_QWebEnginePage::cssMediaTypePageSetting()
#endif
}
+class JavaScriptCallback
+{
+public:
+ JavaScriptCallback() { }
+ JavaScriptCallback(const QVariant& _expected) : expected(_expected) { }
+ virtual void operator() (const QVariant& result) {
+ QVERIFY(result.isValid());
+ QCOMPARE(result, expected);
+ }
+private:
+ QVariant expected;
+};
+
+class JavaScriptCallbackNull
+{
+public:
+ virtual void operator() (const QVariant& result) {
+ QVERIFY(result.isNull());
+// FIXME: Returned null values are currently invalid QVariants.
+// QVERIFY(result.isValid());
+ }
+};
+
+class JavaScriptCallbackUndefined
+{
+public:
+ virtual void operator() (const QVariant& result) {
+ QVERIFY(result.isNull());
+ QVERIFY(!result.isValid());
+ }
+};
+
+void tst_QWebEnginePage::runJavaScript()
+{
+ TestPage page;
+
+ JavaScriptCallback callbackBool(QVariant(false));
+ page.runJavaScript("false", QWebEngineCallback<const QVariant&>(callbackBool));
+
+ JavaScriptCallback callbackInt(QVariant(2));
+ page.runJavaScript("2", QWebEngineCallback<const QVariant&>(callbackInt));
+
+ JavaScriptCallback callbackDouble(QVariant(2.5));
+ page.runJavaScript("2.5", QWebEngineCallback<const QVariant&>(callbackDouble));
+
+ JavaScriptCallback callbackString(QVariant(QStringLiteral("Test")));
+ page.runJavaScript("\"Test\"", QWebEngineCallback<const QVariant&>(callbackString));
+
+ QVariantList list;
+ JavaScriptCallback callbackList(list);
+ page.runJavaScript("[]", QWebEngineCallback<const QVariant&>(callbackList));
+
+ QVariantMap map;
+ map.insert(QStringLiteral("test"), QVariant(2));
+ JavaScriptCallback callbackMap(map);
+ page.runJavaScript("var el = {\"test\": 2}; el", QWebEngineCallback<const QVariant&>(callbackMap));
+
+ JavaScriptCallbackNull callbackNull;
+ page.runJavaScript("null", QWebEngineCallback<const QVariant&>(callbackNull));
+
+ JavaScriptCallbackNull callbackUndefined;
+ page.runJavaScript("undefined", QWebEngineCallback<const QVariant&>(callbackUndefined));
+
+ QTest::qWait(100);
+}
+
QTEST_MAIN(tst_QWebEnginePage)
#include "tst_qwebenginepage.moc"
diff --git a/tests/quicktestbrowser/quickwindow.qml b/tests/quicktestbrowser/quickwindow.qml
index 36668fc6d..b1be6db3e 100644
--- a/tests/quicktestbrowser/quickwindow.qml
+++ b/tests/quicktestbrowser/quickwindow.qml
@@ -70,6 +70,7 @@ ApplicationWindow {
Settings {
property alias autoLoadImages: loadImages.checked;
property alias javaScriptEnabled: javaScriptEnabled.checked;
+ property alias errorPageEnabled: errorPageEnabled.checked;
}
// Make sure the Qt.WindowFullscreenButtonHint is set on Mac.
@@ -227,6 +228,13 @@ ApplicationWindow {
checked: WebEngine.settings.javascriptEnabled
onCheckedChanged: WebEngine.settings.javascriptEnabled = checked
}
+ MenuItem {
+ id: errorPageEnabled
+ text: "ErrorPage On"
+ checkable: true
+ checked: WebEngine.settings.errorPageEnabled
+ onCheckedChanged: WebEngine.settings.errorPageEnabled = checked
+ }
}
}
}
diff --git a/tools/buildscripts/repack_locales.py b/tools/buildscripts/repack_locales.py
index 05e2895ed..389e9b1fd 100755
--- a/tools/buildscripts/repack_locales.py
+++ b/tools/buildscripts/repack_locales.py
@@ -77,15 +77,7 @@ class Usage(Exception):
def calc_output(locale):
"""Determine the file that will be generated for the given locale."""
#e.g. '<(INTERMEDIATE_DIR)/repack/qtwebengine_locales/da.pak',
- if OS == 'mac' or OS == 'ios':
- # For Cocoa to find the locale at runtime, it needs to use '_' instead
- # of '-' (http://crbug.com/20441). Also, 'en-US' should be represented
- # simply as 'en' (http://crbug.com/19165, http://crbug.com/25578).
- if locale == 'en-US':
- locale = 'en'
- return '%s/repack/qtwebengine_locales/%s.lproj/locale.pak' % (INT_DIR, locale.replace('-', '_'))
- else:
- return os.path.join(INT_DIR, 'repack/qtwebengine_locales', locale + '.pak')
+ return os.path.join(INT_DIR, 'repack/qtwebengine_locales', locale + '.pak')
def calc_inputs(locale):
diff --git a/tools/qmake/mkspecs/features/functions.prf b/tools/qmake/mkspecs/features/functions.prf
index 80b64a653..acf15a811 100644
--- a/tools/qmake/mkspecs/features/functions.prf
+++ b/tools/qmake/mkspecs/features/functions.prf
@@ -1,9 +1,32 @@
defineTest(isPlatformSupported) {
static: return(false)
- !equals(QMAKE_HOST.arch, "x86_64"): return(false)
- osx:lessThan(QMAKE_XCODE_VERSION, 5.1): return(false)
+ osx:lessThan(QMAKE_XCODE_VERSION, 5.1) {
+ warning("Using xcode version $$QMAKE_XCODE_VERSION, but at least version 5.1 is required to build Qt WebEngine.")
+ return(false)
+ }
+
+ linux-g++*:!isGCCVersionSupported():return(false)
+ !isPythonVersionSupported(): return(false)
+ linux-g++*|win32-msvc2013|macx-clang: return(true)
+ boot2qt: return(true)
+
+ warning("Qt WebEngine can currently only be built for Linux (GCC), Windows (MSVC 2013), OS X (XCode 5.1+) or Qt for Device Creation".)
+ return(false)
+}
- linux|win32-msvc2013|macx-clang: return(true)
+defineTest(isPythonVersionSupported) {
+ python_major_version = $$system('python -c "import sys; print sys.version_info.major"')
+ python_minor_version = $$system('python -c "import sys; print sys.version_info.minor"')
+ greaterThan(python_major_version, 1): greaterThan(python_minor_version, 6): return(true)
+ warning("Using Python version "$$python_major_version"."$$python_minor_version", but at least Python version 2.7 is required to build Qt WebEngine.")
+ return(false)
+}
+
+defineTest(isGCCVersionSupported) {
+ # The below will work for gcc 4.6 and up and also match gcc 5
+ greaterThan(QT_GCC_MINOR_VERSION, 5):return(true)
+ greaterThan(QT_GCC_MAJOR_VERSION, 4):return(true)
+ warning("Using gcc version "$$QT_GCC_MAJOR_VERSION"."$$QT_GCC_MINOR_VERSION", but at least gcc version 4.6 is required to build Qt WebEngine.")
return(false)
}
@@ -35,7 +58,7 @@ defineReplace(getChromiumSrcDir) {
}
defineReplace(extractCFlag) {
- CFLAGS = $$QMAKE_CFLAGS
+ CFLAGS = $$QMAKE_CC $$QMAKE_CFLAGS
!isEmpty(ANDROID_TARGET_CFLAGS): CFLAGS = $$ANDROID_TARGET_CFLAGS
OPTION = $$find(CFLAGS, $$1)
OPTION = $$split(OPTION, =)
@@ -105,10 +128,15 @@ defineReplace(which) {
}
defineReplace(findOrBuildNinja) {
- out = $$absolute_path("$${getChromiumSrcDir()}/../ninja/ninja", "$$QTWEBENGINE_ROOT")
- win32: out = $$system_path($${out}.exe)
+ # If NINJA_PATH env var is set, prefer that.
+ # Fallback to locating our own bootstrapped ninja.
+ out = $(NINJA_PATH)
+ !exists($$out) {
+ out = $$absolute_path("$${getChromiumSrcDir()}/../ninja/ninja", "$$QTWEBENGINE_ROOT")
+ win32: out = $$system_path($${out}.exe)
- # If we did not find ninja, then we bootstrap it.
- !exists($$out): system("python $$dirname(out)/bootstrap.py")
+ # If we did not find ninja, then we bootstrap it.
+ !exists($$out): system("python $$dirname(out)/bootstrap.py")
+ }
return($$out)
}