summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/CMakeLists.txt3
-rw-r--r--src/core/api/qwebenginepage.cpp5
-rw-r--r--src/core/content_browser_client_qt.cpp1
-rw-r--r--src/core/extensions/plugin_service_filter_qt.cpp1
-rw-r--r--src/core/favicon_driver_qt.cpp407
-rw-r--r--src/core/favicon_driver_qt.h168
-rw-r--r--src/core/favicon_manager.cpp437
-rw-r--r--src/core/favicon_manager.h151
-rw-r--r--src/core/favicon_service_factory_qt.cpp193
-rw-r--r--src/core/favicon_service_factory_qt.h146
-rw-r--r--src/core/net/plugin_response_interceptor_url_loader_throttle.cpp1
-rw-r--r--src/core/profile_adapter.cpp33
-rw-r--r--src/core/profile_adapter.h1
-rw-r--r--src/core/profile_qt.cpp18
-rw-r--r--src/core/profile_qt.h1
-rw-r--r--src/core/qtwebengine.gni2
-rw-r--r--src/core/type_conversion.cpp46
-rw-r--r--src/core/type_conversion.h5
-rw-r--r--src/core/visited_links_manager_qt.cpp17
-rw-r--r--src/core/web_contents_adapter.cpp28
-rw-r--r--src/core/web_contents_adapter.h2
-rw-r--r--src/core/web_contents_delegate_qt.cpp29
-rw-r--r--src/core/web_contents_delegate_qt.h4
-rw-r--r--src/core/web_engine_library_info.cpp1
-rw-r--r--src/webenginequick/api/qquickwebenginefaviconprovider.cpp184
-rw-r--r--src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h19
-rw-r--r--src/webenginequick/api/qquickwebengineview.cpp31
-rw-r--r--src/webenginequick/api/qquickwebengineview_p.h1
-rw-r--r--src/webenginequick/api/qquickwebengineview_p_p.h2
-rw-r--r--tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp10
-rw-r--r--tests/auto/quick/qmltests/CMakeLists.txt3
-rw-r--r--tests/auto/quick/qmltests/data/favicon-misc.html4
-rw-r--r--tests/auto/quick/qmltests/data/tst_favicon.qml337
-rw-r--r--tests/auto/quick/qmltests/data/tst_faviconDownload.qml121
-rw-r--r--tests/auto/widgets/CMakeLists.txt2
-rw-r--r--tests/auto/widgets/favicon/CMakeLists.txt (renamed from tests/auto/widgets/faviconmanager/CMakeLists.txt)10
-rw-r--r--tests/auto/widgets/favicon/favicon.pro (renamed from tests/auto/widgets/faviconmanager/faviconmanager.pro)0
-rw-r--r--tests/auto/widgets/favicon/resources/favicon-misc.html (renamed from tests/auto/widgets/faviconmanager/resources/favicon-misc.html)4
-rw-r--r--tests/auto/widgets/favicon/resources/favicon-multi.html (renamed from tests/auto/widgets/faviconmanager/resources/favicon-multi.html)2
-rw-r--r--tests/auto/widgets/favicon/resources/favicon-shortcut.html (renamed from tests/auto/widgets/faviconmanager/resources/favicon-shortcut.html)0
-rw-r--r--tests/auto/widgets/favicon/resources/favicon-single.html (renamed from tests/auto/widgets/faviconmanager/resources/favicon-single.html)0
-rw-r--r--tests/auto/widgets/favicon/resources/favicon-touch.html (renamed from tests/auto/widgets/faviconmanager/resources/favicon-touch.html)0
-rw-r--r--tests/auto/widgets/favicon/resources/favicon-unavailable.html (renamed from tests/auto/widgets/faviconmanager/resources/favicon-unavailable.html)0
-rw-r--r--tests/auto/widgets/favicon/resources/icons/qt144.png (renamed from tests/auto/widgets/faviconmanager/resources/icons/qt144.png)bin8315 -> 8315 bytes
-rw-r--r--tests/auto/widgets/favicon/resources/icons/qt32.ico (renamed from tests/auto/widgets/faviconmanager/resources/icons/qt32.ico)bin4286 -> 4286 bytes
-rw-r--r--tests/auto/widgets/favicon/resources/icons/qtmulti.ico (renamed from tests/auto/widgets/faviconmanager/resources/icons/qtmulti.ico)bin22382 -> 22382 bytes
-rw-r--r--tests/auto/widgets/favicon/resources/test1.html (renamed from tests/auto/widgets/faviconmanager/resources/test1.html)0
-rw-r--r--tests/auto/widgets/favicon/tst_favicon.cpp (renamed from tests/auto/widgets/faviconmanager/tst_faviconmanager.cpp)282
-rw-r--r--tests/auto/widgets/favicon/tst_favicon.qrc (renamed from tests/auto/widgets/faviconmanager/tst_faviconmanager.qrc)0
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp6
-rw-r--r--tests/manual/quick/faviconbrowser/AddressBar.qml102
-rw-r--r--tests/manual/quick/faviconbrowser/FaviconPanel.qml234
-rw-r--r--tests/manual/quick/faviconbrowser/faviconbrowser.pro23
-rw-r--r--tests/manual/quick/faviconbrowser/faviconbrowser.qrc17
-rw-r--r--tests/manual/quick/faviconbrowser/main.cpp54
-rw-r--r--tests/manual/quick/faviconbrowser/main.qml170
-rw-r--r--tests/manual/quick/faviconbrowser/utils.h49
57 files changed, 1484 insertions, 1883 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 2a545f5b2..b32415028 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -91,7 +91,8 @@ foreach(config ${configs})
devtools_frontend_qt.cpp devtools_frontend_qt.h
devtools_manager_delegate_qt.cpp devtools_manager_delegate_qt.h
download_manager_delegate_qt.cpp download_manager_delegate_qt.h
- favicon_manager.cpp favicon_manager.h
+ favicon_driver_qt.cpp favicon_driver_qt.h
+ favicon_service_factory_qt.cpp favicon_service_factory_qt.h
file_picker_controller.cpp file_picker_controller.h
find_text_helper.cpp find_text_helper.h
global_descriptors_qt.h
diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index 6e2b37514..64b4f4d99 100644
--- a/src/core/api/qwebenginepage.cpp
+++ b/src/core/api/qwebenginepage.cpp
@@ -44,7 +44,6 @@
#include "authentication_dialog_controller.h"
#include "profile_adapter.h"
#include "color_chooser_controller.h"
-#include "favicon_manager.h"
#include "find_text_helper.h"
#include "file_picker_controller.h"
#include "javascript_dialog_controller.h"
@@ -255,7 +254,7 @@ void QWebEnginePagePrivate::iconChanged(const QUrl &url)
return;
iconUrl = url;
Q_EMIT q->iconUrlChanged(iconUrl);
- Q_EMIT q->iconChanged(adapter->faviconManager()->getIcon());
+ Q_EMIT q->iconChanged(iconUrl.isEmpty() ? QIcon() : adapter->icon());
}
void QWebEnginePagePrivate::loadProgressChanged(int progress)
@@ -1980,7 +1979,7 @@ QIcon QWebEnginePage::icon() const
if (d->iconUrl.isEmpty() || !d->adapter->isInitialized())
return QIcon();
- return d->adapter->faviconManager()->getIcon();
+ return d->adapter->icon();
}
qreal QWebEnginePage::zoomFactor() const
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index d68cad2b0..fdcd98024 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -113,6 +113,7 @@
#include "web_contents_view_qt.h"
#include "web_engine_context.h"
#include "web_engine_library_info.h"
+#include "web_engine_settings.h"
#include "api/qwebenginecookiestore.h"
#include "api/qwebenginecookiestore_p.h"
diff --git a/src/core/extensions/plugin_service_filter_qt.cpp b/src/core/extensions/plugin_service_filter_qt.cpp
index 94cf5cb27..778f803c3 100644
--- a/src/core/extensions/plugin_service_filter_qt.cpp
+++ b/src/core/extensions/plugin_service_filter_qt.cpp
@@ -43,6 +43,7 @@
#include "content/public/browser/web_contents.h"
#include "web_contents_delegate_qt.h"
+#include "web_engine_settings.h"
using namespace QtWebEngineCore;
diff --git a/src/core/favicon_driver_qt.cpp b/src/core/favicon_driver_qt.cpp
new file mode 100644
index 000000000..a3bbd5939
--- /dev/null
+++ b/src/core/favicon_driver_qt.cpp
@@ -0,0 +1,407 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "favicon_driver_qt.h"
+#include "type_conversion.h"
+#include "web_contents_adapter_client.h"
+#include "web_engine_settings.h"
+
+#include "components/favicon/content/favicon_url_util.h"
+#include "components/favicon/core/favicon_service.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/favicon_status.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/navigation_handle.h"
+#include "third_party/blink/public/common/manifest/manifest.h"
+
+namespace QtWebEngineCore {
+
+namespace {
+
+void ExtractManifestIcons(FaviconDriverQt::ManifestDownloadCallback callback,
+ const GURL &manifest_url, const blink::Manifest &manifest)
+{
+ std::vector<favicon::FaviconURL> candidates;
+ for (const auto &icon : manifest.icons) {
+ candidates.emplace_back(icon.src, favicon_base::IconType::kWebManifestIcon, icon.sizes);
+ }
+ std::move(callback).Run(candidates);
+}
+
+int activeHandlersCount(QWebEngineSettings *settings)
+{
+ bool touchIconsEnabled = settings->testAttribute(QWebEngineSettings::TouchIconsEnabled);
+ return touchIconsEnabled ? 2 : 1;
+}
+
+} // namespace
+
+FaviconStatusQt::FaviconStatusQt()
+ : FaviconStatus(), source(favicon::FaviconDriverObserver::NON_TOUCH_16_DIP)
+{
+}
+
+// static
+void FaviconDriverQt::CreateForWebContents(content::WebContents *webContents,
+ favicon::FaviconService *faviconService,
+ WebContentsAdapterClient *viewClient)
+{
+ if (FromWebContents(webContents))
+ return;
+
+ webContents->SetUserData(
+ UserDataKey(),
+ base::WrapUnique(new FaviconDriverQt(webContents, faviconService, viewClient)));
+}
+
+FaviconDriverQt::FaviconDriverQt(content::WebContents *webContents,
+ favicon::FaviconService *faviconService,
+ WebContentsAdapterClient *viewClient)
+ : content::WebContentsObserver(webContents)
+ , m_faviconService(faviconService)
+ , m_viewClient(viewClient)
+{
+ if (!m_faviconService)
+ return;
+
+ m_handlers.push_back(std::make_unique<favicon::FaviconHandler>(
+ m_faviconService, this, favicon::FaviconDriverObserver::NON_TOUCH_16_DIP));
+ m_handlers.push_back(std::make_unique<favicon::FaviconHandler>(
+ m_faviconService, this, favicon::FaviconDriverObserver::NON_TOUCH_LARGEST));
+ m_handlers.push_back(std::make_unique<favicon::FaviconHandler>(
+ m_faviconService, this, favicon::FaviconDriverObserver::TOUCH_LARGEST));
+}
+
+void FaviconDriverQt::FetchFavicon(const GURL &page_url, bool is_same_document)
+{
+ QWebEngineSettings *settings = m_viewClient->webEngineSettings();
+ bool iconsEnabled = settings->testAttribute(QWebEngineSettings::AutoLoadIconsForPage);
+ bool touchIconsEnabled = settings->testAttribute(QWebEngineSettings::TouchIconsEnabled);
+
+ if (!iconsEnabled)
+ return;
+
+ for (const std::unique_ptr<favicon::FaviconHandler> &handler : m_handlers) {
+ switch (handler->Type()) {
+ case favicon::FaviconDriverObserver::NON_TOUCH_16_DIP:
+ if (touchIconsEnabled)
+ continue;
+ break;
+ case favicon::FaviconDriverObserver::NON_TOUCH_LARGEST:
+ case favicon::FaviconDriverObserver::TOUCH_LARGEST:
+ if (!touchIconsEnabled)
+ continue;
+ break;
+ }
+
+ handler->FetchFavicon(page_url, is_same_document);
+ }
+}
+
+gfx::Image FaviconDriverQt::GetFavicon() const
+{
+ // Like GetTitle(), we also want to use the favicon for the last committed
+ // entry rather than a pending navigation entry.
+ content::NavigationController &controller = web_contents()->GetController();
+
+ content::NavigationEntry *entry = controller.GetLastCommittedEntry();
+ if (entry)
+ return entry->GetFavicon().image;
+ return gfx::Image();
+}
+
+bool FaviconDriverQt::FaviconIsValid() const
+{
+ content::NavigationController &controller = web_contents()->GetController();
+
+ content::NavigationEntry *entry = controller.GetLastCommittedEntry();
+ if (entry)
+ return entry->GetFavicon().valid;
+
+ return false;
+}
+
+GURL FaviconDriverQt::GetActiveURL()
+{
+ content::NavigationEntry *entry = web_contents()->GetController().GetLastCommittedEntry();
+ return entry ? entry->GetURL() : GURL();
+}
+
+GURL FaviconDriverQt::GetFaviconURL() const
+{
+ content::NavigationController &controller = web_contents()->GetController();
+
+ content::NavigationEntry *entry = controller.GetLastCommittedEntry();
+ if (entry)
+ return entry->GetFavicon().url;
+ return GURL();
+}
+
+int FaviconDriverQt::DownloadImage(const GURL &url, int max_image_size,
+ ImageDownloadCallback callback)
+{
+ bool bypass_cache = (m_bypassCachePageURL == GetActiveURL());
+ m_bypassCachePageURL = GURL();
+
+ return web_contents()->DownloadImage(url, true, /*preferred_size=*/max_image_size,
+ /*max_bitmap_size=*/max_image_size, bypass_cache,
+ std::move(callback));
+}
+
+void FaviconDriverQt::DownloadManifest(const GURL &url, ManifestDownloadCallback callback)
+{
+ web_contents()->GetManifest(base::BindOnce(&ExtractManifestIcons, std::move(callback)));
+}
+
+bool FaviconDriverQt::IsOffTheRecord()
+{
+ DCHECK(web_contents());
+ return web_contents()->GetBrowserContext()->IsOffTheRecord();
+}
+
+void FaviconDriverQt::OnFaviconUpdated(
+ const GURL &page_url,
+ favicon::FaviconDriverObserver::NotificationIconType notification_icon_type,
+ const GURL &icon_url, bool icon_url_changed, const gfx::Image &image)
+{
+ Q_UNUSED(page_url);
+
+ QWebEngineSettings *settings = m_viewClient->webEngineSettings();
+ bool touchIconsEnabled = settings->testAttribute(QWebEngineSettings::TouchIconsEnabled);
+
+ // Prefer touch icons over favicons if touch icons are enabled.
+ if (!touchIconsEnabled
+ || m_latestFavicon.source != favicon::FaviconDriverObserver::TOUCH_LARGEST
+ || notification_icon_type == favicon::FaviconDriverObserver::TOUCH_LARGEST) {
+ m_latestFavicon.valid = true;
+ m_latestFavicon.url = icon_url;
+ m_latestFavicon.image = image;
+ m_latestFavicon.source = notification_icon_type;
+ }
+
+ NotifyFaviconUpdatedObservers(notification_icon_type, icon_url, icon_url_changed, image);
+ emitIconChangedIfNeeded();
+}
+
+void FaviconDriverQt::OnFaviconDeleted(
+ const GURL &page_url,
+ favicon::FaviconDriverObserver::NotificationIconType notification_icon_type)
+{
+ content::NavigationEntry *entry = web_contents()->GetController().GetLastCommittedEntry();
+ DCHECK(entry && entry->GetURL() == page_url);
+
+ entry->GetFavicon() = FaviconStatusQt();
+ web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB);
+
+ NotifyFaviconUpdatedObservers(notification_icon_type, /*icon_url=*/GURL(),
+ /*icon_url_changed=*/true, FaviconStatusQt().image);
+}
+
+void FaviconDriverQt::OnHandlerCompleted(favicon::FaviconHandler *handler)
+{
+ Q_UNUSED(handler);
+
+ if (activeHandlersCount(m_viewClient->webEngineSettings()) > m_completedHandlersCount)
+ ++m_completedHandlersCount;
+ emitIconChangedIfNeeded();
+}
+
+void FaviconDriverQt::DidUpdateFaviconURL(
+ content::RenderFrameHost *render_frame_host,
+ const std::vector<blink::mojom::FaviconURLPtr> &candidates)
+{
+ Q_UNUSED(render_frame_host);
+
+ // Ignore the update if there is no last committed navigation entry. This can
+ // occur when loading an initially blank page.
+ content::NavigationEntry *entry = web_contents()->GetController().GetLastCommittedEntry();
+ if (!entry)
+ return;
+
+ // We update |m_faviconUrls| even if the list is believed to be partial
+ // (checked below), because callers of our getter favicon_urls() expect so.
+ std::vector<blink::mojom::FaviconURL> faviconUrls;
+ for (const auto &candidate : candidates)
+ faviconUrls.push_back(*candidate);
+ m_faviconUrls = faviconUrls;
+
+ if (!m_documentOnLoadCompleted)
+ return;
+
+ OnUpdateCandidates(entry->GetURL(),
+ favicon::FaviconURLsFromContentFaviconURLs(
+ m_faviconUrls.value_or(std::vector<blink::mojom::FaviconURL>())),
+ m_manifestUrl);
+}
+
+void FaviconDriverQt::DidUpdateWebManifestURL(content::RenderFrameHost *target_frame,
+ const base::Optional<GURL> &manifest_url)
+{
+ Q_UNUSED(target_frame);
+
+ // Ignore the update if there is no last committed navigation entry. This can
+ // occur when loading an initially blank page.
+ content::NavigationEntry *entry = web_contents()->GetController().GetLastCommittedEntry();
+ if (!entry || !m_documentOnLoadCompleted)
+ return;
+
+ m_manifestUrl = manifest_url.value_or(GURL());
+
+ // On regular page loads, DidUpdateManifestURL() is guaranteed to be called
+ // before DidUpdateFaviconURL(). However, a page can update the favicons via
+ // javascript.
+ if (m_faviconUrls.has_value()) {
+ OnUpdateCandidates(entry->GetURL(),
+ favicon::FaviconURLsFromContentFaviconURLs(*m_faviconUrls),
+ m_manifestUrl);
+ }
+}
+
+void FaviconDriverQt::DidStartNavigation(content::NavigationHandle *navigation_handle)
+{
+ if (!navigation_handle->IsInMainFrame())
+ return;
+
+ m_faviconUrls.reset();
+ m_completedHandlersCount = 0;
+ m_latestFavicon = FaviconStatusQt();
+
+ if (!navigation_handle->IsSameDocument()) {
+ m_documentOnLoadCompleted = false;
+ m_manifestUrl = GURL();
+ }
+
+ m_viewClient->iconChanged(QUrl());
+
+ content::ReloadType reload_type = navigation_handle->GetReloadType();
+ if (reload_type == content::ReloadType::NONE || IsOffTheRecord())
+ return;
+
+ m_bypassCachePageURL = navigation_handle->GetURL();
+ SetFaviconOutOfDateForPage(navigation_handle->GetURL(),
+ reload_type == content::ReloadType::BYPASSING_CACHE);
+}
+
+void FaviconDriverQt::DidFinishNavigation(content::NavigationHandle *navigation_handle)
+{
+ if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted()
+ || navigation_handle->IsErrorPage()) {
+ return;
+ }
+
+ // Wait till the user navigates to a new URL to start checking the cache
+ // again. The cache may be ignored for non-reload navigations (e.g.
+ // history.replace() in-page navigation). This is allowed to increase the
+ // likelihood that "reloading a page ignoring the cache" redownloads the
+ // favicon. In particular, a page may do an in-page navigation before
+ // FaviconHandler has the time to determine that the favicon needs to be
+ // redownloaded.
+ GURL url = navigation_handle->GetURL();
+ if (url != m_bypassCachePageURL)
+ m_bypassCachePageURL = GURL();
+
+ // Get the favicon, either from history or request it from the net.
+ FetchFavicon(url, navigation_handle->IsSameDocument());
+}
+
+void FaviconDriverQt::DocumentOnLoadCompletedInMainFrame()
+{
+ m_documentOnLoadCompleted = true;
+}
+
+void FaviconDriverQt::SetFaviconOutOfDateForPage(const GURL &url, bool force_reload)
+{
+ if (m_faviconService) {
+ m_faviconService->SetFaviconOutOfDateForPage(url);
+ if (force_reload)
+ m_faviconService->ClearUnableToDownloadFavicons();
+ }
+}
+
+void FaviconDriverQt::OnUpdateCandidates(const GURL &page_url,
+ const std::vector<favicon::FaviconURL> &candidates,
+ const GURL &manifest_url)
+{
+ QWebEngineSettings *settings = m_viewClient->webEngineSettings();
+ bool touchIconsEnabled = settings->testAttribute(QWebEngineSettings::TouchIconsEnabled);
+ for (const std::unique_ptr<favicon::FaviconHandler> &handler : m_handlers) {
+ switch (handler->Type()) {
+ case favicon::FaviconDriverObserver::NON_TOUCH_16_DIP:
+ if (touchIconsEnabled)
+ continue;
+ break;
+ case favicon::FaviconDriverObserver::NON_TOUCH_LARGEST:
+ case favicon::FaviconDriverObserver::TOUCH_LARGEST:
+ if (!touchIconsEnabled)
+ continue;
+ break;
+ }
+
+ // We feed in the Web Manifest URL (if any) to the instance handling type
+ // kWebManifestIcon, because those compete which each other (i.e. manifest
+ // icons override inline touch icons).
+ handler->OnUpdateCandidates(
+ page_url, candidates,
+ (handler->icon_types().count(favicon_base::IconType::kWebManifestIcon) != 0)
+ ? manifest_url
+ : GURL::EmptyGURL());
+ }
+}
+
+void FaviconDriverQt::emitIconChangedIfNeeded()
+{
+ if (activeHandlersCount(m_viewClient->webEngineSettings()) != m_completedHandlersCount)
+ return;
+
+ content::NavigationEntry *entry = web_contents()->GetController().GetLastCommittedEntry();
+ DCHECK(entry);
+
+ if (entry->GetFavicon().url != m_latestFavicon.url) {
+ entry->GetFavicon().valid = m_latestFavicon.valid;
+ entry->GetFavicon().url = m_latestFavicon.url;
+ entry->GetFavicon().image = m_latestFavicon.image;
+ web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB);
+ }
+
+ m_viewClient->iconChanged(toQt(m_latestFavicon.url));
+}
+
+WEB_CONTENTS_USER_DATA_KEY_IMPL(FaviconDriverQt)
+
+} // namespace QtWebEngineCore
diff --git a/src/core/favicon_driver_qt.h b/src/core/favicon_driver_qt.h
new file mode 100644
index 000000000..b49017946
--- /dev/null
+++ b/src/core/favicon_driver_qt.h
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef FAVICON_DRIVER_QT_H
+#define FAVICON_DRIVER_QT_H
+
+#include "qtwebenginecoreglobal_p.h"
+
+#include "components/favicon/core/favicon_driver.h"
+#include "components/favicon/core/favicon_handler.h"
+#include "content/public/browser/favicon_status.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+#include "third_party/blink/public/mojom/favicon/favicon_url.mojom.h"
+
+namespace content {
+class WebContents;
+}
+
+namespace favicon {
+class FaviconService;
+}
+
+namespace QtWebEngineCore {
+
+class WebContentsAdapterClient;
+
+struct FaviconStatusQt : public content::FaviconStatus
+{
+ FaviconStatusQt();
+
+ // Type of the favicon::FaviconHandler that provided this icon.
+ favicon::FaviconDriverObserver::NotificationIconType source;
+};
+
+class FaviconDriverQt : public favicon::FaviconDriver,
+ public favicon::FaviconHandler::Delegate,
+ public content::WebContentsObserver,
+ public content::WebContentsUserData<FaviconDriverQt>
+{
+public:
+ static void CreateForWebContents(content::WebContents *webContents,
+ favicon::FaviconService *faviconService,
+ WebContentsAdapterClient *viewClient);
+
+ // FaviconDriver implementation.
+ void FetchFavicon(const GURL &page_url, bool is_same_document) override;
+ gfx::Image GetFavicon() const override;
+ bool FaviconIsValid() const override;
+ GURL GetActiveURL() override;
+
+ GURL GetFaviconURL() const;
+
+protected:
+ FaviconDriverQt(content::WebContents *webContent, favicon::FaviconService *faviconService,
+ WebContentsAdapterClient *viewClient);
+
+private:
+ friend class content::WebContentsUserData<FaviconDriverQt>;
+
+ // FaviconHandler::Delegate implementation.
+ int DownloadImage(const GURL &url, int max_image_size, ImageDownloadCallback callback) override;
+ void DownloadManifest(const GURL &url, ManifestDownloadCallback callback) override;
+ bool IsOffTheRecord() override;
+ void OnFaviconUpdated(const GURL &page_url,
+ favicon::FaviconDriverObserver::NotificationIconType icon_type,
+ const GURL &icon_url, bool icon_url_changed,
+ const gfx::Image &image) override;
+ void OnFaviconDeleted(
+ const GURL &page_url,
+ favicon::FaviconDriverObserver::NotificationIconType notification_icon_type) override;
+ void OnHandlerCompleted(favicon::FaviconHandler *handler) override;
+
+ // content::WebContentsObserver implementation.
+ void DidUpdateFaviconURL(content::RenderFrameHost *render_frame_host,
+ const std::vector<blink::mojom::FaviconURLPtr> &candidates) override;
+ void DidUpdateWebManifestURL(content::RenderFrameHost *target_frame,
+ const base::Optional<GURL> &manifest_url) override;
+ void DidStartNavigation(content::NavigationHandle *navigation_handle) override;
+ void DidFinishNavigation(content::NavigationHandle *navigation_handle) override;
+ void DocumentOnLoadCompletedInMainFrame() override;
+
+ // Informs FaviconService that the favicon for |url| is out of date. If
+ // |force_reload| is true, then discard information about favicon download
+ // failures.
+ void SetFaviconOutOfDateForPage(const GURL &url, bool force_reload);
+
+ // Broadcasts new favicon URL candidates to FaviconHandlers.
+ void OnUpdateCandidates(const GURL &page_url,
+ const std::vector<favicon::FaviconURL> &candidates,
+ const GURL &manifest_url);
+
+ void emitIconChangedIfNeeded();
+
+ // KeyedService used by FaviconDriverImpl. It may be null during testing,
+ // but if it is defined, it must outlive the FaviconDriverImpl.
+ favicon::FaviconService *m_faviconService;
+
+ WebContentsAdapterClient *m_viewClient;
+
+ // FaviconHandlers used to download the different kind of favicons.
+ std::vector<std::unique_ptr<favicon::FaviconHandler>> m_handlers;
+
+ GURL m_bypassCachePageURL;
+ bool m_documentOnLoadCompleted = false;
+
+ // nullopt until the actual list is reported via DidUpdateFaviconURL().
+ base::Optional<std::vector<blink::mojom::FaviconURL>> m_faviconUrls;
+ // Web Manifest URL or empty URL if none.
+ GURL m_manifestUrl;
+
+ int m_completedHandlersCount = 0;
+ FaviconStatusQt m_latestFavicon;
+
+ WEB_CONTENTS_USER_DATA_KEY_DECL();
+ DISALLOW_COPY_AND_ASSIGN(FaviconDriverQt);
+};
+
+} // namespace QtWebEngineCore
+
+#endif // FAVICON_DRIVER_QT_H
diff --git a/src/core/favicon_manager.cpp b/src/core/favicon_manager.cpp
deleted file mode 100644
index 3cb417c4f..000000000
--- a/src/core/favicon_manager.cpp
+++ /dev/null
@@ -1,437 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "favicon_manager.h"
-#include "type_conversion.h"
-#include "web_contents_adapter_client.h"
-#include "web_engine_settings.h"
-
-#include "base/bind.h"
-#include "content/public/browser/favicon_status.h"
-#include "content/public/browser/navigation_entry.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/common/url_constants.h"
-#include "net/base/data_url.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkPixelRef.h"
-#include "ui/gfx/geometry/size.h"
-
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-#include <qiconengine.h>
-#include <private/qicon_p.h>
-#endif
-
-namespace QtWebEngineCore {
-
-static inline bool isResourceUrl(const QUrl &url)
-{
- return !url.scheme().compare(QLatin1String("qrc"));
-}
-
-static inline bool isDataUrl(const QUrl &url)
-{
- return !url.scheme().compare(QLatin1String(url::kDataScheme));
-}
-
-static inline unsigned area(const QSize &size)
-{
- return size.width() * size.height();
-}
-
-
-FaviconManager::FaviconManager(content::WebContents *webContents, WebContentsAdapterClient *viewClient)
- : m_webContents(webContents)
- , m_viewClient(viewClient)
- , m_candidateCount(0)
- , m_weakFactory(new base::WeakPtrFactory<FaviconManager>(this))
-{
-}
-
-FaviconManager::~FaviconManager()
-{
-}
-
-int FaviconManager::downloadIcon(const QUrl &url)
-{
- static const uint32_t maxSize = 256;
- static int fakeId = 0;
- int id;
-
- bool cached = m_icons.contains(url);
- if (isResourceUrl(url) || isDataUrl(url) || cached) {
- id = --fakeId;
- m_pendingRequests.insert(id, url);
- } else {
- id = m_webContents->DownloadImage(
- toGurl(url),
- true, // is_favicon
- 0, // preferred_size
- maxSize,
- false, // normal cache policy
- base::Bind(&FaviconManager::iconDownloadFinished, m_weakFactory->GetWeakPtr()));
- }
-
- Q_ASSERT(!m_inProgressRequests.contains(id));
- m_inProgressRequests.insert(id, url);
-
- return id;
-}
-
-void FaviconManager::iconDownloadFinished(int id,
- int status,
- const GURL &url,
- const std::vector<SkBitmap> &bitmaps,
- const std::vector<gfx::Size> &original_bitmap_sizes)
-{
- Q_UNUSED(status);
- Q_UNUSED(url);
- Q_UNUSED(original_bitmap_sizes);
-
- storeIcon(id, toQIcon(bitmaps));
-}
-
-/* Pending requests are used to mark icons that are already downloaded (cached icons or icons
- * stored in qrc). These requests are also stored in the m_inProgressRequests but the corresponding
- * icons are stored in m_icons explicitly by this function. It is necessary to avoid
- * m_inProgressRequests being emptied right before the next icon is added by a downloadIcon() call.
- */
-void FaviconManager::downloadPendingRequests()
-{
- for (auto it = m_pendingRequests.cbegin(), end = m_pendingRequests.cend(); it != end; ++it) {
- QIcon icon;
-
- QUrl requestUrl = it.value();
- if (!m_icons.contains(requestUrl)) {
- if (isResourceUrl(requestUrl)) {
- icon = QIcon(requestUrl.toString().remove(0, 3));
- } else if (isDataUrl(requestUrl)) {
- std::string mime_type, char_set, data;
- if (net::DataURL::Parse(toGurl(requestUrl), &mime_type, &char_set, &data) && !data.empty()) {
- const unsigned char *src_data = reinterpret_cast<const unsigned char *>(data.data());
- QImage image = QImage::fromData(src_data, data.size());
- icon.addPixmap(QPixmap::fromImage(image).copy());
- }
- }
- }
-
- storeIcon(it.key(), icon);
- }
-
- m_pendingRequests.clear();
-}
-
-void FaviconManager::storeIcon(int id, const QIcon &icon)
-{
-
- // Icon download has been interrupted
- if (!m_inProgressRequests.contains(id))
- return;
-
- QUrl requestUrl = m_inProgressRequests[id];
- FaviconInfo &faviconInfo = m_faviconInfoMap[requestUrl];
-
- unsigned iconCount = 0;
- if (!icon.isNull())
- iconCount = icon.availableSizes().count();
-
- if (iconCount > 0) {
- m_icons.insert(requestUrl, icon);
-
- faviconInfo.size = icon.availableSizes().at(0);
- if (iconCount > 1) {
- faviconInfo.multiSize = true;
- unsigned bestArea = area(faviconInfo.size);
- for (unsigned i = 1; i < iconCount; ++i) {
- QSize iconSize = icon.availableSizes().at(i);
- if (bestArea < area(iconSize)) {
- faviconInfo.size = iconSize;
- bestArea = area(iconSize);
- }
- }
- }
- } else if (id >= 0) {
- // Reset size if icon cannot be downloaded
- faviconInfo.size = QSize(0, 0);
- }
-
- m_inProgressRequests.remove(id);
- if (m_inProgressRequests.isEmpty()) {
- QWebEngineSettings *settings = m_viewClient->webEngineSettings();
- bool touchIconsEnabled = settings->testAttribute(QWebEngineSettings::TouchIconsEnabled);
-
- generateCandidateIcon(touchIconsEnabled);
- const QUrl &iconUrl = candidateIconUrl(touchIconsEnabled);
- propagateIcon(iconUrl);
- }
-}
-
-void FaviconManager::propagateIcon(const QUrl &iconUrl) const
-{
- content::NavigationEntry *entry = m_webContents->GetController().GetVisibleEntry();
- if (entry) {
- content::FaviconStatus &favicon = entry->GetFavicon();
- favicon.url = toGurl(iconUrl);
- favicon.valid = true;
- }
-
- m_viewClient->iconChanged(iconUrl);
-}
-
-QIcon FaviconManager::getIcon(const QUrl &url) const
-{
- if (url.isEmpty())
- return m_candidateIcon;
-
- if (!m_icons.contains(url))
- return QIcon();
-
- return m_icons[url];
-}
-
-FaviconInfo FaviconManager::getFaviconInfo(const QUrl &url) const
-{
- Q_ASSERT(m_faviconInfoMap.contains(url));
- return m_faviconInfoMap[url];
-}
-
-QList<FaviconInfo> FaviconManager::getFaviconInfoList(bool candidatesOnly) const
-{
- QList<FaviconInfo> faviconInfoList = m_faviconInfoMap.values();
-
- if (candidatesOnly) {
- const auto hasNoCandidate = [](const FaviconInfo &info) { return !info.candidate; };
- faviconInfoList.erase(std::remove_if(faviconInfoList.begin(), faviconInfoList.end(),
- hasNoCandidate),
- faviconInfoList.end());
- }
-
- return faviconInfoList;
-}
-
-void FaviconManager::update(const QList<FaviconInfo> &candidates)
-{
- updateCandidates(candidates);
-
- QWebEngineSettings *settings = m_viewClient->webEngineSettings();
- if (!settings->testAttribute(QWebEngineSettings::AutoLoadIconsForPage)) {
- m_viewClient->iconChanged(QUrl());
- return;
- }
-
- bool touchIconsEnabled = settings->testAttribute(QWebEngineSettings::TouchIconsEnabled);
-
- const QList<FaviconInfo> &faviconInfoList = getFaviconInfoList(true /* candidates only */);
- for (auto it = faviconInfoList.cbegin(), end = faviconInfoList.cend(); it != end; ++it) {
- if (!touchIconsEnabled && !(it->type & FaviconInfo::Favicon))
- continue;
-
- if (it->isValid())
- downloadIcon(it->url);
- }
-
- downloadPendingRequests();
-
- // Reset icon if nothing was downloaded
- if (m_inProgressRequests.isEmpty()) {
- content::NavigationEntry *entry = m_webContents->GetController().GetVisibleEntry();
- if (entry && !entry->GetFavicon().valid)
- m_viewClient->iconChanged(QUrl());
- }
-}
-
-void FaviconManager::updateCandidates(const QList<FaviconInfo> &candidates)
-{
- // Invalidate types of the already stored candidate icons because it might differ
- // among pages.
- for (FaviconInfo candidateFaviconInfo : candidates) {
- const QUrl &candidateUrl = candidateFaviconInfo.url;
- if (m_faviconInfoMap.contains(candidateUrl))
- m_faviconInfoMap[candidateUrl].type = FaviconInfo::InvalidIcon;
- }
-
- m_candidateCount = candidates.count();
- for (FaviconInfo candidateFaviconInfo : candidates) {
- const QUrl &candidateUrl = candidateFaviconInfo.url;
-
- if (!m_faviconInfoMap.contains(candidateUrl))
- m_faviconInfoMap.insert(candidateUrl, candidateFaviconInfo);
- else {
- // The same icon URL can be used for different types.
- m_faviconInfoMap[candidateUrl].type |= candidateFaviconInfo.type;
- }
-
- m_faviconInfoMap[candidateUrl].candidate = true;
- }
-}
-
-void FaviconManager::resetCandidates()
-{
- // Interrupt in progress icon downloads
- m_pendingRequests.clear();
- m_inProgressRequests.clear();
-
- m_candidateCount = 0;
- m_candidateIcon = QIcon();
- for (auto it = m_faviconInfoMap.begin(), end = m_faviconInfoMap.end(); it != end; ++it)
- it->candidate = false;
-}
-
-bool FaviconManager::hasCandidate() const
-{
- return (m_candidateCount > 0);
-}
-
-QUrl FaviconManager::candidateIconUrl(bool touchIconsEnabled) const
-{
- QUrl iconUrl;
- const QList<FaviconInfo> &faviconInfoList = getFaviconInfoList(true /* candidates only */);
-
- unsigned bestArea = 0;
- for (auto it = faviconInfoList.cbegin(), end = faviconInfoList.cend(); it != end; ++it) {
- if (!touchIconsEnabled && !(it->type & FaviconInfo::Favicon))
- continue;
-
- if (it->isValid() && bestArea < area(it->size)) {
- iconUrl = it->url;
- bestArea = area(it->size);
- }
- }
-
- return iconUrl;
-}
-
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-static QPixmap getUnscaledPixmap(QIcon icon, const QSize &size)
-{
- QPixmap pixmap = icon.data_ptr()->engine->pixmap(size, QIcon::Normal, QIcon::Off);
- pixmap.setDevicePixelRatio(1.0);
- return pixmap;
-}
-#else
-static QPixmap getUnscaledPixmap(const QIcon &icon, const QSize &size)
-{
- return icon.pixmap(size, 1.0);
-}
-#endif
-
-void FaviconManager::generateCandidateIcon(bool touchIconsEnabled)
-{
- Q_ASSERT(m_candidateCount);
-
- m_candidateIcon = QIcon();
- const QList<FaviconInfo> &faviconInfoList = getFaviconInfoList(true /* candidates only */);
-
- for (auto it = faviconInfoList.cbegin(), end = faviconInfoList.cend(); it != end; ++it) {
- if (!touchIconsEnabled && !(it->type & FaviconInfo::Favicon))
- continue;
-
- if (!it->isValid() || !it->isDownloaded())
- continue;
-
- const QIcon &icon = getIcon(it->url);
-
- if (!it->multiSize) {
- if (!m_candidateIcon.availableSizes().contains(it->size))
- m_candidateIcon.addPixmap(getUnscaledPixmap(icon, it->size));
-
- continue;
- }
-
- const auto sizes = icon.availableSizes();
- for (const QSize &size : sizes) {
- if (!m_candidateIcon.availableSizes().contains(size))
- m_candidateIcon.addPixmap(getUnscaledPixmap(icon, size));
- }
- }
-}
-
-void FaviconManager::copyStateFrom(FaviconManager *source)
-{
- m_faviconInfoMap = source->m_faviconInfoMap;
- m_icons = source->m_icons;
-}
-
-FaviconInfo::FaviconInfo()
- : url(QUrl())
- , type(FaviconInfo::InvalidIcon)
- , size(QSize(0, 0))
- , candidate(false)
- , multiSize(false)
-{
-}
-
-FaviconInfo::FaviconInfo(const FaviconInfo &other)
- : url(other.url)
- , type(other.type)
- , size(other.size)
- , candidate(other.candidate)
- , multiSize(other.multiSize)
-{
-}
-
-FaviconInfo::FaviconInfo(const QUrl &url, FaviconInfo::FaviconTypeFlags type)
- : url(url)
- , type(type)
- , size(QSize(0, 0))
- , candidate(false)
- , multiSize(false)
-{
-}
-
-FaviconInfo::~FaviconInfo()
-{
-}
-
-bool FaviconInfo::isValid() const
-{
- if (type == FaviconInfo::InvalidIcon)
- return false;
-
- if (url.isEmpty() || !url.isValid())
- return false;
-
- return true;
-}
-
-bool FaviconInfo::isDownloaded() const
-{
- return area(size) > 0;
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/favicon_manager.h b/src/core/favicon_manager.h
deleted file mode 100644
index a6e5822a9..000000000
--- a/src/core/favicon_manager.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#ifndef FAVICON_MANAGER_H
-#define FAVICON_MANAGER_H
-
-#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
-#include <memory>
-#include <QtCore/QMap>
-#include <QtCore/QObject>
-#include <QtCore/QSize>
-#include <QtCore/QUrl>
-#include <QtGui/QIcon>
-
-#include "web_engine_settings.h"
-
-class GURL;
-class SkBitmap;
-
-namespace gfx {
-class Size;
-}
-
-namespace content {
-class WebContents;
-}
-
-namespace base {
-template<class T>
-class WeakPtrFactory;
-}
-
-namespace QtWebEngineCore {
-
-class WebContentsAdapterClient;
-
-// Based on src/3rdparty/chromium/content/public/common/favicon_url.h
-class Q_WEBENGINECORE_PRIVATE_EXPORT FaviconInfo {
-public:
- enum FaviconTypeFlag {
- InvalidIcon = 0,
- Favicon = 1 << 0,
- TouchIcon = 1 << 1,
- TouchPrecomposedIcon = 1 << 2
- };
- Q_DECLARE_FLAGS(FaviconTypeFlags, FaviconTypeFlag)
-
- FaviconInfo();
- FaviconInfo(const FaviconInfo &);
- FaviconInfo(const QUrl &, FaviconInfo::FaviconTypeFlags);
- ~FaviconInfo();
-
- bool isValid() const;
- bool isDownloaded() const;
-
- QUrl url;
- FaviconTypeFlags type;
- // Stores the largest size in case of multi-size icon
- QSize size;
- bool candidate;
- bool multiSize;
-};
-
-
-class Q_WEBENGINECORE_PRIVATE_EXPORT FaviconManager {
-
-public:
- FaviconManager(content::WebContents *, WebContentsAdapterClient *);
- ~FaviconManager();
-
- QIcon getIcon(const QUrl &url = QUrl()) const;
- FaviconInfo getFaviconInfo(const QUrl &) const;
- QList<FaviconInfo> getFaviconInfoList(bool) const;
- void copyStateFrom(FaviconManager *source);
-
-private:
- void update(const QList<FaviconInfo> &);
- void updateCandidates(const QList<FaviconInfo> &);
- void resetCandidates();
- bool hasCandidate() const;
- QUrl candidateIconUrl(bool touchIconsEnabled) const;
- void generateCandidateIcon(bool touchIconsEnabled);
- int downloadIcon(const QUrl &);
- void iconDownloadFinished(int, int, const GURL &, const std::vector<SkBitmap> &, const std::vector<gfx::Size> &);
- void storeIcon(int, const QIcon &);
- void downloadPendingRequests();
- void propagateIcon(const QUrl &) const;
-
-private:
- content::WebContents *m_webContents;
- WebContentsAdapterClient *m_viewClient;
- QMap<QUrl, FaviconInfo> m_faviconInfoMap;
- int m_candidateCount;
- QIcon m_candidateIcon;
- QMap<QUrl, QIcon> m_icons;
- QMap<int, QUrl> m_inProgressRequests;
- QMap<int, QUrl> m_pendingRequests;
- std::unique_ptr<base::WeakPtrFactory<FaviconManager>> m_weakFactory;
- friend class WebContentsDelegateQt;
-};
-
-} // namespace QtWebEngineCore
-
-#endif // FAVICON_MANAGER_H
diff --git a/src/core/favicon_service_factory_qt.cpp b/src/core/favicon_service_factory_qt.cpp
new file mode 100644
index 000000000..898882486
--- /dev/null
+++ b/src/core/favicon_service_factory_qt.cpp
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "favicon_service_factory_qt.h"
+
+#include "base/files/file_util.h"
+#include "components/favicon/core/favicon_service_impl.h"
+#include "components/history/content/browser/content_visit_delegate.h"
+#include "components/history/content/browser/history_database_helper.h"
+#include "components/history/core/browser/history_backend_client.h"
+#include "components/history/core/browser/history_database_params.h"
+#include "components/history/core/browser/history_service.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "content/public/browser/browser_context.h"
+#include "url/gurl.h"
+
+namespace QtWebEngineCore {
+
+void HistoryClientQt::OnHistoryServiceCreated(history::HistoryService *history_service)
+{
+ Q_UNUSED(history_service);
+}
+
+void HistoryClientQt::Shutdown() { }
+
+bool HistoryClientQt::CanAddURL(const GURL &url)
+{
+ Q_UNUSED(url);
+ return true;
+}
+
+void HistoryClientQt::NotifyProfileError(sql::InitStatus init_status,
+ const std::string &diagnostics)
+{
+ Q_UNUSED(init_status);
+ Q_UNUSED(diagnostics);
+}
+
+std::unique_ptr<history::HistoryBackendClient> HistoryClientQt::CreateBackendClient()
+{
+ return nullptr;
+}
+
+// static
+history::HistoryService *
+HistoryServiceFactoryQt::GetForBrowserContext(content::BrowserContext *context)
+{
+ if (context->IsOffTheRecord())
+ return nullptr;
+
+ if (!base::PathExists(context->GetPath()))
+ return nullptr;
+
+ return static_cast<history::HistoryService *>(
+ GetInstance()->GetServiceForBrowserContext(context, true));
+}
+
+// static
+HistoryServiceFactoryQt *HistoryServiceFactoryQt::GetInstance()
+{
+ return base::Singleton<HistoryServiceFactoryQt>::get();
+}
+
+HistoryServiceFactoryQt::HistoryServiceFactoryQt()
+ : BrowserContextKeyedServiceFactory("HistoryService",
+ BrowserContextDependencyManager::GetInstance())
+{
+}
+
+HistoryServiceFactoryQt::~HistoryServiceFactoryQt() { }
+
+content::BrowserContext *
+HistoryServiceFactoryQt::GetBrowserContextToUse(content::BrowserContext *context) const
+{
+ return context;
+}
+
+KeyedService *
+HistoryServiceFactoryQt::BuildServiceInstanceFor(content::BrowserContext *context) const
+{
+ Q_ASSERT(!context->IsOffTheRecord());
+ Q_ASSERT(base::PathExists(context->GetPath()));
+
+ std::unique_ptr<history::HistoryService> historyService(
+ new history::HistoryService(std::make_unique<HistoryClientQt>(), nullptr));
+ if (!historyService->Init(history::HistoryDatabaseParamsForPath(context->GetPath()))) {
+ return nullptr;
+ }
+ return historyService.release();
+}
+
+bool FaviconClientQt::IsNativeApplicationURL(const GURL &url)
+{
+ Q_UNUSED(url);
+ return false;
+}
+
+bool FaviconClientQt::IsReaderModeURL(const GURL &url)
+{
+ Q_UNUSED(url)
+ return false;
+}
+
+const GURL FaviconClientQt::GetOriginalUrlFromReaderModeUrl(const GURL &url)
+{
+ return url;
+}
+
+base::CancelableTaskTracker::TaskId FaviconClientQt::GetFaviconForNativeApplicationURL(
+ const GURL &url, const std::vector<int> &desired_sizes_in_pixel,
+ favicon_base::FaviconResultsCallback callback, base::CancelableTaskTracker *tracker)
+{
+ Q_UNUSED(url);
+ Q_UNUSED(desired_sizes_in_pixel);
+ Q_UNUSED(callback);
+ Q_UNUSED(tracker);
+
+ return base::CancelableTaskTracker::kBadTaskId;
+}
+
+// static
+favicon::FaviconService *
+FaviconServiceFactoryQt::GetForBrowserContext(content::BrowserContext *context)
+{
+ return static_cast<favicon::FaviconService *>(
+ GetInstance()->GetServiceForBrowserContext(context, true));
+}
+
+// static
+FaviconServiceFactoryQt *FaviconServiceFactoryQt::GetInstance()
+{
+ return base::Singleton<FaviconServiceFactoryQt>::get();
+}
+
+FaviconServiceFactoryQt::FaviconServiceFactoryQt()
+ : BrowserContextKeyedServiceFactory("FaviconService",
+ BrowserContextDependencyManager::GetInstance())
+{
+}
+
+FaviconServiceFactoryQt::~FaviconServiceFactoryQt() { }
+
+content::BrowserContext *
+FaviconServiceFactoryQt::GetBrowserContextToUse(content::BrowserContext *context) const
+{
+ return context;
+}
+
+KeyedService *
+FaviconServiceFactoryQt::BuildServiceInstanceFor(content::BrowserContext *context) const
+{
+ history::HistoryService *historyService = static_cast<history::HistoryService *>(
+ HistoryServiceFactoryQt::GetInstance()->GetForBrowserContext(context));
+ return new favicon::FaviconServiceImpl(std::make_unique<FaviconClientQt>(), historyService);
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/favicon_service_factory_qt.h b/src/core/favicon_service_factory_qt.h
new file mode 100644
index 000000000..1ba0db076
--- /dev/null
+++ b/src/core/favicon_service_factory_qt.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef FAVICON_SERVICE_FACTORY_QT_H
+#define FAVICON_SERVICE_FACTORY_QT_H
+
+#include "qtwebenginecoreglobal_p.h"
+
+#include "base/memory/singleton.h"
+#include "base/task/cancelable_task_tracker.h"
+#include "components/favicon/core/favicon_client.h"
+#include "components/history/core/browser/history_client.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+class GURL;
+
+namespace content {
+class BrowserContext;
+}
+
+namespace favicon {
+class FaviconService;
+}
+
+namespace history {
+class HistoryBackendClient;
+class HistoryService;
+}
+
+namespace QtWebEngineCore {
+
+class HistoryClientQt : public history::HistoryClient
+{
+public:
+ HistoryClientQt() { }
+ virtual ~HistoryClientQt() { }
+
+ void OnHistoryServiceCreated(history::HistoryService *history_service) override;
+ void Shutdown() override;
+ bool CanAddURL(const GURL &url) override;
+ void NotifyProfileError(sql::InitStatus init_status, const std::string &diagnostics) override;
+ std::unique_ptr<history::HistoryBackendClient> CreateBackendClient() override;
+};
+
+class HistoryServiceFactoryQt : public BrowserContextKeyedServiceFactory
+{
+public:
+ static history::HistoryService *GetForBrowserContext(content::BrowserContext *context);
+ static HistoryServiceFactoryQt *GetInstance();
+
+private:
+ friend struct base::DefaultSingletonTraits<HistoryServiceFactoryQt>;
+
+ HistoryServiceFactoryQt();
+ ~HistoryServiceFactoryQt() override;
+
+ // BrowserContextKeyedServiceFactory:
+ content::BrowserContext *
+ GetBrowserContextToUse(content::BrowserContext *context) const override;
+ KeyedService *BuildServiceInstanceFor(content::BrowserContext *context) const override;
+};
+
+class FaviconClientQt : public favicon::FaviconClient
+{
+public:
+ FaviconClientQt() { }
+ virtual ~FaviconClientQt() { }
+
+ bool IsNativeApplicationURL(const GURL &url) override;
+ bool IsReaderModeURL(const GURL &url) override;
+ const GURL GetOriginalUrlFromReaderModeUrl(const GURL &url) override;
+ base::CancelableTaskTracker::TaskId
+ GetFaviconForNativeApplicationURL(const GURL &url,
+ const std::vector<int> &desired_sizes_in_pixel,
+ favicon_base::FaviconResultsCallback callback,
+ base::CancelableTaskTracker *tracker) override;
+};
+
+class FaviconServiceFactoryQt : public BrowserContextKeyedServiceFactory
+{
+public:
+ static favicon::FaviconService *GetForBrowserContext(content::BrowserContext *context);
+ static FaviconServiceFactoryQt *GetInstance();
+
+private:
+ friend struct base::DefaultSingletonTraits<FaviconServiceFactoryQt>;
+
+ FaviconServiceFactoryQt();
+ ~FaviconServiceFactoryQt() override;
+
+ // BrowserContextKeyedServiceFactory:
+ content::BrowserContext *
+ GetBrowserContextToUse(content::BrowserContext *context) const override;
+ KeyedService *BuildServiceInstanceFor(content::BrowserContext *context) const override;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // FAVICON_SERVICE_FACTORY_QT_H
diff --git a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
index bca059ae6..e01e82aa9 100644
--- a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
+++ b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
@@ -56,6 +56,7 @@
#include "extensions/extension_system_qt.h"
#include "web_contents_delegate_qt.h"
+#include "web_engine_settings.h"
#include <string>
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index 9a6275a84..204974c28 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -39,6 +39,10 @@
#include "profile_adapter.h"
+#include "components/favicon/core/favicon_service.h"
+#include "components/history/content/browser/history_database_helper.h"
+#include "components/history/core/browser/history_database_params.h"
+#include "components/history/core/browser/history_service.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browsing_data_remover.h"
@@ -51,6 +55,7 @@
#include "api/qwebengineurlscheme.h"
#include "content_browser_client_qt.h"
#include "download_manager_delegate_qt.h"
+#include "favicon_service_factory_qt.h"
#include "permission_manager_qt.h"
#include "profile_adapter_client.h"
#include "profile_io_data_qt.h"
@@ -151,6 +156,8 @@ void ProfileAdapter::setStorageName(const QString &storageName)
m_profile->m_profileIOData->resetNetworkContext();
if (m_visitedLinksManager)
resetVisitedLinksManager();
+
+ reinitializeHistoryService();
}
}
@@ -164,6 +171,14 @@ void ProfileAdapter::setOffTheRecord(bool offTheRecord)
m_profile->m_profileIOData->resetNetworkContext();
if (m_visitedLinksManager)
resetVisitedLinksManager();
+
+ if (offTheRecord) {
+ favicon::FaviconService *faviconService =
+ FaviconServiceFactoryQt::GetForBrowserContext(m_profile.data());
+ faviconService->SetHistoryService(nullptr);
+ } else if (!m_name.isEmpty()) {
+ reinitializeHistoryService();
+ }
}
ProfileQt *ProfileAdapter::profile()
@@ -273,6 +288,9 @@ void ProfileAdapter::setDataPath(const QString &path)
m_profile->m_profileIOData->resetNetworkContext();
if (!m_offTheRecord && m_visitedLinksManager)
resetVisitedLinksManager();
+
+ if (!m_offTheRecord)
+ reinitializeHistoryService();
}
void ProfileAdapter::setDownloadPath(const QString &path)
@@ -652,6 +670,21 @@ void ProfileAdapter::resetVisitedLinksManager()
m_visitedLinksManager.reset(new VisitedLinksManagerQt(m_profile.data(), persistVisitedLinks()));
}
+void ProfileAdapter::reinitializeHistoryService()
+{
+ Q_ASSERT(!m_profile->IsOffTheRecord());
+ if (m_profile->ensureDirectoryExists()) {
+ favicon::FaviconService *faviconService =
+ FaviconServiceFactoryQt::GetForBrowserContext(m_profile.data());
+ history::HistoryService *historyService = static_cast<history::HistoryService *>(
+ HistoryServiceFactoryQt::GetInstance()->GetForBrowserContext(m_profile.data()));
+ Q_ASSERT(historyService);
+ faviconService->SetHistoryService(historyService);
+ } else {
+ qWarning("Favicon database is not available for this profile.");
+ }
+}
+
void ProfileAdapter::setUseForGlobalCertificateVerification(bool enable)
{
if (m_usedForGlobalCertificateVerification == enable)
diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h
index fecb338ad..979316b4a 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -220,6 +220,7 @@ private:
void updateCustomUrlSchemeHandlers();
void resetVisitedLinksManager();
bool persistVisitedLinks() const;
+ void reinitializeHistoryService();
QString m_name;
bool m_offTheRecord;
diff --git a/src/core/profile_qt.cpp b/src/core/profile_qt.cpp
index 36303605f..ae1169558 100644
--- a/src/core/profile_qt.cpp
+++ b/src/core/profile_qt.cpp
@@ -58,6 +58,7 @@
#include "content/public/browser/storage_partition.h"
#include "base/base_paths.h"
+#include "base/files/file_util.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/prefs/pref_member.h"
#include "components/prefs/pref_service.h"
@@ -298,4 +299,21 @@ content::PlatformNotificationService *ProfileQt::platformNotificationService()
return m_platformNotificationService.get();
}
+bool ProfileQt::ensureDirectoryExists()
+{
+ const base::FilePath &path = GetPath();
+
+ if (base::PathExists(path))
+ return true;
+
+ base::File::Error error;
+ if (base::CreateDirectoryAndGetError(path, &error))
+ return true;
+
+ std::string errorstr = base::File::ErrorToString(error);
+ qWarning("Cannot create directory %s. Error: %s.", path.AsUTF8Unsafe().c_str(),
+ errorstr.c_str());
+ return false;
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/profile_qt.h b/src/core/profile_qt.h
index 11b567b97..349532939 100644
--- a/src/core/profile_qt.h
+++ b/src/core/profile_qt.h
@@ -119,6 +119,7 @@ public:
PrefServiceAdapter &prefServiceAdapter();
const PrefServiceAdapter &prefServiceAdapter() const;
+ bool ensureDirectoryExists();
private:
friend class ContentBrowserClientQt;
diff --git a/src/core/qtwebengine.gni b/src/core/qtwebengine.gni
index 49217603f..8f3cac727 100644
--- a/src/core/qtwebengine.gni
+++ b/src/core/qtwebengine.gni
@@ -19,6 +19,8 @@ deps = [
"//base",
"//components/cdm/renderer",
"//components/error_page/common",
+ "//components/favicon/content",
+ "//components/history/content/browser",
"//components/keyed_service/content",
"//components/navigation_interception",
"//components/network_hints/browser",
diff --git a/src/core/type_conversion.cpp b/src/core/type_conversion.cpp
index a4cc57b76..e8f8131b6 100644
--- a/src/core/type_conversion.cpp
+++ b/src/core/type_conversion.cpp
@@ -39,9 +39,11 @@
#include "type_conversion.h"
+#include <components/favicon_base/favicon_util.h>
#include <net/cert/x509_certificate.h>
#include <net/cert/x509_util.h>
#include <ui/events/event_constants.h>
+#include <ui/gfx/image/image.h>
#include <ui/gfx/image/image_skia.h>
#include "third_party/blink/public/mojom/favicon/favicon_url.mojom.h"
@@ -216,6 +218,23 @@ SkBitmap toSkBitmap(const QImage &image)
return bitmapCopy;
}
+QIcon toQIcon(const gfx::Image &image)
+{
+ // Based on ExtractSkBitmapsToStore in chromium/components/favicon/core/favicon_service_impl.cc
+ gfx::ImageSkia image_skia = image.AsImageSkia();
+ image_skia.EnsureRepsForSupportedScales();
+ const std::vector<gfx::ImageSkiaRep> &image_reps = image_skia.image_reps();
+ std::vector<SkBitmap> bitmaps;
+ const std::vector<float> favicon_scales = favicon_base::GetFaviconScales();
+ for (size_t i = 0; i < image_reps.size(); ++i) {
+ // Don't save if the scale isn't one of supported favicon scales.
+ if (!base::Contains(favicon_scales, image_reps[i].scale()))
+ continue;
+ bitmaps.push_back(image_reps[i].GetBitmap());
+ }
+ return toQIcon(bitmaps);
+}
+
QIcon toQIcon(const std::vector<SkBitmap> &bitmaps)
{
if (!bitmaps.size())
@@ -257,33 +276,6 @@ int flagsFromModifiers(Qt::KeyboardModifiers modifiers)
return modifierFlags;
}
-FaviconInfo::FaviconTypeFlags toQt(blink::mojom::FaviconIconType type)
-{
- switch (type) {
- case blink::mojom::FaviconIconType::kFavicon:
- return FaviconInfo::Favicon;
- case blink::mojom::FaviconIconType::kTouchIcon:
- return FaviconInfo::TouchIcon;
- case blink::mojom::FaviconIconType::kTouchPrecomposedIcon:
- return FaviconInfo::TouchPrecomposedIcon;
- case blink::mojom::FaviconIconType::kInvalid:
- return FaviconInfo::InvalidIcon;
- }
- Q_UNREACHABLE();
- return FaviconInfo::InvalidIcon;
-}
-
-FaviconInfo toFaviconInfo(const blink::mojom::FaviconURLPtr &favicon_url)
-{
- FaviconInfo info;
- info.url = toQt(favicon_url->icon_url);
- info.type = toQt(favicon_url->icon_type);
- // TODO: Add support for rel sizes attribute (favicon_url.icon_sizes):
- // http://www.w3schools.com/tags/att_link_sizes.asp
- info.size = QSize(0, 0);
- return info;
-}
-
void convertToQt(const SkMatrix44 &m, QMatrix4x4 &c)
{
QMatrix4x4 qtMatrix(
diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h
index 85fd763b4..fff130218 100644
--- a/src/core/type_conversion.h
+++ b/src/core/type_conversion.h
@@ -52,7 +52,6 @@
#include <base/strings/nullable_string16.h>
#include "base/files/file_path.h"
#include "base/time/time.h"
-#include "favicon_manager.h"
#include "net/cookies/canonical_cookie.h"
#include "third_party/blink/public/mojom/favicon/favicon_url.mojom-forward.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -68,6 +67,7 @@ QT_FORWARD_DECLARE_CLASS(QMatrix4x4)
QT_FORWARD_DECLARE_CLASS(QSslCertificate)
namespace gfx {
+class Image;
class ImageSkiaRep;
}
@@ -222,6 +222,7 @@ QImage toQImage(const SkBitmap &bitmap);
QImage toQImage(const gfx::ImageSkiaRep &imageSkiaRep);
SkBitmap toSkBitmap(const QImage &image);
+QIcon toQIcon(const gfx::Image &image);
QIcon toQIcon(const std::vector<SkBitmap> &bitmaps);
void convertToQt(const SkMatrix44 &m, QMatrix4x4 &c);
@@ -272,8 +273,6 @@ inline QStringList fromVector(const std::vector<base::string16> &vector)
return result;
}
-FaviconInfo toFaviconInfo(const blink::mojom::FaviconURLPtr &favicon_url);
-
QList<QSslCertificate> toCertificateChain(net::X509Certificate *certificate);
Qt::InputMethodHints toQtInputMethodHints(ui::TextInputType inputType);
diff --git a/src/core/visited_links_manager_qt.cpp b/src/core/visited_links_manager_qt.cpp
index 37343cc39..15f655012 100644
--- a/src/core/visited_links_manager_qt.cpp
+++ b/src/core/visited_links_manager_qt.cpp
@@ -90,27 +90,12 @@ bool VisitedLinksManagerQt::containsUrl(const QUrl &url) const
return m_visitedLinkWriter->IsVisited(toGurl(url));
}
-static void ensureDirectoryExists(const base::FilePath &path)
-{
- if (base::PathExists(path))
- return;
-
- base::File::Error error;
- if (base::CreateDirectoryAndGetError(path, &error))
- return;
-
- std::string errorstr = base::File::ErrorToString(error);
- qWarning("Cannot create directory %s. Error: %s.",
- path.AsUTF8Unsafe().c_str(),
- errorstr.c_str());
-}
-
VisitedLinksManagerQt::VisitedLinksManagerQt(ProfileQt *profile, bool persistVisitedLinks)
: m_delegate(new VisitedLinkDelegateQt)
{
Q_ASSERT(profile);
if (persistVisitedLinks)
- ensureDirectoryExists(profile->GetPath());
+ profile->ensureDirectoryExists();
m_visitedLinkWriter.reset(new visitedlink::VisitedLinkWriter(profile, m_delegate.data(), persistVisitedLinks));
m_visitedLinkWriter->Init();
}
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index f5656f571..16e91e6c7 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -45,6 +45,8 @@
#include "devtools_frontend_qt.h"
#include "download_manager_delegate_qt.h"
+#include "favicon_driver_qt.h"
+#include "favicon_service_factory_qt.h"
#include "media_capture_devices_dispatcher.h"
#if QT_CONFIG(webengine_printing_and_pdf)
#include "printing/print_view_manager_qt.h"
@@ -69,6 +71,7 @@
#include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
#include "base/values.h"
#include "chrome/browser/tab_contents/form_interaction_tab_helper.h"
+#include "components/favicon/core/favicon_service.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/text_input_manager.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -532,6 +535,10 @@ void WebContentsAdapter::initialize(content::SiteInstance *site)
extensions::ExtensionWebContentsObserverQt::CreateForWebContents(webContents());
#endif
+ content::BrowserContext *context = webContents()->GetBrowserContext();
+ FaviconDriverQt::CreateForWebContents(
+ webContents(), FaviconServiceFactoryQt::GetForBrowserContext(context), m_adapterClient);
+
// Create an instance of WebEngineVisitedLinksManager to catch the first
// content::NOTIFICATION_RENDERER_PROCESS_CREATED event. This event will
// force to initialize visited links in VisitedLinkSlave.
@@ -818,12 +825,15 @@ QUrl WebContentsAdapter::requestedUrl() const
QUrl WebContentsAdapter::iconUrl() const
{
CHECK_INITIALIZED(QUrl());
- if (content::NavigationEntry* entry = m_webContents->GetController().GetVisibleEntry()) {
- content::FaviconStatus &favicon = entry->GetFavicon();
- if (favicon.valid)
- return toQt(favicon.url);
- }
- return QUrl();
+ FaviconDriverQt *driver = FaviconDriverQt::FromWebContents(webContents());
+ return toQt(driver->GetFaviconURL());
+}
+
+QIcon WebContentsAdapter::icon() const
+{
+ CHECK_INITIALIZED(QIcon());
+ FaviconDriverQt *driver = FaviconDriverQt::FromWebContents(webContents());
+ return toQIcon(driver->GetFavicon());
}
QString WebContentsAdapter::pageTitle() const
@@ -1805,12 +1815,6 @@ WebContentsAdapterClient::renderProcessExitStatus(int terminationStatus) {
return status;
}
-FaviconManager *WebContentsAdapter::faviconManager()
-{
- CHECK_INITIALIZED(nullptr);
- return m_webContentsDelegate->faviconManager();
-}
-
FindTextHelper *WebContentsAdapter::findTextHelper()
{
CHECK_INITIALIZED(nullptr);
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index b05ddeb4d..f4905e1d4 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -138,6 +138,7 @@ public:
QString pageTitle() const;
QString selectedText() const;
QUrl iconUrl() const;
+ QIcon icon() const;
void undo();
void redo();
@@ -212,7 +213,6 @@ public:
QWebChannel *webChannel() const;
void setWebChannel(QWebChannel *, uint worldId);
#endif
- FaviconManager *faviconManager();
FindTextHelper *findTextHelper();
QPointF lastScrollOffset() const;
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 5d11f43c3..34e1f7ad1 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -46,7 +46,6 @@
#include "profile_adapter.h"
#include "color_chooser_controller.h"
#include "color_chooser_qt.h"
-#include "favicon_manager.h"
#include "file_picker_controller.h"
#include "media_capture_devices_dispatcher.h"
#include "profile_qt.h"
@@ -102,7 +101,6 @@ static WebContentsAdapterClient::JavaScriptConsoleMessageLevel mapToJavascriptCo
WebContentsDelegateQt::WebContentsDelegateQt(content::WebContents *webContents, WebContentsAdapterClient *adapterClient)
: m_viewClient(adapterClient)
- , m_faviconManager(new FaviconManager(webContents, adapterClient))
, m_findTextHelper(new FindTextHelper(webContents, adapterClient))
, m_loadingState(determineLoadingState(webContents))
, m_didStartLoadingSeen(m_loadingState == LoadingState::Loading)
@@ -362,8 +360,6 @@ void WebContentsDelegateQt::DidStartNavigation(content::NavigationHandle *naviga
if (!navigation_handle->IsInMainFrame() || !web_contents()->IsLoadingToDifferentDocument())
return;
- m_faviconManager->resetCandidates();
-
m_loadingInfo.url = toQt(navigation_handle->GetURL());
// IsErrorPage is only set after navigation commit, so check it otherwise: error page shouldn't have navigation entry
bool isErrorPage = m_loadingInfo.triggersErrorPage && !navigation_handle->GetNavigationEntry();
@@ -426,7 +422,6 @@ void WebContentsDelegateQt::DidFinishNavigation(content::NavigationHandle *navig
// The load will succede as an error-page load later, and we reported the original error above
if (navigation_handle->IsErrorPage()) {
// Now report we are starting to load an error-page.
- m_faviconManager->resetCandidates();
emitLoadStarted(true);
// If it is already committed we will not see another DidFinishNavigation call or a DidFinishLoad call.
@@ -533,9 +528,6 @@ void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame
return;
}
- if (!m_faviconManager->hasCandidate())
- m_viewClient->iconChanged(QUrl());
-
content::NavigationEntry *entry = web_contents()->GetController().GetActiveEntry();
int http_statuscode = entry ? entry->GetHttpStatusCode() : 0;
bool errorPageEnabled = webEngineSettings()->testAttribute(QWebEngineSettings::ErrorPageEnabled);
@@ -547,21 +539,6 @@ void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame
m_loadingInfo.triggersErrorPage = triggersErrorPage;
}
-void WebContentsDelegateQt::DidUpdateFaviconURL(content::RenderFrameHost *render_frame_host, const std::vector<blink::mojom::FaviconURLPtr> &candidates)
-{
- QList<FaviconInfo> faviconCandidates;
- faviconCandidates.reserve(static_cast<int>(candidates.size()));
- for (const blink::mojom::FaviconURLPtr &candidate : candidates) {
- // Store invalid candidates too for later debugging via API
- faviconCandidates.append(toFaviconInfo(candidate));
- }
-
- // Favicon URL can be changed from JavaScript too. Thus we need to reset
- // the current candidate icon list to not handle previous icon as a candidate.
- m_faviconManager->resetCandidates();
- m_faviconManager->update(faviconCandidates);
-}
-
void WebContentsDelegateQt::WebContentsCreated(content::WebContents * /*source_contents*/,
int /*opener_render_process_id*/, int /*opener_render_frame_id*/,
const std::string &/*frame_name*/,
@@ -867,11 +844,6 @@ void WebContentsDelegateQt::ResourceLoadComplete(content::RenderFrameHost* rende
}
}
-FaviconManager *WebContentsDelegateQt::faviconManager()
-{
- return m_faviconManager.data();
-}
-
FindTextHelper *WebContentsDelegateQt::findTextHelper()
{
return m_findTextHelper.data();
@@ -890,7 +862,6 @@ void WebContentsDelegateQt::copyStateFrom(WebContentsDelegateQt *source)
{
m_title = source->m_title;
NavigationStateChanged(web_contents(), content::INVALIDATE_TYPE_URL);
- m_faviconManager->copyStateFrom(source->m_faviconManager.data());
}
WebContentsDelegateQt::LoadingState WebContentsDelegateQt::determineLoadingState(content::WebContents *contents)
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index c3676d996..d6adcd77c 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -49,7 +49,6 @@
#include "base/callback.h"
#include "color_chooser_controller.h"
-#include "favicon_manager.h"
#include "find_text_helper.h"
#include "javascript_dialog_manager_qt.h"
#include <QtCore/qlist.h>
@@ -166,7 +165,6 @@ public:
void DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code) override;
void DidFinishLoad(content::RenderFrameHost *render_frame_host, const GURL &validated_url) override;
void BeforeUnloadFired(bool proceed, const base::TimeTicks& proceed_time) override;
- void DidUpdateFaviconURL(content::RenderFrameHost *render_frame_host, const std::vector<blink::mojom::FaviconURLPtr> &candidates) override;
void OnVisibilityChanged(content::Visibility visibility) override;
void DidFirstVisuallyNonEmptyPaint() override;
void ActivateContents(content::WebContents* contents) override;
@@ -180,7 +178,6 @@ public:
void selectClientCert(const QSharedPointer<ClientCertSelectController> &);
void requestFeaturePermission(ProfileAdapter::PermissionType feature, const QUrl &requestingOrigin);
void launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame, bool has_user_gesture);
- FaviconManager *faviconManager();
FindTextHelper *findTextHelper();
void setSavePageInfo(const SavePageInfo &spi) { m_savePageInfo = spi; }
@@ -221,7 +218,6 @@ private:
int &streamCount(blink::mojom::MediaStreamType type);
WebContentsAdapterClient *m_viewClient;
- QScopedPointer<FaviconManager> m_faviconManager;
QScopedPointer<FindTextHelper> m_findTextHelper;
SavePageInfo m_savePageInfo;
QSharedPointer<FilePickerController> m_filePickerController;
diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index 249f50613..6b11cf0cd 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -38,6 +38,7 @@
**
****************************************************************************/
+#include "qtwebenginecoreglobal_p.h"
#include "web_engine_library_info.h"
#include "base/base_paths.h"
diff --git a/src/webenginequick/api/qquickwebenginefaviconprovider.cpp b/src/webenginequick/api/qquickwebenginefaviconprovider.cpp
index f817e4016..23397003e 100644
--- a/src/webenginequick/api/qquickwebenginefaviconprovider.cpp
+++ b/src/webenginequick/api/qquickwebenginefaviconprovider.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -39,7 +39,6 @@
#include "qquickwebenginefaviconprovider_p_p.h"
-#include "favicon_manager.h"
#include "qquickwebengineview_p.h"
#include "qquickwebengineview_p_p.h"
#include "web_contents_adapter.h"
@@ -47,21 +46,65 @@
#include <QtGui/QIcon>
#include <QtGui/QPixmap>
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-#include <QtGui/qiconengine.h>
-#include <QtGui/private/qicon_p.h>
-#endif
-
QT_BEGIN_NAMESPACE
-using QtWebEngineCore::FaviconInfo;
-using QtWebEngineCore::FaviconManager;
-
static inline unsigned area(const QSize &size)
{
return size.width() * size.height();
}
+static QSize largestSize(const QList<QSize> &availableSizes)
+{
+ QSize result;
+ for (const QSize &size : availableSizes) {
+ if (area(size) > area(result))
+ result = size;
+ }
+
+ return result;
+}
+
+static QSize fitSize(const QList<QSize> &availableSizes, const QSize &requestedSize)
+{
+ Q_ASSERT(availableSizes.count());
+ QSize result = largestSize(availableSizes);
+ if (availableSizes.count() == 1 || area(requestedSize) >= area(result))
+ return result;
+
+ for (const QSize &size : availableSizes) {
+ if (area(size) == area(requestedSize))
+ return size;
+
+ if (area(requestedSize) < area(size) && area(size) < area(result))
+ result = size;
+ }
+
+ return result;
+}
+
+static QPixmap extractPixmap(const QIcon &icon, const QSize &requestedSize)
+{
+ Q_ASSERT(!icon.isNull());
+
+ // If source size is not specified, use the largest icon
+ if (!requestedSize.isValid())
+ return icon.pixmap(largestSize(icon.availableSizes()), 1.0).copy();
+
+ const QSize &size = fitSize(icon.availableSizes(), requestedSize);
+ const QPixmap &iconPixmap = icon.pixmap(size, 1.0);
+ return iconPixmap.scaled(requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation).copy();
+}
+
+static QQuickWebEngineView *findViewById(const QString &id, QList<QQuickWebEngineView *> *views)
+{
+ for (QQuickWebEngineView *view : *views) {
+ if (view->icon() == QQuickWebEngineFaviconProvider::faviconProviderUrl(QUrl(id)))
+ return view;
+ }
+
+ return nullptr;
+}
+
QString QQuickWebEngineFaviconProvider::identifier()
{
return QStringLiteral("favicon");
@@ -75,7 +118,8 @@ QUrl QQuickWebEngineFaviconProvider::faviconProviderUrl(const QUrl &url)
QUrl providerUrl;
providerUrl.setScheme(QStringLiteral("image"));
providerUrl.setHost(identifier());
- providerUrl.setPath(QStringLiteral("/%1").arg(url.toString(QUrl::RemoveQuery | QUrl::RemoveFragment)));
+ providerUrl.setPath(
+ QStringLiteral("/%1").arg(url.toString(QUrl::RemoveQuery | QUrl::RemoveFragment)));
if (url.hasQuery())
providerUrl.setQuery(url.query(QUrl::FullyDecoded));
if (url.hasFragment())
@@ -86,125 +130,29 @@ QUrl QQuickWebEngineFaviconProvider::faviconProviderUrl(const QUrl &url)
QQuickWebEngineFaviconProvider::QQuickWebEngineFaviconProvider()
: QQuickImageProvider(QQuickImageProvider::Pixmap)
- , m_latestView(0)
{
}
-QQuickWebEngineFaviconProvider::~QQuickWebEngineFaviconProvider()
-{
- qDeleteAll(m_iconUrlMap);
-}
+QQuickWebEngineFaviconProvider::~QQuickWebEngineFaviconProvider() { }
-QUrl QQuickWebEngineFaviconProvider::attach(QQuickWebEngineView *view, const QUrl &iconUrl)
-{
- if (iconUrl.isEmpty())
- return QUrl();
-
- m_latestView = view;
-
- if (!m_iconUrlMap.contains(view))
- m_iconUrlMap.insert(view, new QList<QUrl>());
-
- QList<QUrl> *iconUrls = m_iconUrlMap[view];
- if (!iconUrls->contains(iconUrl))
- iconUrls->append(iconUrl);
-
- return faviconProviderUrl(iconUrl);
-}
-
-void QQuickWebEngineFaviconProvider::detach(QQuickWebEngineView *view)
-{
- QList<QUrl> *iconUrls = m_iconUrlMap.take(view);
- delete iconUrls;
-}
-
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-static QPixmap getUnscaledPixmap(QIcon icon, const QSize &size)
-{
- QPixmap pixmap = icon.data_ptr()->engine->pixmap(size, QIcon::Normal, QIcon::Off);
- pixmap.setDevicePixelRatio(1.0);
- return pixmap;
-}
-#else
-static QPixmap getUnscaledPixmap(const QIcon &icon, const QSize &size)
-{
- return icon.pixmap(size, 1.0);
-}
-#endif
-
-QPixmap QQuickWebEngineFaviconProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
+QPixmap QQuickWebEngineFaviconProvider::requestPixmap(const QString &id, QSize *size,
+ const QSize &requestedSize)
{
Q_UNUSED(size);
Q_UNUSED(requestedSize);
- QUrl iconUrl(id);
- QQuickWebEngineView *view = viewForIconUrl(iconUrl);
-
- if (!view || iconUrl.isEmpty())
+ if (m_views.isEmpty())
return QPixmap();
- FaviconManager *faviconManager = view->d_ptr->adapter->faviconManager();
-
- Q_ASSERT(faviconManager);
- const FaviconInfo &faviconInfo = faviconManager->getFaviconInfo(iconUrl);
- const QIcon &icon = faviconManager->getIcon(faviconInfo.candidate ? QUrl() : iconUrl);
-
- Q_ASSERT(!icon.isNull());
- const QSize &bestSize = faviconInfo.size;
-
- // If source size is not specified, use the best quality
- if (!requestedSize.isValid()) {
- if (size)
- *size = bestSize;
-
- return getUnscaledPixmap(icon, bestSize).copy();
- }
-
- const QSize &fitSize = findFitSize(icon.availableSizes(), requestedSize, bestSize);
- const QPixmap &iconPixmap = getUnscaledPixmap(icon, fitSize);
-
- if (size)
- *size = iconPixmap.size();
-
- return iconPixmap.scaled(requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation).copy();
-}
-
-QQuickWebEngineView *QQuickWebEngineFaviconProvider::viewForIconUrl(const QUrl &iconUrl) const
-{
- // The most common use case is that the requested iconUrl belongs to the
- // latest WebEngineView which was raised an iconChanged signal.
- if (m_latestView) {
- QList<QUrl> *iconUrls = m_iconUrlMap[m_latestView];
- if (iconUrls && iconUrls->contains(iconUrl))
- return m_latestView;
- }
-
- for (auto it = m_iconUrlMap.cbegin(), end = m_iconUrlMap.cend(); it != end; ++it) {
- if (it.value()->contains(iconUrl))
- return it.key();
- }
-
- return 0;
-}
-
-QSize QQuickWebEngineFaviconProvider::findFitSize(const QList<QSize> &availableSizes,
- const QSize &requestedSize,
- const QSize &bestSize) const
-{
- Q_ASSERT(availableSizes.count());
- if (availableSizes.count() == 1 || area(requestedSize) >= area(bestSize))
- return bestSize;
-
- QSize fitSize = bestSize;
- for (const QSize &size : availableSizes) {
- if (area(size) == area(requestedSize))
- return size;
+ QQuickWebEngineView *view = findViewById(id, &m_views);
+ if (!view)
+ return QPixmap();
- if (area(requestedSize) < area(size) && area(size) < area(fitSize))
- fitSize = size;
- }
+ QIcon icon = view->d_ptr->adapter->icon();
+ if (icon.isNull())
+ return QPixmap();
- return fitSize;
+ return extractPixmap(icon, requestedSize).copy();
}
QT_END_NAMESPACE
diff --git a/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h b/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h
index 80d2f65f2..d284a73d5 100644
--- a/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h
+++ b/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -52,15 +52,15 @@
//
#include <QtWebEngineQuick/private/qtwebengineglobal_p.h>
+#include <QtCore/QList>
#include <QtQuick/QQuickImageProvider>
-#include <QtCore/QMap>
-
QT_BEGIN_NAMESPACE
class QQuickWebEngineView;
-class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineFaviconProvider : public QQuickImageProvider {
+class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineFaviconProvider : public QQuickImageProvider
+{
public:
static QString identifier();
static QUrl faviconProviderUrl(const QUrl &);
@@ -68,18 +68,13 @@ public:
QQuickWebEngineFaviconProvider();
~QQuickWebEngineFaviconProvider();
- QUrl attach(QQuickWebEngineView *, const QUrl &);
- void detach(QQuickWebEngineView *);
-
+ void attach(QQuickWebEngineView *view) { m_views.append(view); }
+ void detach(QQuickWebEngineView *view) { m_views.removeAll(view); }
QPixmap requestPixmap(const QString &, QSize *, const QSize &) override;
private:
- QQuickWebEngineView *viewForIconUrl(const QUrl &) const;
- QSize findFitSize(const QList<QSize> &, const QSize &, const QSize &) const;
-
- QMap<QQuickWebEngineView *, QList<QUrl> *> m_iconUrlMap;
- QQuickWebEngineView *m_latestView;
+ QList<QQuickWebEngineView *> m_views;
};
QT_END_NAMESPACE
diff --git a/src/webenginequick/api/qquickwebengineview.cpp b/src/webenginequick/api/qquickwebengineview.cpp
index 5524b8954..2e6a2f428 100644
--- a/src/webenginequick/api/qquickwebengineview.cpp
+++ b/src/webenginequick/api/qquickwebengineview.cpp
@@ -132,7 +132,6 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
, m_testSupport(0)
#endif
, contextMenuExtraItems(0)
- , faviconProvider(0)
, loadProgress(0)
, m_fullscreenMode(false)
, isLoading(false)
@@ -179,8 +178,8 @@ QQuickWebEngineViewPrivate::~QQuickWebEngineViewPrivate()
{
Q_ASSERT(m_profileInitialized);
m_profile->d_ptr->removeWebContentsAdapterClient(this);
- if (faviconProvider)
- faviconProvider->detach(q_ptr);
+ if (m_faviconProvider)
+ m_faviconProvider->detach(q_ptr);
// q_ptr->d_ptr might be null due to destroy()
if (q_ptr->d_ptr)
bindViewAndWidget(q_ptr, nullptr);
@@ -408,20 +407,7 @@ void QQuickWebEngineViewPrivate::iconChanged(const QUrl &url)
if (iconUrl == QQuickWebEngineFaviconProvider::faviconProviderUrl(url))
return;
- if (!faviconProvider) {
- QQmlEngine *engine = qmlEngine(q);
-
- // TODO: this is a workaround for QTBUG-65044
- if (!engine)
- return;
-
- Q_ASSERT(engine);
- faviconProvider = static_cast<QQuickWebEngineFaviconProvider *>(
- engine->imageProvider(QQuickWebEngineFaviconProvider::identifier()));
- Q_ASSERT(faviconProvider);
- }
-
- iconUrl = faviconProvider->attach(q, url);
+ iconUrl = QQuickWebEngineFaviconProvider::faviconProviderUrl(url);
m_history->reset();
QTimer::singleShot(0, q, &QQuickWebEngineView::iconChanged);
}
@@ -904,6 +890,17 @@ void QQuickWebEngineViewPrivate::ensureContentsAdapter()
else
adapter->loadDefault();
}
+
+ if (!m_faviconProvider) {
+ QQmlEngine *engine = qmlEngine(q_ptr);
+ // TODO: this is a workaround for QTBUG-65044
+ if (!engine)
+ return;
+ m_faviconProvider = static_cast<QQuickWebEngineFaviconProvider *>(
+ engine->imageProvider(QQuickWebEngineFaviconProvider::identifier()));
+ m_faviconProvider->attach(q_ptr);
+ Q_ASSERT(m_faviconProvider);
+ }
}
void QQuickWebEngineViewPrivate::initializationFinished()
diff --git a/src/webenginequick/api/qquickwebengineview_p.h b/src/webenginequick/api/qquickwebengineview_p.h
index ca3b5349e..5b8231cbf 100644
--- a/src/webenginequick/api/qquickwebengineview_p.h
+++ b/src/webenginequick/api/qquickwebengineview_p.h
@@ -70,7 +70,6 @@ class QQuickWebEngineAction;
class QQuickWebEngineAuthenticationDialogRequest;
class QQuickWebEngineClientCertificateSelection;
class QQuickWebEngineColorDialogRequest;
-class QQuickWebEngineFaviconProvider;
class QQuickWebEngineFileDialogRequest;
class QQuickWebEngineHistory;
class QQuickWebEngineJavaScriptDialogRequest;
diff --git a/src/webenginequick/api/qquickwebengineview_p_p.h b/src/webenginequick/api/qquickwebengineview_p_p.h
index 115c13e06..1b50de26a 100644
--- a/src/webenginequick/api/qquickwebengineview_p_p.h
+++ b/src/webenginequick/api/qquickwebengineview_p_p.h
@@ -196,7 +196,6 @@ public:
QUrl m_url;
QString m_html;
QUrl iconUrl;
- QQuickWebEngineFaviconProvider *faviconProvider;
int loadProgress;
bool m_fullscreenMode;
bool isLoading;
@@ -230,6 +229,7 @@ private:
QWebEngineContextMenuRequest *m_contextMenuRequest;
LoadVisuallyCommittedState m_loadVisuallyCommittedState = NotCommitted;
QScopedPointer<QQuickWebEngineScriptCollection> m_scriptCollection;
+ QQuickWebEngineFaviconProvider *m_faviconProvider = nullptr;
};
#ifndef QT_NO_ACCESSIBILITY
diff --git a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
index 0e8248508..ef3b84691 100644
--- a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
+++ b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
@@ -294,9 +294,9 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP()
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
QVERIFY(!cookieRequestHeader.isEmpty());
QTRY_COMPARE(cookieAddedSpy.count(), 1);
- QTRY_COMPARE(accessTested.loadAcquire(), 7);
+ QTRY_COMPARE(accessTested.loadAcquire(), 6);
- QTRY_COMPARE(serverSpy.count(), 6);
+ QTRY_COMPARE(serverSpy.count(), 5);
client->deleteAllCookies();
QTRY_COMPARE(cookieRemovedSpy.count(), 1);
@@ -313,9 +313,9 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP()
// Test cookies are NOT added:
QTest::qWait(100);
QCOMPARE(cookieAddedSpy.count(), 1);
- QTRY_COMPARE(accessTested.loadAcquire(), 11);
+ QTRY_COMPARE(accessTested.loadAcquire(), 9);
- QTRY_COMPARE(serverSpy.count(), 9);
+ QTRY_COMPARE(serverSpy.count(), 7);
page.triggerAction(QWebEnginePage::Reload);
QTRY_COMPARE(loadSpy.count(), 1);
@@ -324,7 +324,7 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP()
QCOMPARE(cookieAddedSpy.count(), 1);
// Wait for last GET /favicon.ico
- QTRY_COMPARE(serverSpy.count(), 12);
+ QTRY_COMPARE(serverSpy.count(), 9);
(void) httpServer.stop();
QCOMPARE(resourceFirstParty.size(), accessTested.loadAcquire());
diff --git a/tests/auto/quick/qmltests/CMakeLists.txt b/tests/auto/quick/qmltests/CMakeLists.txt
index b5898cc2a..1c77e1a05 100644
--- a/tests/auto/quick/qmltests/CMakeLists.txt
+++ b/tests/auto/quick/qmltests/CMakeLists.txt
@@ -16,6 +16,7 @@ set(testList
tst_activeFocusOnPress.qml
tst_audioMuted.qml
tst_desktopBehaviorLoadHtml.qml
+ tst_favicon.qml
tst_findText.qml
tst_focusOnNavigation.qml
tst_fullScreenRequest.qml
@@ -53,8 +54,6 @@ endif()
if(QT_FEATURE_webengine_testsupport)
list(APPEND testList
- tst_favicon.qml
- tst_faviconDownload.qml
tst_inputMethod.qml
tst_javaScriptDialogs.qml
tst_linkHovered.qml
diff --git a/tests/auto/quick/qmltests/data/favicon-misc.html b/tests/auto/quick/qmltests/data/favicon-misc.html
index 9e788bdf4..03d1086ff 100644
--- a/tests/auto/quick/qmltests/data/favicon-misc.html
+++ b/tests/auto/quick/qmltests/data/favicon-misc.html
@@ -1,8 +1,8 @@
<html>
<head>
<title>Favicon Test</title>
- <link rel="shortcut icon" href="icons/qt32.ico" />
- <link rel="apple-touch-icon" href="icons/qt144.png" />
+ <link rel="shortcut icon" href="icons/qt32.ico" sizes="32x32" />
+ <link rel="apple-touch-icon" href="icons/qt144.png" sizes="144x144"/>
<link rel="shortcut icon" href="icons/unavailable.ico" />
</head>
<body>
diff --git a/tests/auto/quick/qmltests/data/tst_favicon.qml b/tests/auto/quick/qmltests/data/tst_favicon.qml
index fc8b90542..4d13d1e76 100644
--- a/tests/auto/quick/qmltests/data/tst_favicon.qml
+++ b/tests/auto/quick/qmltests/data/tst_favicon.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -26,30 +26,26 @@
**
****************************************************************************/
-import QtQuick 2.0
-import QtTest 1.0
-import QtWebEngine 1.3
-import QtWebEngine.testsupport 1.0
-import QtQuick.Window 2.0
-import "../../qmltests/data" 1.0
+import QtQuick
+import QtTest
+import QtWebEngine
+import Test.util
+import "../../qmltests/data"
TestWebEngineView {
id: webEngineView
width: 200
height: 400
- testSupport: WebEngineTestSupport {
- property var errorPageLoadStatus: null
+ TempDir { id: tempDir }
- function waitForErrorPageLoadSucceeded() {
- var success = _waitFor(function() { return testSupport.errorPageLoadStatus == WebEngineView.LoadSucceededStatus })
- testSupport.errorPageLoadStatus = null
- return success
- }
+ property QtObject defaultProfile: WebEngineProfile {
+ offTheRecord: true
+ }
- errorPage.onLoadingChanged: function(load) {
- errorPageLoadStatus = load.status
- }
+ property QtObject nonOTRProfile: WebEngineProfile {
+ persistentStoragePath: tempDir.path() + '/WebEngineFavicon'
+ offTheRecord: false
}
function removeFaviconProviderPrefix(url) {
@@ -58,10 +54,10 @@ TestWebEngineView {
function getFaviconPixel(faviconImage) {
var grabImage = Qt.createQmlObject("
- import QtQuick 2.5\n
+ import QtQuick\n
Image { }", testCase)
var faviconCanvas = Qt.createQmlObject("
- import QtQuick 2.5\n
+ import QtQuick\n
Canvas { }", testCase)
testCase.tryVerify(function() { return faviconImage.status == Image.Ready });
@@ -104,12 +100,22 @@ TestWebEngineView {
function init() {
// It is worth to restore the initial state with loading a blank page before all test functions.
- webEngineView.url = 'about:blank'
- verify(webEngineView.waitForLoadSucceeded())
- iconChangedSpy.clear()
+ webEngineView.url = 'about:blank';
+ verify(webEngineView.waitForLoadSucceeded());
+ iconChangedSpy.clear();
+ webEngineView.settings.touchIconsEnabled = false;
+ webEngineView.settings.autoLoadIconsForPage = true;
}
- function test_faviconLoad() {
+ function test_faviconLoad_data() {
+ return [
+ { tag: "OTR", profile: defaultProfile },
+ { tag: "non-OTR", profile: nonOTRProfile },
+ ];
+ }
+
+ function test_faviconLoad(row) {
+ webEngineView.profile = row.profile
compare(iconChangedSpy.count, 0)
var url = Qt.resolvedUrl("favicon.html")
@@ -119,11 +125,20 @@ TestWebEngineView {
iconChangedSpy.wait()
compare(iconChangedSpy.count, 1)
- compare(favicon.width, 48)
- compare(favicon.height, 48)
+ tryCompare(favicon, "status", Image.Ready)
+ compare(favicon.width, 32)
+ compare(favicon.height, 32)
+ }
+
+ function test_faviconLoadEncodedUrl_data() {
+ return [
+ { tag: "OTR", profile: defaultProfile },
+ { tag: "non-OTR", profile: nonOTRProfile },
+ ];
}
- function test_faviconLoadEncodedUrl() {
+ function test_faviconLoadEncodedUrl(row) {
+ webEngineView.profile = row.profile
compare(iconChangedSpy.count, 0)
var url = Qt.resolvedUrl("favicon2.html?favicon=load should work with#whitespace!")
@@ -133,11 +148,62 @@ TestWebEngineView {
iconChangedSpy.wait()
compare(iconChangedSpy.count, 1)
- compare(favicon.width, 16)
- compare(favicon.height, 16)
+ tryCompare(favicon, "status", Image.Ready)
+ compare(favicon.width, 32)
+ compare(favicon.height, 32)
}
- function test_noFavicon() {
+ function test_faviconLoadAfterHistoryNavigation_data() {
+ return [
+ { tag: "OTR", profile: defaultProfile },
+ { tag: "non-OTR", profile: nonOTRProfile },
+ ];
+ }
+
+ function test_faviconLoadAfterHistoryNavigation(row) {
+ webEngineView.profile = row.profile
+ compare(iconChangedSpy.count, 0)
+
+ var iconUrl
+
+ webEngineView.url = Qt.resolvedUrl("favicon.html")
+ verify(webEngineView.waitForLoadSucceeded())
+ tryCompare(iconChangedSpy, "count", 1)
+ iconUrl = removeFaviconProviderPrefix(webEngineView.icon)
+ compare(iconUrl, Qt.resolvedUrl("icons/favicon.png"))
+
+ iconChangedSpy.clear()
+ webEngineView.url = Qt.resolvedUrl("favicon-shortcut.html")
+ verify(webEngineView.waitForLoadSucceeded())
+ tryCompare(iconChangedSpy, "count", 2)
+ iconUrl = removeFaviconProviderPrefix(webEngineView.icon)
+ compare(iconUrl, Qt.resolvedUrl("icons/qt32.ico"))
+
+ iconChangedSpy.clear()
+ webEngineView.goBack();
+ verify(webEngineView.waitForLoadSucceeded())
+ tryCompare(iconChangedSpy, "count", 2)
+ iconUrl = removeFaviconProviderPrefix(webEngineView.icon)
+ compare(iconUrl, Qt.resolvedUrl("icons/favicon.png"))
+
+ iconChangedSpy.clear()
+ webEngineView.goForward();
+ verify(webEngineView.waitForLoadSucceeded())
+ tryCompare(iconChangedSpy, "count", 2)
+ iconUrl = removeFaviconProviderPrefix(webEngineView.icon)
+ compare(iconUrl, Qt.resolvedUrl("icons/qt32.ico"))
+ }
+
+
+ function test_noFavicon_data() {
+ return [
+ { tag: "OTR", profile: defaultProfile },
+ { tag: "non-OTR", profile: nonOTRProfile },
+ ];
+ }
+
+ function test_noFavicon(row) {
+ webEngineView.profile = row.profile
compare(iconChangedSpy.count, 0)
var url = Qt.resolvedUrl("test1.html")
@@ -150,7 +216,15 @@ TestWebEngineView {
compare(iconUrl, Qt.resolvedUrl(""))
}
- function test_aboutBlank() {
+ function test_aboutBlank_data() {
+ return [
+ { tag: "OTR", profile: defaultProfile },
+ { tag: "non-OTR", profile: nonOTRProfile },
+ ];
+ }
+
+ function test_aboutBlank(row) {
+ webEngineView.profile = row.profile
compare(iconChangedSpy.count, 0)
var url = Qt.resolvedUrl("about:blank")
@@ -163,7 +237,15 @@ TestWebEngineView {
compare(iconUrl, Qt.resolvedUrl(""))
}
- function test_unavailableFavicon() {
+ function test_unavailableFavicon_data() {
+ return [
+ { tag: "OTR", profile: defaultProfile },
+ { tag: "non-OTR", profile: nonOTRProfile },
+ ];
+ }
+
+ function test_unavailableFavicon(row) {
+ webEngineView.profile = row.profile
compare(iconChangedSpy.count, 0)
var url = Qt.resolvedUrl("favicon-unavailable.html")
@@ -176,15 +258,25 @@ TestWebEngineView {
compare(iconUrl, Qt.resolvedUrl(""))
}
- function test_errorPageEnabled() {
- WebEngine.settings.errorPageEnabled = true
+ function test_errorPageEnabled_data() {
+ return [
+ { tag: "OTR", profile: defaultProfile },
+ { tag: "non-OTR", profile: nonOTRProfile },
+ ];
+ }
+
+ function test_errorPageEnabled(row) {
+ webEngineView.profile = row.profile
+ webEngineView.settings.errorPageEnabled = true
compare(iconChangedSpy.count, 0)
var url = Qt.resolvedUrl("http://url.invalid")
webEngineView.url = url
verify(webEngineView.waitForLoadFailed(20000))
- verify(webEngineView.testSupport.waitForErrorPageLoadSucceeded())
+ // FIXME: Wait for error page load to finish.
+ // This should be done without testSupport API.
+ wait(500)
compare(iconChangedSpy.count, 0)
@@ -192,8 +284,16 @@ TestWebEngineView {
compare(iconUrl, Qt.resolvedUrl(""))
}
- function test_errorPageDisabled() {
- WebEngine.settings.errorPageEnabled = false
+ function test_errorPageDisabled_data() {
+ return [
+ { tag: "OTR", profile: defaultProfile },
+ { tag: "non-OTR", profile: nonOTRProfile },
+ ];
+ }
+
+ function test_errorPageDisabled(row) {
+ webEngineView.profile = row.profile
+ webEngineView.settings.errorPageEnabled = false
compare(iconChangedSpy.count, 0)
@@ -207,7 +307,15 @@ TestWebEngineView {
compare(iconUrl, Qt.resolvedUrl(""))
}
- function test_bestFavicon() {
+ function test_bestFavicon_data() {
+ return [
+ { tag: "OTR", profile: defaultProfile },
+ { tag: "non-OTR", profile: nonOTRProfile },
+ ];
+ }
+
+ function test_bestFavicon(row) {
+ webEngineView.profile = row.profile
compare(iconChangedSpy.count, 0)
var url, iconUrl
@@ -221,6 +329,7 @@ TestWebEngineView {
iconUrl = removeFaviconProviderPrefix(webEngineView.icon)
// Touch icon is ignored
compare(iconUrl, Qt.resolvedUrl("icons/qt32.ico"))
+ tryCompare(favicon, "status", Image.Ready)
compare(favicon.width, 32)
compare(favicon.height, 32)
@@ -230,23 +339,25 @@ TestWebEngineView {
webEngineView.url = url
verify(webEngineView.waitForLoadSucceeded())
- iconChangedSpy.wait()
- verify(iconChangedSpy.count >= 1)
+ tryCompare(iconChangedSpy, "count", 2)
iconUrl = removeFaviconProviderPrefix(webEngineView.icon)
- // If the icon URL is empty we have to wait for
- // the second iconChanged signal that propagates the expected URL
- if (iconUrl == Qt.resolvedUrl("")) {
- tryCompare(iconChangedSpy, "count", 2)
- iconUrl = removeFaviconProviderPrefix(webEngineView.icon)
- }
+ // If touch icon is disabled, FaviconHandler propagates the icon closest to size 16x16
+ compare(iconUrl, Qt.resolvedUrl("icons/qt32.ico"))
+ tryCompare(favicon, "status", Image.Ready)
+ compare(favicon.width, 32)
+ compare(favicon.height, 32)
+ }
- compare(iconUrl, Qt.resolvedUrl("icons/qt144.png"))
- compare(favicon.width, 144)
- compare(favicon.height, 144)
+ function test_touchIcon_data() {
+ return [
+ { tag: "OTR", profile: defaultProfile },
+ { tag: "non-OTR", profile: nonOTRProfile },
+ ];
}
- function test_touchIcon() {
+ function test_touchIcon(row) {
+ webEngineView.profile = row.profile
compare(iconChangedSpy.count, 0)
var url = Qt.resolvedUrl("favicon-touch.html")
@@ -260,7 +371,7 @@ TestWebEngineView {
compare(favicon.width, 0)
compare(favicon.height, 0)
- WebEngine.settings.touchIconsEnabled = true
+ webEngineView.settings.touchIconsEnabled = true
url = Qt.resolvedUrl("favicon-touch.html")
webEngineView.url = url
@@ -270,11 +381,20 @@ TestWebEngineView {
iconUrl = removeFaviconProviderPrefix(webEngineView.icon)
compare(iconUrl, Qt.resolvedUrl("icons/qt144.png"))
compare(iconChangedSpy.count, 1)
+ tryCompare(favicon, "status", Image.Ready)
compare(favicon.width, 144)
compare(favicon.height, 144)
}
- function test_multiIcon() {
+ function test_multiIcon_data() {
+ return [
+ { tag: "OTR", profile: defaultProfile },
+ { tag: "non-OTR", profile: nonOTRProfile },
+ ];
+ }
+
+ function test_multiIcon(row) {
+ webEngineView.profile = row.profile
compare(iconChangedSpy.count, 0)
var url = Qt.resolvedUrl("favicon-multi.html")
@@ -283,61 +403,24 @@ TestWebEngineView {
iconChangedSpy.wait()
compare(iconChangedSpy.count, 1)
- compare(favicon.width, 64)
- compare(favicon.height, 64)
+ tryCompare(favicon, "status", Image.Ready)
+ compare(favicon.width, 32)
+ compare(favicon.height, 32)
}
- function test_faviconProvider_data() {
+ function test_dynamicFavicon_data() {
return [
- { tag: "multi 8x8", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 8, value: 16 },
- { tag: "multi 16x16", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 16, value: 16 },
- { tag: "multi 17x17", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 17, value: 32 },
- { tag: "multi 31x31", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 31, value: 32 },
- { tag: "multi 32x32", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 32, value: 32 },
- { tag: "multi 33x33", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 33, value: 64 },
- { tag: "multi 64x64", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 64, value: 64 },
- { tag: "multi 128x128", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 128, value: 128 },
- { tag: "multi 255x255", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 255, value: 255 },
- { tag: "multi 256x256", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 256, value: 255 },
- { tag: "candidate 8x8", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 8, value: 16 },
- { tag: "candidate 16x16", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 16, value: 16 },
- { tag: "candidate 17x17", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 17, value: 32 },
- { tag: "candidate 31x31", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 31, value: 32 },
- { tag: "candidate 32x32", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 32, value: 32 },
- { tag: "candidate 33x33", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 33, value: 64 },
- { tag: "candidate 64x64", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 64, value: 64 },
- { tag: "candidate 128x128", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 128, value: 128 },
- { tag: "candidate 255x255", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 255, value: 255 },
- { tag: "candidate 256x256", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 256, value: 255 },
+ { tag: "OTR", profile: defaultProfile },
+ { tag: "non-OTR", profile: nonOTRProfile },
];
}
- function test_faviconProvider(row) {
- var faviconImage = Qt.createQmlObject("
- import QtQuick 2.5\n
- Image { sourceSize: Qt.size(width, height) }", testCase)
-
+ function test_dynamicFavicon(row) {
+ webEngineView.profile = row.profile
compare(iconChangedSpy.count, 0)
- webEngineView.url = row.url
- verify(webEngineView.waitForLoadSucceeded())
-
- iconChangedSpy.wait()
- compare(iconChangedSpy.count, 1)
-
- faviconImage.width = row.size / Screen.devicePixelRatio
- faviconImage.height = row.size / Screen.devicePixelRatio
- faviconImage.source = webEngineView.icon
-
- var pixel = getFaviconPixel(faviconImage);
- compare(pixel[0], row.value)
-
- faviconImage.destroy()
- }
-
- function test_dynamicFavicon() {
var faviconImage = Qt.createQmlObject("
- import QtQuick 2.5\n
+ import QtQuick\n
Image { width: 16; height: 16; sourceSize: Qt.size(width, height); }", testCase)
faviconImage.source = Qt.binding(function() { return webEngineView.icon; });
@@ -377,9 +460,17 @@ TestWebEngineView {
faviconImage.destroy()
}
- function test_touchIconWithSameURL()
+ function test_touchIconWithSameURL_data() {
+ return [
+ { tag: "OTR", profile: defaultProfile },
+ { tag: "non-OTR", profile: nonOTRProfile },
+ ];
+ }
+
+ function test_touchIconWithSameURL(row)
{
- WebEngine.settings.touchIconsEnabled = false;
+ webEngineView.profile = row.profile;
+ compare(iconChangedSpy.count, 0);
var icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=";
@@ -409,5 +500,53 @@ TestWebEngineView {
tryCompare(iconChangedSpy, "count", 1);
verify(!webEngineView.icon.toString().replace(/^image:\/\/favicon\//, ''));
}
+
+ function test_iconsDisabled_data() {
+ return [
+ { tag: "misc", url: Qt.resolvedUrl("favicon-misc.html") },
+ { tag: "shortcut", url: Qt.resolvedUrl("favicon-shortcut.html") },
+ { tag: "single", url: Qt.resolvedUrl("favicon-single.html") },
+ { tag: "touch", url: Qt.resolvedUrl("favicon-touch.html") },
+ { tag: "unavailable", url: Qt.resolvedUrl("favicon-unavailable.html") },
+ ];
+ }
+
+ function test_iconsDisabled(row) {
+ webEngineView.settings.autoLoadIconsForPage = false
+ webEngineView.profile = defaultProfile
+ compare(iconChangedSpy.count, 0)
+
+ webEngineView.url = row.url
+ verify(webEngineView.waitForLoadSucceeded())
+
+ compare(iconChangedSpy.count, 0)
+
+ var iconUrl = webEngineView.icon
+ compare(iconUrl, Qt.resolvedUrl(""))
+ }
+
+ function test_touchIconsEnabled_data() {
+ return [
+ { tag: "misc", url: Qt.resolvedUrl("favicon-misc.html"), expectedIconUrl: Qt.resolvedUrl("icons/qt144.png") },
+ { tag: "shortcut", url: Qt.resolvedUrl("favicon-shortcut.html"), expectedIconUrl: Qt.resolvedUrl("icons/qt144.png") },
+ { tag: "single", url: Qt.resolvedUrl("favicon-single.html"), expectedIconUrl: Qt.resolvedUrl("icons/qt32.ico") },
+ { tag: "touch", url: Qt.resolvedUrl("favicon-touch.html"), expectedIconUrl: Qt.resolvedUrl("icons/qt144.png") },
+ ];
+ }
+
+ function test_touchIconsEnabled(row) {
+ webEngineView.settings.touchIconsEnabled = true
+ webEngineView.profile = defaultProfile
+ compare(iconChangedSpy.count, 0)
+
+ webEngineView.url = row.url
+ verify(webEngineView.waitForLoadSucceeded())
+
+ iconChangedSpy.wait()
+ compare(iconChangedSpy.count, 1)
+
+ var iconUrl = removeFaviconProviderPrefix(webEngineView.icon)
+ compare(iconUrl, row.expectedIconUrl)
+ }
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_faviconDownload.qml b/tests/auto/quick/qmltests/data/tst_faviconDownload.qml
deleted file mode 100644
index 7d9c39814..000000000
--- a/tests/auto/quick/qmltests/data/tst_faviconDownload.qml
+++ /dev/null
@@ -1,121 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.0
-import QtTest 1.0
-import QtWebEngine 1.3
-import "../../qmltests/data" 1.0
-
-TestWebEngineView {
- id: webEngineView
- width: 200
- height: 400
-
- function removeFaviconProviderPrefix(url) {
- return url.toString().substring(16)
- }
-
- SignalSpy {
- id: iconChangedSpy
- target: webEngineView
- signalName: "iconChanged"
- }
-
- TestCase {
- id: testCase
- name: "WebEngineFaviconDownload"
-
- function init() {
- WebEngine.settings.autoLoadIconsForPage = true
- WebEngine.settings.touchIconsEnabled = false
-
- if (webEngineView.icon != '') {
- // If this is not the first test, then load a blank page without favicon, restoring the initial state.
- webEngineView.url = 'about:blank'
- verify(webEngineView.waitForLoadSucceeded())
- iconChangedSpy.wait()
- }
-
- iconChangedSpy.clear()
- }
-
- function cleanupTestCase() {
- WebEngine.settings.autoLoadIconsForPage = true
- WebEngine.settings.touchIconsEnabled = false
- }
-
- function test_downloadIconsDisabled_data() {
- return [
- { tag: "misc", url: Qt.resolvedUrl("favicon-misc.html") },
- { tag: "shortcut", url: Qt.resolvedUrl("favicon-shortcut.html") },
- { tag: "single", url: Qt.resolvedUrl("favicon-single.html") },
- { tag: "touch", url: Qt.resolvedUrl("favicon-touch.html") },
- { tag: "unavailable", url: Qt.resolvedUrl("favicon-unavailable.html") },
- ];
- }
-
- function test_downloadIconsDisabled(row) {
- WebEngine.settings.autoLoadIconsForPage = false
-
- compare(iconChangedSpy.count, 0)
-
- webEngineView.url = row.url
- verify(webEngineView.waitForLoadSucceeded())
-
- compare(iconChangedSpy.count, 0)
-
- var iconUrl = webEngineView.icon
- compare(iconUrl, Qt.resolvedUrl(""))
- }
-
- function test_downloadTouchIconsEnabled_data() {
- return [
- { tag: "misc", url: Qt.resolvedUrl("favicon-misc.html"), expectedIconUrl: Qt.resolvedUrl("icons/qt144.png") },
- { tag: "shortcut", url: Qt.resolvedUrl("favicon-shortcut.html"), expectedIconUrl: Qt.resolvedUrl("icons/qt144.png") },
- { tag: "single", url: Qt.resolvedUrl("favicon-single.html"), expectedIconUrl: Qt.resolvedUrl("icons/qt32.ico") },
- { tag: "touch", url: Qt.resolvedUrl("favicon-touch.html"), expectedIconUrl: Qt.resolvedUrl("icons/qt144.png") },
- ];
- }
-
- function test_downloadTouchIconsEnabled(row) {
- WebEngine.settings.touchIconsEnabled = true
-
- compare(iconChangedSpy.count, 0)
-
- webEngineView.url = row.url
- verify(webEngineView.waitForLoadSucceeded())
-
- iconChangedSpy.wait()
- compare(iconChangedSpy.count, 1)
-
- var iconUrl = removeFaviconProviderPrefix(webEngineView.icon)
- compare(iconUrl, row.expectedIconUrl)
- }
- }
-}
-
diff --git a/tests/auto/widgets/CMakeLists.txt b/tests/auto/widgets/CMakeLists.txt
index 7072329c3..f7955b1f8 100644
--- a/tests/auto/widgets/CMakeLists.txt
+++ b/tests/auto/widgets/CMakeLists.txt
@@ -5,7 +5,7 @@ if(NOT boot2qt)
add_subdirectory(qwebengineprofile)
add_subdirectory(qwebengineview)
endif()
-add_subdirectory(faviconmanager)
+add_subdirectory(favicon)
add_subdirectory(loadsignals)
add_subdirectory(origins)
add_subdirectory(proxy)
diff --git a/tests/auto/widgets/faviconmanager/CMakeLists.txt b/tests/auto/widgets/favicon/CMakeLists.txt
index 89bee5a2a..64c4efc91 100644
--- a/tests/auto/widgets/faviconmanager/CMakeLists.txt
+++ b/tests/auto/widgets/favicon/CMakeLists.txt
@@ -1,14 +1,14 @@
include(../../util/util.cmake)
-qt_internal_add_test(tst_faviconmanager
+qt_internal_add_test(tst_favicon
SOURCES
- tst_faviconmanager.cpp
+ tst_favicon.cpp
LIBRARIES
Qt::WebEngineWidgets
Test::Util
)
-set(tst_faviconmanager_resource_files
+set(tst_favicon_resource_files
"resources/favicon-misc.html"
"resources/favicon-multi.html"
"resources/favicon-shortcut.html"
@@ -21,9 +21,9 @@ set(tst_faviconmanager_resource_files
"resources/test1.html"
)
-qt_add_resource(tst_faviconmanager "tst_faviconmanager"
+qt_add_resource(tst_favicon "tst_favicon"
PREFIX
"/"
FILES
- ${tst_faviconmanager_resource_files}
+ ${tst_favicon_resource_files}
)
diff --git a/tests/auto/widgets/faviconmanager/faviconmanager.pro b/tests/auto/widgets/favicon/favicon.pro
index e99c7f493..e99c7f493 100644
--- a/tests/auto/widgets/faviconmanager/faviconmanager.pro
+++ b/tests/auto/widgets/favicon/favicon.pro
diff --git a/tests/auto/widgets/faviconmanager/resources/favicon-misc.html b/tests/auto/widgets/favicon/resources/favicon-misc.html
index 9e788bdf4..ea587886f 100644
--- a/tests/auto/widgets/faviconmanager/resources/favicon-misc.html
+++ b/tests/auto/widgets/favicon/resources/favicon-misc.html
@@ -1,8 +1,8 @@
<html>
<head>
<title>Favicon Test</title>
- <link rel="shortcut icon" href="icons/qt32.ico" />
- <link rel="apple-touch-icon" href="icons/qt144.png" />
+ <link rel="shortcut icon" href="icons/qt32.ico" sizes="32x32" />
+ <link rel="apple-touch-icon" href="icons/qt144.png" sizes="144x144" />
<link rel="shortcut icon" href="icons/unavailable.ico" />
</head>
<body>
diff --git a/tests/auto/widgets/faviconmanager/resources/favicon-multi.html b/tests/auto/widgets/favicon/resources/favicon-multi.html
index cc5f3fd66..56eeca8c4 100644
--- a/tests/auto/widgets/faviconmanager/resources/favicon-multi.html
+++ b/tests/auto/widgets/favicon/resources/favicon-multi.html
@@ -1,7 +1,7 @@
<html>
<head>
<title>Multi-sized Favicon Test</title>
- <link rel="shortcut icon" sizes="16x16 32x23 64x64" href="icons/qtmulti.ico" />
+ <link rel="shortcut icon" sizes="16x16 32x32 64x64" href="icons/qtmulti.ico" />
</head>
<body>
<h1>Multi-sized Favicon Test</h1>
diff --git a/tests/auto/widgets/faviconmanager/resources/favicon-shortcut.html b/tests/auto/widgets/favicon/resources/favicon-shortcut.html
index 786cdb816..786cdb816 100644
--- a/tests/auto/widgets/faviconmanager/resources/favicon-shortcut.html
+++ b/tests/auto/widgets/favicon/resources/favicon-shortcut.html
diff --git a/tests/auto/widgets/faviconmanager/resources/favicon-single.html b/tests/auto/widgets/favicon/resources/favicon-single.html
index eb4675c75..eb4675c75 100644
--- a/tests/auto/widgets/faviconmanager/resources/favicon-single.html
+++ b/tests/auto/widgets/favicon/resources/favicon-single.html
diff --git a/tests/auto/widgets/faviconmanager/resources/favicon-touch.html b/tests/auto/widgets/favicon/resources/favicon-touch.html
index 271783434..271783434 100644
--- a/tests/auto/widgets/faviconmanager/resources/favicon-touch.html
+++ b/tests/auto/widgets/favicon/resources/favicon-touch.html
diff --git a/tests/auto/widgets/faviconmanager/resources/favicon-unavailable.html b/tests/auto/widgets/favicon/resources/favicon-unavailable.html
index c45664294..c45664294 100644
--- a/tests/auto/widgets/faviconmanager/resources/favicon-unavailable.html
+++ b/tests/auto/widgets/favicon/resources/favicon-unavailable.html
diff --git a/tests/auto/widgets/faviconmanager/resources/icons/qt144.png b/tests/auto/widgets/favicon/resources/icons/qt144.png
index 050b1e066..050b1e066 100644
--- a/tests/auto/widgets/faviconmanager/resources/icons/qt144.png
+++ b/tests/auto/widgets/favicon/resources/icons/qt144.png
Binary files differ
diff --git a/tests/auto/widgets/faviconmanager/resources/icons/qt32.ico b/tests/auto/widgets/favicon/resources/icons/qt32.ico
index 2f6fcb5bc..2f6fcb5bc 100644
--- a/tests/auto/widgets/faviconmanager/resources/icons/qt32.ico
+++ b/tests/auto/widgets/favicon/resources/icons/qt32.ico
Binary files differ
diff --git a/tests/auto/widgets/faviconmanager/resources/icons/qtmulti.ico b/tests/auto/widgets/favicon/resources/icons/qtmulti.ico
index 81e5a22e8..81e5a22e8 100644
--- a/tests/auto/widgets/faviconmanager/resources/icons/qtmulti.ico
+++ b/tests/auto/widgets/favicon/resources/icons/qtmulti.ico
Binary files differ
diff --git a/tests/auto/widgets/faviconmanager/resources/test1.html b/tests/auto/widgets/favicon/resources/test1.html
index b323f966e..b323f966e 100644
--- a/tests/auto/widgets/faviconmanager/resources/test1.html
+++ b/tests/auto/widgets/favicon/resources/test1.html
diff --git a/tests/auto/widgets/faviconmanager/tst_faviconmanager.cpp b/tests/auto/widgets/favicon/tst_favicon.cpp
index 8e9bb2470..377699aaa 100644
--- a/tests/auto/widgets/faviconmanager/tst_faviconmanager.cpp
+++ b/tests/auto/widgets/favicon/tst_favicon.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -29,13 +29,13 @@
#include <QtTest/QtTest>
#include <util.h>
-#include <qwebenginepage.h>
-#include <qwebengineprofile.h>
-#include <qwebenginesettings.h>
-#include <qwebengineview.h>
+#include <QWebEnginePage>
+#include <QWebEngineProfile>
+#include <QWebEngineSettings>
+#include <QWebEngineView>
-
-class tst_FaviconManager : public QObject {
+class tst_Favicon : public QObject
+{
Q_OBJECT
public Q_SLOTS:
@@ -48,15 +48,14 @@ private Q_SLOTS:
void faviconLoad();
void faviconLoadFromResources();
void faviconLoadEncodedUrl();
+ void faviconLoadAfterHistoryNavigation();
void noFavicon();
void aboutBlank();
void unavailableFavicon();
void errorPageEnabled();
void errorPageDisabled();
- void bestFavicon();
void touchIcon();
void multiIcon();
- void candidateIcon();
void downloadIconsDisabled_data();
void downloadIconsDisabled();
void downloadTouchIconsEnabled_data();
@@ -70,8 +69,7 @@ private:
QWebEngineProfile *m_profile;
};
-
-void tst_FaviconManager::init()
+void tst_Favicon::init()
{
m_profile = new QWebEngineProfile(this);
m_view = new QWebEngineView();
@@ -79,23 +77,17 @@ void tst_FaviconManager::init()
m_view->setPage(m_page);
}
+void tst_Favicon::initTestCase() { }
-void tst_FaviconManager::initTestCase()
-{
-}
-
-void tst_FaviconManager::cleanupTestCase()
-{
-}
-
+void tst_Favicon::cleanupTestCase() { }
-void tst_FaviconManager::cleanup()
+void tst_Favicon::cleanup()
{
delete m_view;
delete m_profile;
}
-void tst_FaviconManager::faviconLoad()
+void tst_Favicon::faviconLoad()
{
if (!QDir(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()).exists())
W_QSKIP(QString("This test requires access to resources found in '%1'")
@@ -125,12 +117,12 @@ void tst_FaviconManager::faviconLoad()
const QIcon &icon = m_page->icon();
QVERIFY(!icon.isNull());
- QCOMPARE(icon.availableSizes().count(), 1);
- QSize iconSize = icon.availableSizes().first();
- QCOMPARE(iconSize, QSize(32, 32));
+ QCOMPARE(icon.availableSizes().count(), 2);
+ QVERIFY(icon.availableSizes().contains(QSize(16, 16)));
+ QVERIFY(icon.availableSizes().contains(QSize(32, 32)));
}
-void tst_FaviconManager::faviconLoadFromResources()
+void tst_Favicon::faviconLoadFromResources()
{
QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
@@ -150,12 +142,12 @@ void tst_FaviconManager::faviconLoadFromResources()
const QIcon &icon = m_page->icon();
QVERIFY(!icon.isNull());
- QCOMPARE(icon.availableSizes().count(), 1);
- QSize iconSize = icon.availableSizes().first();
- QCOMPARE(iconSize, QSize(32, 32));
+ QCOMPARE(icon.availableSizes().count(), 2);
+ QVERIFY(icon.availableSizes().contains(QSize(16, 16)));
+ QVERIFY(icon.availableSizes().contains(QSize(32, 32)));
}
-void tst_FaviconManager::faviconLoadEncodedUrl()
+void tst_Favicon::faviconLoadEncodedUrl()
{
if (!QDir(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()).exists())
W_QSKIP(QString("This test requires access to resources found in '%1'")
@@ -187,12 +179,43 @@ void tst_FaviconManager::faviconLoadEncodedUrl()
const QIcon &icon = m_page->icon();
QVERIFY(!icon.isNull());
- QCOMPARE(icon.availableSizes().count(), 1);
- QSize iconSize = icon.availableSizes().first();
- QCOMPARE(iconSize, QSize(32, 32));
+ QCOMPARE(icon.availableSizes().count(), 2);
+ QVERIFY(icon.availableSizes().contains(QSize(16, 16)));
+ QVERIFY(icon.availableSizes().contains(QSize(32, 32)));
+}
+
+void tst_Favicon::faviconLoadAfterHistoryNavigation()
+{
+ QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
+ QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
+ QSignalSpy iconChangedSpy(m_page, SIGNAL(iconChanged(QIcon)));
+
+ m_page->load(QUrl("qrc:/resources/favicon-single.html"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
+ QTRY_COMPARE(iconChangedSpy.count(), 1);
+ QCOMPARE(m_page->iconUrl(), QUrl("qrc:/resources/icons/qt32.ico"));
+
+ m_page->load(QUrl("qrc:/resources/favicon-multi.html"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 2, 30000);
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 3);
+ QTRY_COMPARE(iconChangedSpy.count(), 3);
+ QCOMPARE(m_page->iconUrl(), QUrl("qrc:/resources/icons/qtmulti.ico"));
+
+ m_page->triggerAction(QWebEnginePage::Back);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 3, 30000);
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 5);
+ QTRY_COMPARE(iconChangedSpy.count(), 5);
+ QCOMPARE(m_page->iconUrl(), QUrl("qrc:/resources/icons/qt32.ico"));
+
+ m_page->triggerAction(QWebEnginePage::Forward);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 4, 30000);
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 7);
+ QTRY_COMPARE(iconChangedSpy.count(), 7);
+ QCOMPARE(m_page->iconUrl(), QUrl("qrc:/resources/icons/qtmulti.ico"));
}
-void tst_FaviconManager::noFavicon()
+void tst_Favicon::noFavicon()
{
if (!QDir(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()).exists())
W_QSKIP(QString("This test requires access to resources found in '%1'")
@@ -217,7 +240,7 @@ void tst_FaviconManager::noFavicon()
QVERIFY(m_page->icon().isNull());
}
-void tst_FaviconManager::aboutBlank()
+void tst_Favicon::aboutBlank()
{
QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
@@ -234,7 +257,7 @@ void tst_FaviconManager::aboutBlank()
QVERIFY(m_page->icon().isNull());
}
-void tst_FaviconManager::unavailableFavicon()
+void tst_Favicon::unavailableFavicon()
{
if (!QDir(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()).exists())
W_QSKIP(QString("This test requires access to resources found in '%1'")
@@ -259,7 +282,7 @@ void tst_FaviconManager::unavailableFavicon()
QVERIFY(m_page->icon().isNull());
}
-void tst_FaviconManager::errorPageEnabled()
+void tst_Favicon::errorPageEnabled()
{
m_page->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, true);
@@ -278,7 +301,7 @@ void tst_FaviconManager::errorPageEnabled()
QVERIFY(m_page->icon().isNull());
}
-void tst_FaviconManager::errorPageDisabled()
+void tst_Favicon::errorPageDisabled()
{
m_page->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
@@ -297,80 +320,7 @@ void tst_FaviconManager::errorPageDisabled()
QVERIFY(m_page->icon().isNull());
}
-void tst_FaviconManager::bestFavicon()
-{
- if (!QDir(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()).exists())
- W_QSKIP(QString("This test requires access to resources found in '%1'")
- .arg(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath())
- .toLatin1()
- .constData(),
- SkipAll);
-
- QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
- QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
- QSignalSpy iconChangedSpy(m_page, SIGNAL(iconChanged(QIcon)));
-
- QUrl url, iconUrl;
- QIcon icon;
- QSize iconSize;
-
- url = QUrl::fromLocalFile(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
- + QLatin1String("/resources/favicon-misc.html"));
- m_page->load(url);
-
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
- QTRY_COMPARE(iconChangedSpy.count(), 1);
-
- iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
- QCOMPARE(iconUrl, m_page->iconUrl());
- // Touch icon is ignored
- QCOMPARE(iconUrl,
- QUrl::fromLocalFile(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
- + QLatin1String("/resources/icons/qt32.ico")));
-
- icon = m_page->icon();
- QVERIFY(!icon.isNull());
-
- QCOMPARE(icon.availableSizes().count(), 1);
- iconSize = icon.availableSizes().first();
- QCOMPARE(iconSize, QSize(32, 32));
-
- loadFinishedSpy.clear();
- iconUrlChangedSpy.clear();
- iconChangedSpy.clear();
-
- url = QUrl::fromLocalFile(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
- + QLatin1String("/resources/favicon-shortcut.html"));
- m_page->load(url);
-
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
- QTRY_VERIFY(iconUrlChangedSpy.count() >= 1);
- QTRY_VERIFY(iconChangedSpy.count() >= 1);
-
- iconUrl = iconUrlChangedSpy.last().at(0).toString();
-
- // If the icon URL is empty we have to wait for
- // the second iconChanged signal that propagates the expected URL
- if (iconUrl.isEmpty()) {
- QTRY_COMPARE(iconUrlChangedSpy.count(), 2);
- QTRY_COMPARE(iconChangedSpy.count(), 2);
- iconUrl = iconUrlChangedSpy.last().at(0).toString();
- }
-
- QCOMPARE(iconUrl, m_page->iconUrl());
- QCOMPARE(iconUrl,
- QUrl::fromLocalFile(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
- + QLatin1String("/resources/icons/qt144.png")));
-
- icon = m_page->icon();
- QVERIFY(!icon.isNull());
-
- QVERIFY(icon.availableSizes().count() >= 1);
- QVERIFY(icon.availableSizes().contains(QSize(144, 144)));
-}
-
-void tst_FaviconManager::touchIcon()
+void tst_Favicon::touchIcon()
{
if (!QDir(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()).exists())
W_QSKIP(QString("This test requires access to resources found in '%1'")
@@ -395,7 +345,7 @@ void tst_FaviconManager::touchIcon()
QVERIFY(m_page->icon().isNull());
}
-void tst_FaviconManager::multiIcon()
+void tst_Favicon::multiIcon()
{
if (!QDir(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()).exists())
W_QSKIP(QString("This test requires access to resources found in '%1'")
@@ -410,61 +360,60 @@ void tst_FaviconManager::multiIcon()
QUrl url = QUrl::fromLocalFile(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
+ QLatin1String("/resources/favicon-multi.html"));
+ QUrl iconUrl;
+ QIcon icon;
+
+ // If touch icons are disabled, the favicon is provided in two sizes (16x16 and 32x32) according
+ // to the supported scale factors (100P, 200P).
+ m_page->settings()->setAttribute(QWebEngineSettings::TouchIconsEnabled, false);
m_page->load(url);
QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
QTRY_COMPARE(iconChangedSpy.count(), 1);
- QUrl iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
+ iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
QCOMPARE(m_page->iconUrl(), iconUrl);
QCOMPARE(iconUrl,
QUrl::fromLocalFile(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
+ QLatin1String("/resources/icons/qtmulti.ico")));
- const QIcon &icon = m_page->icon();
+ icon = m_page->icon();
QVERIFY(!icon.isNull());
- QCOMPARE(icon.availableSizes().count(), 3);
+ QCOMPARE(icon.availableSizes().count(), 2);
QVERIFY(icon.availableSizes().contains(QSize(16, 16)));
QVERIFY(icon.availableSizes().contains(QSize(32, 32)));
- QVERIFY(icon.availableSizes().contains(QSize(64, 64)));
-}
-void tst_FaviconManager::candidateIcon()
-{
- if (!QDir(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()).exists())
- W_QSKIP(QString("This test requires access to resources found in '%1'")
- .arg(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath())
- .toLatin1()
- .constData(),
- SkipAll);
-
- QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
- QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
- QSignalSpy iconChangedSpy(m_page, SIGNAL(iconChanged(QIcon)));
+ // Reset
+ loadFinishedSpy.clear();
+ m_page->load(QUrl("about:blank"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
+ iconUrlChangedSpy.clear();
+ iconChangedSpy.clear();
+ loadFinishedSpy.clear();
+ icon = QIcon();
- QUrl url = QUrl::fromLocalFile(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
- + QLatin1String("/resources/favicon-shortcut.html"));
+ // If touch icons are enabled, the largest icon is provided.
+ m_page->settings()->setAttribute(QWebEngineSettings::TouchIconsEnabled, true);
m_page->load(url);
QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
QTRY_COMPARE(iconChangedSpy.count(), 1);
- QUrl iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
+ iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
QCOMPARE(m_page->iconUrl(), iconUrl);
QCOMPARE(iconUrl,
QUrl::fromLocalFile(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
- + QLatin1String("/resources/icons/qt144.png")));
+ + QLatin1String("/resources/icons/qtmulti.ico")));
- const QIcon &icon = m_page->icon();
+ icon = m_page->icon();
QVERIFY(!icon.isNull());
- QCOMPARE(icon.availableSizes().count(), 2);
- QVERIFY(icon.availableSizes().contains(QSize(32, 32)));
- QVERIFY(icon.availableSizes().contains(QSize(144, 144)));
+ QCOMPARE(icon.availableSizes().count(), 1);
+ QVERIFY(icon.availableSizes().contains(QSize(64, 64)));
}
-void tst_FaviconManager::downloadIconsDisabled_data()
+void tst_Favicon::downloadIconsDisabled_data()
{
QTest::addColumn<QUrl>("url");
QTest::newRow("misc") << QUrl("qrc:/resources/favicon-misc.html");
@@ -474,7 +423,7 @@ void tst_FaviconManager::downloadIconsDisabled_data()
QTest::newRow("unavailable") << QUrl("qrc:/resources/favicon-unavailable.html");
}
-void tst_FaviconManager::downloadIconsDisabled()
+void tst_Favicon::downloadIconsDisabled()
{
QFETCH(QUrl, url);
@@ -494,18 +443,22 @@ void tst_FaviconManager::downloadIconsDisabled()
QVERIFY(m_page->icon().isNull());
}
-void tst_FaviconManager::downloadTouchIconsEnabled_data()
+void tst_Favicon::downloadTouchIconsEnabled_data()
{
QTest::addColumn<QUrl>("url");
QTest::addColumn<QUrl>("expectedIconUrl");
QTest::addColumn<QSize>("expectedIconSize");
- QTest::newRow("misc") << QUrl("qrc:/resources/favicon-misc.html") << QUrl("qrc:/resources/icons/qt144.png") << QSize(144, 144);
- QTest::newRow("shortcut") << QUrl("qrc:/resources/favicon-shortcut.html") << QUrl("qrc:/resources/icons/qt144.png") << QSize(144, 144);
- QTest::newRow("single") << QUrl("qrc:/resources/favicon-single.html") << QUrl("qrc:/resources/icons/qt32.ico") << QSize(32, 32);
- QTest::newRow("touch") << QUrl("qrc:/resources/favicon-touch.html") << QUrl("qrc:/resources/icons/qt144.png") << QSize(144, 144);
+ QTest::newRow("misc") << QUrl("qrc:/resources/favicon-misc.html")
+ << QUrl("qrc:/resources/icons/qt144.png") << QSize(144, 144);
+ QTest::newRow("shortcut") << QUrl("qrc:/resources/favicon-shortcut.html")
+ << QUrl("qrc:/resources/icons/qt144.png") << QSize(144, 144);
+ QTest::newRow("single") << QUrl("qrc:/resources/favicon-single.html")
+ << QUrl("qrc:/resources/icons/qt32.ico") << QSize(32, 32);
+ QTest::newRow("touch") << QUrl("qrc:/resources/favicon-touch.html")
+ << QUrl("qrc:/resources/icons/qt144.png") << QSize(144, 144);
}
-void tst_FaviconManager::downloadTouchIconsEnabled()
+void tst_Favicon::downloadTouchIconsEnabled()
{
QFETCH(QUrl, url);
QFETCH(QUrl, expectedIconUrl);
@@ -530,23 +483,27 @@ void tst_FaviconManager::downloadTouchIconsEnabled()
const QIcon &icon = m_page->icon();
QVERIFY(!icon.isNull());
- QVERIFY(icon.availableSizes().count() >= 1);
- QVERIFY(icon.availableSizes().contains(expectedIconSize));
+ QCOMPARE(icon.availableSizes().count(), 1);
+ QCOMPARE(icon.availableSizes().first(), expectedIconSize);
}
-void tst_FaviconManager::dynamicFavicon()
+void tst_Favicon::dynamicFavicon()
{
QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
QSignalSpy iconChangedSpy(m_page, SIGNAL(iconChanged(QIcon)));
QMap<Qt::GlobalColor, QString> colors;
- colors.insert(Qt::red, QString("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg=="));
- colors.insert(Qt::green, QString("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M/wHwAEBgIApD5fRAAAAABJRU5ErkJggg=="));
- colors.insert(Qt::blue, QString("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPj/HwADBwIAMCbHYQAAAABJRU5ErkJggg=="));
+ colors.insert(Qt::red,
+ QString("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg=="));
+ colors.insert(Qt::green,
+ QString("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M/wHwAEBgIApD5fRAAAAABJRU5ErkJggg=="));
+ colors.insert(Qt::blue,
+ QString("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPj/HwADBwIAMCbHYQAAAABJRU5ErkJggg=="));
m_page->setHtml("<html>"
- "<link rel='icon' type='image/png' href='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII='/>"
+ "<link rel='icon' type='image/png' "
+ "href='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII='/>"
"</html>");
QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
@@ -556,14 +513,17 @@ void tst_FaviconManager::dynamicFavicon()
for (Qt::GlobalColor color : colors.keys()) {
iconChangedSpy.clear();
- evaluateJavaScriptSync(m_page, "document.getElementsByTagName('link')[0].href = 'data:image/png;base64," + colors[color] + "';");
+ evaluateJavaScriptSync(
+ m_page,
+ "document.getElementsByTagName('link')[0].href = 'data:image/png;base64," + colors[color] + "';");
QTRY_COMPARE(iconChangedSpy.count(), 1);
- QTRY_COMPARE(m_page->iconUrl().toString(), QString("data:image/png;base64," + colors[color]));
+ QTRY_COMPARE(m_page->iconUrl().toString(),
+ QString("data:image/png;base64," + colors[color]));
QCOMPARE(m_page->icon().pixmap(1, 1).toImage().pixelColor(0, 0), QColor(color));
}
}
-void tst_FaviconManager::touchIconWithSameURL()
+void tst_Favicon::touchIconWithSameURL()
{
m_page->settings()->setAttribute(QWebEngineSettings::TouchIconsEnabled, false);
@@ -578,7 +538,8 @@ void tst_FaviconManager::touchIconWithSameURL()
"</html>");
QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
- // The default favicon has to be loaded even if its URL is also set as a touch icon while touch icons are disabled.
+ // The default favicon has to be loaded even if its URL is also set as a touch icon while touch
+ // icons are disabled.
QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
QCOMPARE(m_page->iconUrl().toString(), icon);
QTRY_COMPARE(iconChangedSpy.count(), 1);
@@ -592,14 +553,13 @@ void tst_FaviconManager::touchIconWithSameURL()
"</html>");
QTRY_COMPARE(loadFinishedSpy.count(), 1);
- // This page only has a touch icon. With disabled touch icons we don't expect any icon to be shown even if the same icon
- // was loaded previously.
+ // This page only has a touch icon. With disabled touch icons we don't expect any icon to be
+ // shown even if the same icon was loaded previously.
QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
QVERIFY(m_page->iconUrl().toString().isEmpty());
QTRY_COMPARE(iconChangedSpy.count(), 1);
-
}
-QTEST_MAIN(tst_FaviconManager)
+QTEST_MAIN(tst_Favicon)
-#include "tst_faviconmanager.moc"
+#include "tst_favicon.moc"
diff --git a/tests/auto/widgets/faviconmanager/tst_faviconmanager.qrc b/tests/auto/widgets/favicon/tst_favicon.qrc
index a352f8a83..a352f8a83 100644
--- a/tests/auto/widgets/faviconmanager/tst_faviconmanager.qrc
+++ b/tests/auto/widgets/favicon/tst_favicon.qrc
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 432a91224..170afaafc 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -311,7 +311,8 @@ void tst_QWebEngineView::changePage()
if (!fromIsNullPage) {
QVERIFY(!pageFrom->iconUrl().isEmpty());
QCOMPARE(spyIconUrl.last().value(0).toUrl(), pageFrom->iconUrl());
- QCOMPARE(spyIcon.last().value(0).value<QIcon>(), pageFrom->icon());
+ QCOMPARE(spyIcon.last().value(0).value<QIcon>().availableSizes(),
+ pageFrom->icon().availableSizes());
}
QScopedPointer<QWebEnginePage> pageTo(new QWebEnginePage);
@@ -340,7 +341,8 @@ void tst_QWebEngineView::changePage()
QCOMPARE(pageFrom->iconUrl() == pageTo->iconUrl(), iconIsSame);
if (!iconIsSame) {
QCOMPARE(spyIconUrl.last().value(0).toUrl(), pageTo->iconUrl());
- QCOMPARE(spyIcon.last().value(0).value<QIcon>(), pageTo->icon());
+ QCOMPARE(spyIcon.last().value(0).value<QIcon>().availableSizes(),
+ pageTo->icon().availableSizes());
}
// verify no emits on destroy with the same number of signals in spy
diff --git a/tests/manual/quick/faviconbrowser/AddressBar.qml b/tests/manual/quick/faviconbrowser/AddressBar.qml
deleted file mode 100644
index c79b74f30..000000000
--- a/tests/manual/quick/faviconbrowser/AddressBar.qml
+++ /dev/null
@@ -1,102 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.5
-import QtQuick.Controls 1.4
-import QtQuick.Controls.Styles 1.4
-
-Rectangle {
- id: root
-
- property int progress: 0
- property url iconUrl: ""
- property url pageUrl: ""
-
- signal accepted(url addressUrl)
-
- clip: true
-
- onActiveFocusChanged: {
- if (activeFocus)
- addressField.forceActiveFocus();
- }
-
- Rectangle {
- width: addressField.width / 100 * root.progress
- height: root.height
-
- visible: root.progress < 100
-
- color: "#b6dca6"
- radius: root.radius
- }
-
- TextField {
- id: addressField
- anchors.fill: parent
-
- Image {
- anchors.verticalCenter: addressField.verticalCenter
- x: 5; z: parent.z + 1
- width: 16; height: 16
- sourceSize: Qt.size(width, height)
- source: root.iconUrl
- visible: root.progress == 100
- }
-
- Text {
- text: root.progress < 0 ? "" : root.progress + "%"
- x: 5; z: parent.z + 1
- font.bold: true
- anchors.verticalCenter: parent.verticalCenter
-
- visible: root.progress < 100
- }
-
- style: TextFieldStyle {
- padding.left: 30
-
- background: Rectangle {
- color: "transparent"
- border.color: "black"
- border.width: 1
- radius: root.radius
- }
- }
-
- onActiveFocusChanged: {
- if (activeFocus)
- selectAll();
- else
- deselect();
- }
-
- text: root.pageUrl
- onAccepted: root.accepted(utils.fromUserInput(text))
- }
-}
diff --git a/tests/manual/quick/faviconbrowser/FaviconPanel.qml b/tests/manual/quick/faviconbrowser/FaviconPanel.qml
deleted file mode 100644
index 857019d9a..000000000
--- a/tests/manual/quick/faviconbrowser/FaviconPanel.qml
+++ /dev/null
@@ -1,234 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.5
-import QtQuick.Controls 1.4
-import QtQuick.Controls.Styles 1.4
-import QtQuick.Layouts 1.1
-
-Item {
- id: root
-
- property url iconUrl: ""
- property int iconSize: 128
- property int iconMinimumSize: 8
- property int iconMaximumSize: 256
-
- RowLayout {
- anchors.fill: parent
- spacing: 2
-
- Rectangle {
- Layout.fillWidth: true
- Layout.fillHeight: true
-
- RowLayout {
- anchors.fill: parent
- spacing: 2
-
- Rectangle {
- Layout.fillHeight: true
- Layout.preferredWidth: (parent.width - 2 * parent.spacing) / 3
-
- border.color: "black"
- border.width: 1
- clip: true
-
- Text {
- z: parent.z + 1
- anchors.top: parent.top
- anchors.topMargin: 5
- anchors.left: parent.left
- anchors.leftMargin: 5
- font.bold: true
-
- text: "faviconImage"
- }
-
- Image {
- id: faviconImage
- anchors.centerIn: parent
-
- width: root.iconSize
- height: width
- sourceSize: Qt.size(width, height)
-
- source: root.iconUrl
-
- onStatusChanged: {
- if (status == Image.Ready) {
- grabToImage(function(result) {
- grabImage.source = result.url;
- });
- }
-
- if (status == Image.Null)
- grabImage.source = "";
- }
- }
- }
-
- Rectangle {
- Layout.fillHeight: true
- Layout.preferredWidth: (parent.width - 2 * parent.spacing) / 3
-
- border.color: "black"
- border.width: 1
- clip: true
-
- Text {
- z: parent.z + 1
- anchors.top: parent.top
- anchors.topMargin: 5
- anchors.left: parent.left
- anchors.leftMargin: 5
- font.bold: true
-
- text: "grabImage"
- }
-
- Image {
- id: grabImage
- anchors.centerIn: parent
-
- width: root.iconSize
- height: width
-
- onStatusChanged: {
- if (status == Image.Ready || status == Image.Null)
- faviconCanvas.requestPaint();
- }
- }
- }
-
- Rectangle {
- Layout.fillHeight: true
- Layout.preferredWidth: (parent.width - 2 * parent.spacing) / 3
-
- border.color: "black"
- border.width: 1
- clip: true
-
- Text {
- z: parent.z + 1
- anchors.top: parent.top
- anchors.topMargin: 5
- anchors.left: parent.left
- anchors.leftMargin: 5
- font.bold: true
-
- text: "faviconCanvas"
- }
-
- Canvas {
- id: faviconCanvas
- anchors.centerIn: parent
-
- width: root.iconSize
- height: width
-
- onPaint: {
- var ctx = getContext("2d");
- ctx.reset();
- ctx.clearRect(0, 0, width, height);
-
- if (grabImage.source == "")
- return;
-
- ctx.drawImage(grabImage, 0, 0, width, height);
-
- var imageData = ctx.getImageData(width/2, height/2, width/2, height/2);
- var pixel = imageData.data;
-
- verbose.append("pixel(" + width/2 + ", " + height/2 + "): " + pixel[0] + ", " + pixel[1] + ", " + pixel[2]);
- }
- }
- }
- }
- }
-
- Rectangle {
- Layout.fillHeight: true
- Layout.preferredWidth: 100
-
- Slider {
- id: faviconSizeSlider
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.top: parent.top
- anchors.bottom: faviconSizeSpin.top
-
- orientation: Qt.Vertical
- minimumValue: root.iconMinimumSize
- maximumValue: root.iconMaximumSize
- stepSize: 1
- tickmarksEnabled: true
- value: root.iconSize
-
- onValueChanged: {
- if (pressed && value != root.iconSize)
- root.iconSize = value;
- }
- }
-
- SpinBox {
- id: faviconSizeSpin
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.bottom: parent.bottom
-
- minimumValue: root.iconMinimumSize
- maximumValue: root.iconMaximumSize
- value: root.iconSize
-
- onEditingFinished: {
- if (value != root.iconSize)
- root.iconSize = value;
- }
- }
- }
-
- TextArea {
- id: verbose
-
- Layout.fillHeight: true
- Layout.preferredWidth: 310
-
- readOnly: true
- tabChangesFocus: true
-
- font.family: "Monospace"
- font.pointSize: 12
-
- textFormat: TextEdit.RichText
- frameVisible: false
-
- style: TextAreaStyle {
- backgroundColor: "lightgray"
- }
- }
- }
-}
diff --git a/tests/manual/quick/faviconbrowser/faviconbrowser.pro b/tests/manual/quick/faviconbrowser/faviconbrowser.pro
deleted file mode 100644
index d997d6322..000000000
--- a/tests/manual/quick/faviconbrowser/faviconbrowser.pro
+++ /dev/null
@@ -1,23 +0,0 @@
-QT += qml quick webenginequick
-qtHaveModule(widgets) {
- QT += widgets # QApplication is required to get native styling with QtQuickControls
-}
-
-TARGET = faviconbrowser
-TEMPLATE = app
-
-
-SOURCES = \
- main.cpp
-
-HEADERS = \
- utils.h
-
-OTHER_FILES += \
- main.qml \
- AddressBar.qml \
- FaviconPanel.qml
-
-RESOURCES += \
- faviconbrowser.qrc
-
diff --git a/tests/manual/quick/faviconbrowser/faviconbrowser.qrc b/tests/manual/quick/faviconbrowser/faviconbrowser.qrc
deleted file mode 100644
index b641fa2fa..000000000
--- a/tests/manual/quick/faviconbrowser/faviconbrowser.qrc
+++ /dev/null
@@ -1,17 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
- <qresource prefix="/">
- <file>main.qml</file>
- <file>AddressBar.qml</file>
- <file>FaviconPanel.qml</file>
- </qresource>
- <qresource prefix="test">
- <file alias="favicon-multi-gray.html">../../../auto/quick/qmltests2/data/favicon-multi-gray.html</file>
- <file alias="favicon-candidates-gray.html">../../../auto/quick/qmltests2/data/favicon-candidates-gray.html</file>
- <file alias="icons/grayicons.ico">../../../auto/quick/qmltests2/data/icons/grayicons.ico</file>
- <file alias="icons/gray16.png">../../../auto/quick/qmltests2/data/icons/gray16.png</file>
- <file alias="icons/gray32.png">../../../auto/quick/qmltests2/data/icons/gray32.png</file>
- <file alias="icons/gray64.png">../../../auto/quick/qmltests2/data/icons/gray64.png</file>
- <file alias="icons/gray128.png">../../../auto/quick/qmltests2/data/icons/gray128.png</file>
- <file alias="icons/gray255.png">../../../auto/quick/qmltests2/data/icons/gray255.png</file>
- </qresource>
-</RCC>
diff --git a/tests/manual/quick/faviconbrowser/main.cpp b/tests/manual/quick/faviconbrowser/main.cpp
deleted file mode 100644
index d1faadfa0..000000000
--- a/tests/manual/quick/faviconbrowser/main.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "utils.h"
-
-#ifndef QT_NO_WIDGETS
-#include <QtWidgets/QApplication>
-typedef QApplication Application;
-#else
-#include <QtGui/QGuiApplication>
-typedef QGuiApplication Application;
-#endif
-#include <QtQml/QQmlApplicationEngine>
-#include <QtQml/QQmlContext>
-#include <QtWebEngineQuick/qtwebengineglobal.h>
-
-int main(int argc, char **argv)
-{
- Application app(argc, argv);
-
- QtWebEngine::initialize();
-
- QQmlApplicationEngine appEngine;
- Utils utils;
- appEngine.rootContext()->setContextProperty("utils", &utils);
- appEngine.load(QUrl("qrc:/main.qml"));
-
- return app.exec();
-}
diff --git a/tests/manual/quick/faviconbrowser/main.qml b/tests/manual/quick/faviconbrowser/main.qml
deleted file mode 100644
index c8e2bdbd5..000000000
--- a/tests/manual/quick/faviconbrowser/main.qml
+++ /dev/null
@@ -1,170 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.5
-import QtQuick.Controls 1.4
-import QtQuick.Layouts 1.1
-import QtWebEngine 1.3
-import Qt.labs.settings 1.0
-
-ApplicationWindow {
- width: 1300
- height: 900
- visible: true
-
- Item {
- id: bookmarkUrls
-
- property url multiTest: Qt.resolvedUrl("qrc:/test/favicon-multi-gray.html")
- property url candidatesTest: Qt.resolvedUrl("qrc:/test/favicon-candidates-gray.html")
- property url aboutBlank: Qt.resolvedUrl("about:blank")
- property url qtHome: Qt.resolvedUrl("http://www.qt.io/")
- }
-
- Settings {
- id: appSettings
-
- property alias autoLoadIconsForPage: autoLoadIconsForPage.checked
- property alias touchIconsEnabled: touchIconsEnabled.checked
- }
-
- SplitView {
- anchors.fill: parent
- orientation: Qt.Vertical
-
- FaviconPanel {
- id: faviconPanel
-
- Layout.fillWidth: true
- Layout.minimumHeight: 200
-
- Layout.margins: 2
-
- iconUrl: webEngineView && webEngineView.icon
- }
-
- ColumnLayout {
- Layout.fillWidth: true
- Layout.fillHeight: true
- Layout.topMargin: 2
-
- AddressBar {
- id: addressBar
-
- Layout.fillWidth: true
- Layout.leftMargin: 5
- Layout.rightMargin: 5
- height: 25
-
- color: "white"
- radius: 4
-
- progress: webEngineView && webEngineView.loadProgress
- iconUrl: webEngineView && webEngineView.icon
- pageUrl: webEngineView && webEngineView.url
-
- onAccepted: webEngineView.url = addressUrl
- }
-
- Rectangle {
- id: toolBar
-
- Layout.fillWidth: true
- Layout.leftMargin: 5
- Layout.rightMargin: 5
- Layout.preferredHeight: 25
-
- RowLayout {
- anchors.verticalCenter: parent.verticalCenter
-
- Button {
- text: "Multi-sized Favicon Test"
- onClicked: webEngineView.url = bookmarkUrls.multiTest
- enabled: webEngineView.url != bookmarkUrls.multiTest
- }
-
- Button {
- text: "Candidate Favicons Test"
- onClicked: webEngineView.url = bookmarkUrls.candidatesTest
- enabled: webEngineView.url != bookmarkUrls.candidatesTest
- }
-
- Button {
- text: "About Blank"
- onClicked: webEngineView.url = bookmarkUrls.aboutBlank
- enabled: webEngineView.url != bookmarkUrls.aboutBlank
- }
-
- Button {
- text: "Qt Home Page"
- onClicked: webEngineView.url = bookmarkUrls.qtHome
- enabled: webEngineView.url != bookmarkUrls.qtHome
- }
- }
-
- ToolButton {
- anchors.verticalCenter: parent.verticalCenter
- anchors.right: parent.right
-
- menu: Menu {
- MenuItem {
- id: autoLoadIconsForPage
- text: "Icons On"
- checkable: true
- checked: WebEngine.settings.autoLoadIconsForPage
-
- onCheckedChanged: webEngineView.reload()
- }
-
- MenuItem {
- id: touchIconsEnabled
- text: "Touch Icons On"
- checkable: true
- checked: WebEngine.settings.touchIconsEnabled
- enabled: autoLoadIconsForPage.checked
-
- onCheckedChanged: webEngineView.reload()
- }
- }
- }
- }
-
- WebEngineView {
- id: webEngineView
-
- Layout.fillWidth: true
- Layout.fillHeight: true
-
- settings.autoLoadIconsForPage: appSettings.autoLoadIconsForPage
- settings.touchIconsEnabled: appSettings.touchIconsEnabled
-
- Component.onCompleted: webEngineView.url = bookmarkUrls.multiTest
- }
- }
- }
-}
diff --git a/tests/manual/quick/faviconbrowser/utils.h b/tests/manual/quick/faviconbrowser/utils.h
deleted file mode 100644
index 9deef0b61..000000000
--- a/tests/manual/quick/faviconbrowser/utils.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef UTILS_H
-#define UTILS_H
-
-#include <QtCore/QFileInfo>
-#include <QtCore/QUrl>
-
-class Utils : public QObject {
- Q_OBJECT
-public:
- Q_INVOKABLE static QUrl fromUserInput(const QString& userInput);
-};
-
-inline QUrl Utils::fromUserInput(const QString& userInput)
-{
- QFileInfo fileInfo(userInput);
- if (fileInfo.exists())
- return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
- return QUrl::fromUserInput(userInput);
-}
-
-#endif // UTILS_H