[Qt][WK2] Implement favicon support
authorhausmann@webkit.org <hausmann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Dec 2011 11:49:21 +0000 (11:49 +0000)
committerhausmann@webkit.org <hausmann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Dec 2011 11:49:21 +0000 (11:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=71082

Patch by Rafael Brandao <rafael.lobo@openbossa.org> on 2011-12-20
Reviewed by Simon Hausmann.

.:

* Source/qtwebkit-export.map: Added new classes.

Source/WebKit/qt:

* declarative/plugin.cpp:
(WebKitQmlPlugin::initializeEngine): Setup for the QDeclarativeImageProvider to display favicons.
Its handles the following url format: "image://webicon/<iconID>#<pageURL>".

Source/WebKit2:

Added attribute to QQuickWebView named "icon" that should be used
as source for QQuickImage in order to display it. All images
pointing to it will refresh when the icon is ready. We also use IDs
to make it possible to handle different icons for the same page URL
at different times (i.e. dynamically changing favicon).

IconDatabase storage lies on UIProcess and the synchronous call for
the icon that happens on WebIconDatabase won't need to send any message
to WebProcess. The part of IconDatabase on WebProcess handles the download
of the resource whenever it is needed. Then the content downloaded is sent
through IPC to the actual database, on UIProcess.

* Target.pri:
* UIProcess/API/qt/qquickwebview.cpp:
(QQuickWebViewPrivate::initialize):
(QQuickWebViewPrivate::_q_onIconChangedForPageURL):
(QQuickWebViewPrivate::setIcon):
(QQuickWebView::icon):
* UIProcess/API/qt/qquickwebview_p.h:
* UIProcess/API/qt/qquickwebview_p_p.h:
* UIProcess/API/qt/qwebiconimageprovider.cpp: Added.
(QWebIconImageProvider::QWebIconImageProvider):
(QWebIconImageProvider::~QWebIconImageProvider):
(QWebIconImageProvider::requestImage):
* UIProcess/API/qt/qwebiconimageprovider_p.h: Added.
* UIProcess/WebContext.h:
* UIProcess/WebIconDatabase.cpp:
(WebKit::WebIconDatabase::synchronousIconURLForPageURL):
(WebKit::WebIconDatabase::imageForPageURL): Added iconSize parameter
and a default value for it to not break the old usage. The support for
multiple sizes of favicons is still missing on WebCore.
* UIProcess/WebIconDatabase.h:
* UIProcess/qt/QtWebContext.cpp:
(WebKit::QtWebContext::initialize):
* UIProcess/qt/QtWebContext.h:
(WebKit::QtWebContext::iconDatabase):
* UIProcess/qt/QtWebIconDatabaseClient.cpp: Added.
(toQtWebIconDatabaseClient):
(QtWebIconDatabaseClient::QtWebIconDatabaseClient):
(QtWebIconDatabaseClient::~QtWebIconDatabaseClient):
(QtWebIconDatabaseClient::didChangeIconForPageURL):
(QtWebIconDatabaseClient::iconImageForPageURL):
(QtWebIconDatabaseClient::iconURLHashForPageURL):
(QtWebIconDatabaseClient::requestIconForPageURL):
(QtWebIconDatabaseClient::retainIconForPageURL):
(QtWebIconDatabaseClient::releaseIconForPageURL):
* UIProcess/qt/QtWebIconDatabaseClient.h: Added.
* UIProcess/qt/QtWebPageLoadClient.cpp:
(QtWebPageLoadClient::didStartProgress):

Tools:

A favorite icon was added on MiniBrowser's url bar as example.
We display a default icon when the page doesn't have an icon ready.

* MiniBrowser/qt/MiniBrowser.qrc:
* MiniBrowser/qt/icons/favicon.png: Added.
* MiniBrowser/qt/qml/BrowserWindow.qml:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@103316 268f45cc-cd09-0410-ab3c-d52691b4dbfc

23 files changed:
ChangeLog
Source/WebKit/qt/ChangeLog
Source/WebKit/qt/declarative/plugin.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/Target.pri
Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp
Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h
Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h
Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider.cpp [new file with mode: 0644]
Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h [new file with mode: 0644]
Source/WebKit2/UIProcess/WebContext.h
Source/WebKit2/UIProcess/WebIconDatabase.cpp
Source/WebKit2/UIProcess/WebIconDatabase.h
Source/WebKit2/UIProcess/qt/QtWebContext.cpp
Source/WebKit2/UIProcess/qt/QtWebContext.h
Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp [new file with mode: 0644]
Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.h [new file with mode: 0644]
Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.cpp
Source/qtwebkit-export.map
Tools/ChangeLog
Tools/MiniBrowser/qt/MiniBrowser.qrc
Tools/MiniBrowser/qt/icons/favicon.png [new file with mode: 0644]
Tools/MiniBrowser/qt/qml/BrowserWindow.qml

index 5672bf0..ca551d9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2011-12-20  Rafael Brandao  <rafael.lobo@openbossa.org>
+
+        [Qt][WK2] Implement favicon support
+        https://bugs.webkit.org/show_bug.cgi?id=71082
+
+        Reviewed by Simon Hausmann.
+
+        * Source/qtwebkit-export.map: Added new classes.
+
 2011-12-18  Simon Hausmann  <simon.hausmann@nokia.com>
 
         Rename EditCommandQt to UndoStepQt
index 6d6a6e3..db81930 100644 (file)
@@ -1,3 +1,14 @@
+2011-12-20  Rafael Brandao  <rafael.lobo@openbossa.org>
+
+        [Qt][WK2] Implement favicon support
+        https://bugs.webkit.org/show_bug.cgi?id=71082
+
+        Reviewed by Simon Hausmann.
+
+        * declarative/plugin.cpp:
+        (WebKitQmlPlugin::initializeEngine): Setup for the QDeclarativeImageProvider to display favicons.
+        Its handles the following url format: "image://webicon/<iconID>#<pageURL>".
+
 2011-12-19  Sam Weinig  <sam@webkit.org>
 
         More PlatformEvent cleanup
index bafbb59..64638e4 100644 (file)
 #if defined(HAVE_WEBKIT2)
 #include "qquickwebpage_p.h"
 #include "qquickwebview_p.h"
+#include "qwebiconimageprovider_p.h"
 #include "qwebnavigationrequest_p.h"
 #include "qwebpermissionrequest_p.h"
 #include "qwebpreferences_p.h"
 
+#include <QtDeclarative/qdeclarativeengine.h>
 #include <QtNetwork/qnetworkreply.h>
 #endif
 
@@ -37,6 +39,14 @@ QT_BEGIN_NAMESPACE
 class WebKitQmlPlugin : public QDeclarativeExtensionPlugin {
     Q_OBJECT
 public:
+#if defined(HAVE_WEBKIT2)
+    virtual void initializeEngine(QDeclarativeEngine* engine, const char* uri)
+    {
+        Q_ASSERT(QLatin1String(uri) == QLatin1String("QtWebKit"));
+        engine->addImageProvider(QLatin1String("webicon"), new QWebIconImageProvider);
+    }
+#endif
+
     virtual void registerTypes(const char* uri)
     {
         Q_ASSERT(QLatin1String(uri) == QLatin1String("QtWebKit"));
index dfd0d2b..72477cb 100644 (file)
@@ -1,3 +1,60 @@
+2011-12-20  Rafael Brandao  <rafael.lobo@openbossa.org>
+
+        [Qt][WK2] Implement favicon support
+        https://bugs.webkit.org/show_bug.cgi?id=71082
+
+        Reviewed by Simon Hausmann.
+
+        Added attribute to QQuickWebView named "icon" that should be used
+        as source for QQuickImage in order to display it. All images
+        pointing to it will refresh when the icon is ready. We also use IDs
+        to make it possible to handle different icons for the same page URL
+        at different times (i.e. dynamically changing favicon).
+
+        IconDatabase storage lies on UIProcess and the synchronous call for
+        the icon that happens on WebIconDatabase won't need to send any message
+        to WebProcess. The part of IconDatabase on WebProcess handles the download
+        of the resource whenever it is needed. Then the content downloaded is sent
+        through IPC to the actual database, on UIProcess.
+
+        * Target.pri:
+        * UIProcess/API/qt/qquickwebview.cpp:
+        (QQuickWebViewPrivate::initialize):
+        (QQuickWebViewPrivate::_q_onIconChangedForPageURL):
+        (QQuickWebViewPrivate::setIcon):
+        (QQuickWebView::icon):
+        * UIProcess/API/qt/qquickwebview_p.h:
+        * UIProcess/API/qt/qquickwebview_p_p.h:
+        * UIProcess/API/qt/qwebiconimageprovider.cpp: Added.
+        (QWebIconImageProvider::QWebIconImageProvider):
+        (QWebIconImageProvider::~QWebIconImageProvider):
+        (QWebIconImageProvider::requestImage):
+        * UIProcess/API/qt/qwebiconimageprovider_p.h: Added.
+        * UIProcess/WebContext.h:
+        * UIProcess/WebIconDatabase.cpp:
+        (WebKit::WebIconDatabase::synchronousIconURLForPageURL):
+        (WebKit::WebIconDatabase::imageForPageURL): Added iconSize parameter
+        and a default value for it to not break the old usage. The support for
+        multiple sizes of favicons is still missing on WebCore.
+        * UIProcess/WebIconDatabase.h:
+        * UIProcess/qt/QtWebContext.cpp:
+        (WebKit::QtWebContext::initialize):
+        * UIProcess/qt/QtWebContext.h:
+        (WebKit::QtWebContext::iconDatabase):
+        * UIProcess/qt/QtWebIconDatabaseClient.cpp: Added.
+        (toQtWebIconDatabaseClient):
+        (QtWebIconDatabaseClient::QtWebIconDatabaseClient):
+        (QtWebIconDatabaseClient::~QtWebIconDatabaseClient):
+        (QtWebIconDatabaseClient::didChangeIconForPageURL):
+        (QtWebIconDatabaseClient::iconImageForPageURL):
+        (QtWebIconDatabaseClient::iconURLHashForPageURL):
+        (QtWebIconDatabaseClient::requestIconForPageURL):
+        (QtWebIconDatabaseClient::retainIconForPageURL):
+        (QtWebIconDatabaseClient::releaseIconForPageURL):
+        * UIProcess/qt/QtWebIconDatabaseClient.h: Added.
+        * UIProcess/qt/QtWebPageLoadClient.cpp:
+        (QtWebPageLoadClient::didStartProgress):
+
 2011-12-20  Jesus Sanchez-Palencia  <jesus.palencia@openbossa.org>
 
         [Qt] Improve QQuickWebView error handling API
index 541f94a..2a4fe75 100644 (file)
@@ -271,6 +271,7 @@ HEADERS += \
     UIProcess/qt/QtSGTileNode.h \
     UIProcess/qt/QtViewportInteractionEngine.h \
     UIProcess/qt/QtWebUndoController.h \
+    UIProcess/qt/QtWebIconDatabaseClient.h \
     UIProcess/qt/WebContextMenuProxyQt.h \
     UIProcess/qt/WebGeolocationProviderQt.h \
     UIProcess/qt/WebPopupMenuProxyQt.h \
@@ -502,6 +503,7 @@ SOURCES += \
     UIProcess/API/qt/qquickwebpage.cpp \
     UIProcess/API/qt/qwebnavigationhistory.cpp \
     UIProcess/API/qt/qquickwebview.cpp \
+    UIProcess/API/qt/qwebiconimageprovider.cpp \
     UIProcess/API/qt/qwebpreferences.cpp \
     UIProcess/API/qt/qwebviewportinfo.cpp \
     UIProcess/Authentication/AuthenticationChallengeProxy.cpp \
@@ -602,6 +604,7 @@ SOURCES += \
     UIProcess/qt/WebPageProxyQt.cpp \
     UIProcess/qt/WebPopupMenuProxyQt.cpp \
     UIProcess/qt/WebPreferencesQt.cpp \
+    UIProcess/qt/QtWebIconDatabaseClient.cpp \
     WebProcess/ApplicationCache/WebApplicationCacheManager.cpp \
     WebProcess/Authentication/AuthenticationManager.cpp \
     WebProcess/Cookies/WebCookieManager.cpp \
index 7004804..5e13ae1 100644 (file)
@@ -26,6 +26,7 @@
 #include "QtDialogRunner.h"
 #include "QtDownloadManager.h"
 #include "QtWebContext.h"
+#include "QtWebIconDatabaseClient.h"
 #include "QtWebPageEventHandler.h"
 #include "UtilsQt.h"
 #include "WebBackForwardList.h"
@@ -46,6 +47,7 @@
 #include <QFileDialog>
 #include <QtQuick/QQuickCanvas>
 #include <WKOpenPanelResultListener.h>
+#include <wtf/text/WTFString.h>
 
 QQuickWebViewPrivate::QQuickWebViewPrivate(QQuickWebView* viewport)
     : q_ptr(viewport)
@@ -90,6 +92,11 @@ void QQuickWebViewPrivate::initialize(WKContextRef contextRef, WKPageGroupRef pa
     pageUIClient.reset(new QtWebPageUIClient(toAPI(webPageProxy.get()), q_ptr));
     navigationHistory = adoptPtr(QWebNavigationHistoryPrivate::createHistory(toAPI(webPageProxy.get())));
 
+    RefPtr<QtWebContext> context = QtWebContext::defaultContext();
+    QtWebIconDatabaseClient* iconDatabase = context->iconDatabase();
+    QObject::connect(iconDatabase, SIGNAL(iconChangedForPageURL(QUrl, QUrl)), q_ptr, SLOT(_q_onIconChangedForPageURL(QUrl, QUrl)));
+    QObject::connect(q_ptr, SIGNAL(urlChanged(QUrl)), iconDatabase, SLOT(requestIconForPageURL(QUrl)));
+
     // Any page setting should preferrable be set before creating the page.
     setUseTraditionalDesktopBehaviour(false);
     webPageProxy->pageGroup()->preferences()->setAcceleratedCompositingEnabled(true);
@@ -164,6 +171,15 @@ void QQuickWebViewPrivate::didFinishFirstNonEmptyLayout()
     }
 }
 
+void QQuickWebViewPrivate::_q_onIconChangedForPageURL(const QUrl& pageURL, const QUrl& iconURL)
+{
+    Q_Q(QQuickWebView);
+    if (q->url() != pageURL)
+        return;
+
+    setIcon(iconURL);
+}
+
 void QQuickWebViewPrivate::_q_suspend()
 {
     pageIsSuspended = true;
@@ -501,6 +517,29 @@ void QQuickWebViewPrivate::setViewInAttachedProperties(QObject* object)
     attached->setView(q);
 }
 
+void QQuickWebViewPrivate::setIcon(const QUrl& iconURL)
+{
+    Q_Q(QQuickWebView);
+    if (m_iconURL == iconURL)
+        return;
+
+    String oldPageURL = QUrl::fromPercentEncoding(m_iconURL.encodedFragment());
+    String newPageURL = webPageProxy->mainFrame()->url();
+
+    if (oldPageURL != newPageURL) {
+        RefPtr<QtWebContext> context = QtWebContext::defaultContext();
+        QtWebIconDatabaseClient* iconDatabase = context->iconDatabase();
+        if (!oldPageURL.isEmpty())
+            iconDatabase->releaseIconForPageURL(oldPageURL);
+
+        if (!newPageURL.isEmpty())
+            iconDatabase->retainIconForPageURL(newPageURL);
+    }
+
+    m_iconURL = iconURL;
+    emit q->iconChanged(m_iconURL);
+}
+
 bool QQuickWebViewPrivate::navigatorQtObjectEnabled() const
 {
     return m_navigatorQtObjectEnabled;
@@ -750,6 +789,12 @@ QUrl QQuickWebView::url() const
     return QUrl(QString(mainFrame->url()));
 }
 
+QUrl QQuickWebView::icon() const
+{
+    Q_D(const QQuickWebView);
+    return d->m_iconURL;
+}
+
 int QQuickWebView::loadProgress() const
 {
     Q_D(const QQuickWebView);
index 5f1f328..38f23bc 100644 (file)
@@ -53,6 +53,7 @@ class QWEBKIT_EXPORT QQuickWebView : public QQuickItem {
     Q_OBJECT
     Q_PROPERTY(QString title READ title NOTIFY titleChanged)
     Q_PROPERTY(QUrl url READ url NOTIFY urlChanged)
+    Q_PROPERTY(QUrl icon READ icon NOTIFY iconChanged FINAL)
     Q_PROPERTY(int loadProgress READ loadProgress NOTIFY loadProgressChanged)
     Q_PROPERTY(bool canGoBack READ canGoBack NOTIFY navigationStateChanged FINAL)
     Q_PROPERTY(bool canGoForward READ canGoForward NOTIFY navigationStateChanged FINAL)
@@ -78,6 +79,7 @@ public:
     virtual ~QQuickWebView();
 
     QUrl url() const;
+    QUrl icon() const;
     QString title() const;
     int loadProgress() const;
 
@@ -110,6 +112,7 @@ Q_SIGNALS:
     void loadFailed(QQuickWebView::ErrorDomain errorDomain, int errorCode, const QUrl& url, const QString& description);
     void loadProgressChanged(int progress);
     void urlChanged(const QUrl& url);
+    void iconChanged(const QUrl& iconURL);
     void linkHovered(const QUrl& url, const QString& title);
     void navigationStateChanged();
     void navigationRequested(QWebNavigationRequest* request);
@@ -132,6 +135,7 @@ private:
     Q_PRIVATE_SLOT(d_func(), void _q_onOpenPanelFinished(int result));
     Q_PRIVATE_SLOT(d_func(), void _q_onVisibleChanged());
     Q_PRIVATE_SLOT(d_func(), void _q_onReceivedResponseFromDownload(QWebDownloadItem*));
+    Q_PRIVATE_SLOT(d_func(), void _q_onIconChangedForPageURL(const QUrl&, const QUrl&));
     // Hides QObject::d_ptr allowing us to use the convenience macros.
     QScopedPointer<QQuickWebViewPrivate> d_ptr;
     QQuickWebViewExperimental* m_experimental;
index a96d434..3b99928 100644 (file)
@@ -89,6 +89,7 @@ public:
     void _q_onOpenPanelFinished(int result);
     void _q_onVisibleChanged();
     void _q_onReceivedResponseFromDownload(QWebDownloadItem*);
+    void _q_onIconChangedForPageURL(const QUrl& pageURL, const QUrl& iconURLString);
 
     void chooseFiles(WKOpenPanelResultListenerRef, const QStringList& selectedFileNames, QtWebPageUIClient::FileChooserType);
     void runJavaScriptAlert(const QString&);
@@ -97,6 +98,7 @@ public:
 
     void setUseTraditionalDesktopBehaviour(bool enable);
     void setViewInAttachedProperties(QObject*);
+    void setIcon(const QUrl&);
 
     bool navigatorQtObjectEnabled() const;
     void setNavigatorQtObjectEnabled(bool);
@@ -160,6 +162,7 @@ private:
 
     bool useTraditionalDesktopBehaviour;
     bool m_navigatorQtObjectEnabled;
+    QUrl m_iconURL;
 };
 
 #endif // qquickwebview_p_p_h
diff --git a/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider.cpp b/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider.cpp
new file mode 100644 (file)
index 0000000..f63c38e
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+    Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "qwebiconimageprovider_p.h"
+
+#include "QtWebContext.h"
+#include "QtWebIconDatabaseClient.h"
+#include <QtCore/QUrl>
+#include <QtGui/QImage>
+#include <wtf/text/WTFString.h>
+
+using namespace WebKit;
+
+QWebIconImageProvider::QWebIconImageProvider()
+    : QDeclarativeImageProvider(QDeclarativeImageProvider::Image)
+{
+}
+
+QWebIconImageProvider::~QWebIconImageProvider()
+{
+}
+
+QImage QWebIconImageProvider::requestImage(const QString& id, QSize* size, const QSize& requestedSize)
+{
+    RefPtr<QtWebContext> context = QtWebContext::defaultContext();
+    QtWebIconDatabaseClient* iconDatabase = context->iconDatabase();
+
+    QString encodedIconUrl = id;
+    encodedIconUrl.remove(0, encodedIconUrl.indexOf('#') + 1);
+    String pageURL = QUrl::fromPercentEncoding(encodedIconUrl.toUtf8());
+
+    QImage icon = requestedSize.isValid() ? iconDatabase->iconImageForPageURL(pageURL, requestedSize) : iconDatabase->iconImageForPageURL(pageURL);
+    ASSERT(!icon.isNull());
+
+    if (size)
+        *size = icon.size();
+
+    return icon;
+}
diff --git a/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h b/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h
new file mode 100644 (file)
index 0000000..8815d7b
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+    Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef qwebiconimageprovider_p_h
+#define qwebiconimageprovider_p_h
+
+#include "qwebkitglobal.h"
+#include <QtDeclarative/QDeclarativeImageProvider>
+
+class QWEBKIT_EXPORT QWebIconImageProvider : public QDeclarativeImageProvider {
+public:
+    QWebIconImageProvider();
+    ~QWebIconImageProvider();
+    QImage requestImage(const QString& id, QSize* size, const QSize& requestedSize);
+};
+
+#endif
index 704285e..21f2191 100644 (file)
@@ -171,6 +171,7 @@ public:
 
     void setDatabaseDirectory(const String& dir) { m_overrideDatabaseDirectory = dir; }
     void setIconDatabasePath(const String&);
+    String iconDatabasePath() const;
     void setLocalStorageDirectory(const String& dir) { m_overrideLocalStorageDirectory = dir; }
 
     String overrideWebInspectorBaseDirectory() const { return m_overrideWebInspectorBaseDirectory; }
@@ -236,7 +237,6 @@ private:
     String databaseDirectory() const;
     String platformDefaultDatabaseDirectory() const;
 
-    String iconDatabasePath() const;
     String platformDefaultIconDatabasePath() const;
 
     String localStorageDirectory() const;
index 8427ca3..8016cfb 100644 (file)
@@ -133,9 +133,14 @@ void WebIconDatabase::synchronousIconDataForPageURL(const String&, CoreIPC::Data
     iconData = CoreIPC::DataReference();
 }
 
-void WebIconDatabase::synchronousIconURLForPageURL(const String&, String& iconURL)
+void WebIconDatabase::synchronousIconURLForPageURL(const String& pageURL, String& iconURL)
 {
-    iconURL = String();
+    if (!m_iconDatabaseImpl) {
+        iconURL = String();
+        return;
+    }
+
+    iconURL = m_iconDatabaseImpl->synchronousIconURLForPageURL(pageURL);
 }
 
 void WebIconDatabase::synchronousIconDataKnownForIconURL(const String&, bool& iconDataKnown) const
@@ -175,14 +180,14 @@ void WebIconDatabase::getLoadDecisionForIconURL(const String& iconURL, uint64_t
     m_webContext->sendToAllProcesses(Messages::WebIconDatabaseProxy::ReceivedIconLoadDecision((int)decision, callbackID));
 }
 
-Image* WebIconDatabase::imageForPageURL(const String& pageURL)
+Image* WebIconDatabase::imageForPageURL(const String& pageURL, const WebCore::IntSize& iconSize)
 {
     if (!m_webContext || !m_iconDatabaseImpl || !m_iconDatabaseImpl->isOpen() || pageURL.isEmpty())
         return 0;    
 
     // The WebCore IconDatabase ignores the passed in size parameter.
     // If that changes we'll need to rethink how this API is exposed.
-    return m_iconDatabaseImpl->synchronousIconForPageURL(pageURL, WebCore::IntSize(32, 32));
+    return m_iconDatabaseImpl->synchronousIconForPageURL(pageURL, iconSize);
 }
 
 void WebIconDatabase::removeAllIcons()
index 0c243ef..b74c210 100644 (file)
@@ -31,6 +31,7 @@
 #include "Connection.h"
 #include "WebIconDatabaseClient.h"
 #include <WebCore/IconDatabaseClient.h>
+#include <WebCore/IntSize.h>
 #include <wtf/Forward.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefPtr.h>
@@ -76,7 +77,7 @@ public:
     
     void getLoadDecisionForIconURL(const String&, uint64_t callbackID);
 
-    WebCore::Image* imageForPageURL(const String&);
+    WebCore::Image* imageForPageURL(const String&, const WebCore::IntSize& iconSize = WebCore::IntSize(32, 32));
     
     void removeAllIcons();
     void checkIntegrityBeforeOpening();
index a1ff1d2..bc32668 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "MutableArray.h"
 #include "QtDownloadManager.h"
+#include "QtWebIconDatabaseClient.h"
 #include "WKAPICast.h"
 #include "WebContext.h"
 #include "WebPageProxy.h"
@@ -93,6 +94,7 @@ void QtWebContext::postMessageToNavigatorQtObject(WebPageProxy* webPageProxy, co
 void QtWebContext::initialize()
 {
     m_downloadManager = adoptPtr(new QtDownloadManager(m_context.get()));
+    m_iconDatabase = adoptPtr(new QtWebIconDatabaseClient(m_context.get()));
     initializeContextInjectedBundleClient();
 }
 
index 97ce26d..eab3d7c 100644 (file)
@@ -35,6 +35,7 @@ namespace WebKit {
 
 class PageClient;
 class QtDownloadManager;
+class QtWebIconDatabaseClient;
 class WebContext;
 class WebPageGroup;
 class WebPageProxy;
@@ -49,6 +50,7 @@ public:
     PassRefPtr<WebPageProxy> createWebPage(PageClient*, WebPageGroup*);
 
     QtDownloadManager* downloadManager() { return m_downloadManager.get(); }
+    QtWebIconDatabaseClient* iconDatabase() { return m_iconDatabase.get(); }
 
     void setNavigatorQtObjectEnabled(WebPageProxy*, bool);
     void postMessageToNavigatorQtObject(WebPageProxy*, const QString&);
@@ -66,6 +68,7 @@ private:
 
     RefPtr<WebContext> m_context;
     OwnPtr<QtDownloadManager> m_downloadManager;
+    OwnPtr<QtWebIconDatabaseClient> m_iconDatabase;
 };
 
 }
diff --git a/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp b/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp
new file mode 100644 (file)
index 0000000..171e971
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+    Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "QtWebIconDatabaseClient.h"
+
+#include "Image.h"
+#include "KURL.h"
+#include "SharedBuffer.h"
+#include "WKURLQt.h"
+#include "WebContext.h"
+#include "WebIconDatabase.h"
+#include <QtCore/QHash>
+#include <QtCore/QObject>
+#include <QtCore/QUrl>
+#include <QtGui/QImage>
+
+using namespace WebKit;
+
+static inline QtWebIconDatabaseClient* toQtWebIconDatabaseClient(const void* clientInfo)
+{
+    ASSERT(clientInfo);
+    return reinterpret_cast<QtWebIconDatabaseClient*>(const_cast<void*>(clientInfo));
+}
+
+QtWebIconDatabaseClient::QtWebIconDatabaseClient(WebContext* context)
+{
+    // The setter calls the getter here as it triggers the startup of the icon database.
+    context->setIconDatabasePath(context->iconDatabasePath());
+    m_iconDatabase = context->iconDatabase();
+
+    WKIconDatabaseClient iconDatabaseClient;
+    memset(&iconDatabaseClient, 0, sizeof(WKIconDatabaseClient));
+    iconDatabaseClient.version = kWKIconDatabaseClientCurrentVersion;
+    iconDatabaseClient.clientInfo = this;
+    iconDatabaseClient.didChangeIconForPageURL = didChangeIconForPageURL;
+    WKIconDatabaseSetIconDatabaseClient(toAPI(m_iconDatabase), &iconDatabaseClient);
+}
+
+QtWebIconDatabaseClient::~QtWebIconDatabaseClient()
+{
+}
+
+void QtWebIconDatabaseClient::didChangeIconForPageURL(WKIconDatabaseRef iconDatabase, WKURLRef pageURL, const void* clientInfo)
+{
+    QUrl qUrl = WKURLCopyQUrl(pageURL);
+    toQtWebIconDatabaseClient(clientInfo)->requestIconForPageURL(qUrl);
+}
+
+QImage QtWebIconDatabaseClient::iconImageForPageURL(const String& pageURL, const QSize& iconSize)
+{
+    MutexLocker locker(m_imageLock);
+
+    WebCore::IntSize size(iconSize.width(), iconSize.height());
+    RefPtr<WebCore::Image> image = m_iconDatabase->imageForPageURL(pageURL, size);
+    if (!image)
+        return QImage();
+
+    QPixmap* nativeImage = image->nativeImageForCurrentFrame();
+    if (!nativeImage)
+        return QImage();
+
+    return nativeImage->toImage();
+}
+
+unsigned QtWebIconDatabaseClient::iconURLHashForPageURL(const String& pageURL)
+{
+    String iconURL;
+    m_iconDatabase->synchronousIconURLForPageURL(pageURL, iconURL);
+    return StringHash::hash(iconURL);
+}
+
+void QtWebIconDatabaseClient::requestIconForPageURL(const QUrl& pageURL)
+{
+    String pageURLString = WebCore::KURL(pageURL).string();
+    if (iconImageForPageURL(pageURLString).isNull())
+        return;
+
+    unsigned iconID = iconURLHashForPageURL(pageURLString);
+    QUrl url;
+    url.setScheme(QStringLiteral("image"));
+    url.setHost(QStringLiteral("webicon"));
+    url.setPath(QString::number(iconID).prepend('/'));
+    url.setEncodedFragment(pageURL.toEncoded());
+    emit iconChangedForPageURL(pageURL, url);
+}
+
+void QtWebIconDatabaseClient::retainIconForPageURL(const String& pageURL)
+{
+    m_iconDatabase->retainIconForPageURL(pageURL);
+}
+
+void QtWebIconDatabaseClient::releaseIconForPageURL(const String& pageURL)
+{
+    m_iconDatabase->releaseIconForPageURL(pageURL);
+}
+
+#include "moc_QtWebIconDatabaseClient.cpp"
diff --git a/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.h b/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.h
new file mode 100644 (file)
index 0000000..2cd0a90
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+    Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+
+#ifndef QtWebIconDatabaseClient_h
+#define QtWebIconDatabaseClient_h
+
+#include "WKIconDatabase.h"
+#include "qwebkitglobal.h"
+#include <QtCore/QObject>
+#include <QtCore/QSize>
+#include <wtf/Threading.h>
+#include <wtf/text/WTFString.h>
+
+QT_BEGIN_NAMESPACE
+class QImage;
+class QUrl;
+QT_END_NAMESPACE
+
+namespace WebKit {
+class WebContext;
+class WebIconDatabase;
+
+class QtWebIconDatabaseClient : public QObject {
+    Q_OBJECT
+
+public:
+    QtWebIconDatabaseClient(WebKit::WebContext*);
+    ~QtWebIconDatabaseClient();
+
+    QImage iconImageForPageURL(const String& pageURL, const QSize& iconSize = QSize(32, 32));
+    void retainIconForPageURL(const String&);
+    void releaseIconForPageURL(const String&);
+
+public Q_SLOTS:
+    void requestIconForPageURL(const QUrl&);
+
+public:
+    Q_SIGNAL void iconChangedForPageURL(const QUrl& pageURL, const QUrl& iconURL);
+
+private:
+    unsigned iconURLHashForPageURL(const String&);
+    static void didChangeIconForPageURL(WKIconDatabaseRef, WKURLRef pageURL, const void* clientInfo);
+    WebKit::WebIconDatabase* m_iconDatabase;
+    Mutex m_imageLock;
+};
+
+}
+
+#endif
index 77fb9b5..3ba8c74 100644 (file)
@@ -169,7 +169,9 @@ void QtWebPageLoadClient::didReceiveTitleForFrame(WKPageRef, WKStringRef title,
 
 void QtWebPageLoadClient::didStartProgress(WKPageRef, const void* clientInfo)
 {
-    toQtWebPageLoadClient(clientInfo)->setLoadProgress(0);
+    QtWebPageLoadClient* client = toQtWebPageLoadClient(clientInfo);
+    client->setLoadProgress(0);
+    client->m_webView->d_func()->setIcon(QUrl());
 }
 
 void QtWebPageLoadClient::didChangeProgress(WKPageRef page, const void* clientInfo)
index 83205c8..4958c85 100644 (file)
@@ -109,6 +109,12 @@ qwk_1.0 {
         *QQuickWebViewPrivate;
         non-virtual?thunk?to?QQuickWebViewPrivate*;
         QQuickWebViewPrivate::*;
+        *QWebIconImageProvider;
+        non-virtual?thunk?to?QWebIconImageProvider*;
+        QWebIconImageProvider::*;
+        *QtWebIconDatabaseClient;
+        non-virtual?thunk?to?QtWebIconDatabaseClient*;
+        QtWebIconDatabaseClient::*;
         *QQuickWebViewPrivateExtension;
         non-virtual?thunk?to?QQuickWebViewPrivateExtension*;
         QQuickWebViewPrivateExtension::*;
index 277951d..c4cae4c 100644 (file)
@@ -1,3 +1,17 @@
+2011-12-20  Rafael Brandao  <rafael.lobo@openbossa.org>
+
+        [Qt][WK2] Implement favicon support
+        https://bugs.webkit.org/show_bug.cgi?id=71082
+
+        Reviewed by Simon Hausmann.
+
+        A favorite icon was added on MiniBrowser's url bar as example.
+        We display a default icon when the page doesn't have an icon ready.
+
+        * MiniBrowser/qt/MiniBrowser.qrc:
+        * MiniBrowser/qt/icons/favicon.png: Added.
+        * MiniBrowser/qt/qml/BrowserWindow.qml:
+
 2011-12-19  Sam Weinig  <sam@webkit.org>
 
         Add support for scrollLineDown: and scrollLineUp: NSResponder selectors
index 266683d..710a6cd 100644 (file)
@@ -11,5 +11,6 @@
         <file>qml/MockTouchPoint.qml</file>
         <file>qml/ViewportInfoItem.qml</file>
         <file>useragentlist.txt</file>
+        <file>icons/favicon.png</file>
     </qresource>
 </RCC>
diff --git a/Tools/MiniBrowser/qt/icons/favicon.png b/Tools/MiniBrowser/qt/icons/favicon.png
new file mode 100644 (file)
index 0000000..4462752
Binary files /dev/null and b/Tools/MiniBrowser/qt/icons/favicon.png differ
index 82d10b2..c35e335 100644 (file)
@@ -205,6 +205,17 @@ Rectangle {
                 opacity: 0.3
                 visible: webView.loadProgress != 100
             }
+            Image {
+                id: favIcon
+                source: webView.icon != '' ? webView.icon : '../icons/favicon.png'
+                width: 16
+                height: 16
+                anchors {
+                    left: parent.left
+                    leftMargin: 4
+                    verticalCenter: parent.verticalCenter
+                }
+            }
             TextInput {
                 id: addressLine
                 clip: true
@@ -215,7 +226,7 @@ Rectangle {
                 }
                 anchors {
                     verticalCenter: parent.verticalCenter
-                    left: parent.left
+                    left: favIcon.right
                     right: parent.right
                     margins: 6
                 }