Title: [129994] trunk/Source/WebKit2
Revision
129994
Author
ma...@webkit.org
Date
2012-09-30 11:38:48 -0700 (Sun, 30 Sep 2012)

Log Message

[WK2][GTK] Add API to get the favicon for a WebKitWebView
https://bugs.webkit.org/show_bug.cgi?id=96477

Reviewed by Carlos Garcia Campos.

Provide a new simple API to synchronously try to get the favicon
associated with a WebView, if any, and to keep track of changes on
it, through a new GObject property.

* UIProcess/API/gtk/WebKitWebView.cpp:
(_WebKitWebViewPrivate):
(webkitWebViewIconReadyCallback): Callback to handle the
'icon-ready' signal coming from WebKitFaviconDatabase.
(webkitWebViewWatchForChangesInFavicon): Connects to the
'icon-ready' signal from WebKitFaviconDatabase, to keep track of
changes in favicons, that must be related to the current view.
(webkitWebViewDisconnectFaviconDatabaseSignalHandlers):
Disconnects the handler for 'icon-ready' if needed.
(webkitWebViewGetProperty): Updated for the new "favicon" property .
(webkitWebViewFinalize): Disconnect the new signal handler.
(webkit_web_view_class_init): Definition of the new property.
(webkitWebViewEmitLoadChanged): Make sure we will be watching for
changes in the favicon from WEBKIT_LOAD_STARTED on.
(webkit_web_view_get_favicon): New API funtcion, returning the
current favicon for the WebView, if any, or NULL otherwise.
* UIProcess/API/gtk/WebKitWebView.h:

Internally expose a way to try to get the favicon associated to a
page URL synchronously, through WebKitFaviconDatabase.

* UIProcess/API/gtk/WebKitFaviconDatabase.cpp:
(webkitFaviconDatabaseGetFaviconSync): New internal function, it
will return either 0 or a valid pointer to a cairo_surface_t.
* UIProcess/API/gtk/WebKitFaviconDatabasePrivate.h:

Add unit tests for checking this new API.

* UIProcess/API/gtk/tests/TestWebKitFaviconDatabase.cpp:
(testWebViewFavicon): New unit test.
(beforeAll): Add the test to the test suite.

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (129993 => 129994)


--- trunk/Source/WebKit2/ChangeLog	2012-09-30 16:28:36 UTC (rev 129993)
+++ trunk/Source/WebKit2/ChangeLog	2012-09-30 18:38:48 UTC (rev 129994)
@@ -1,5 +1,48 @@
 2012-09-30  Mario Sanchez Prada  <msanc...@igalia.com>
 
+        [WK2][GTK] Add API to get the favicon for a WebKitWebView
+        https://bugs.webkit.org/show_bug.cgi?id=96477
+
+        Reviewed by Carlos Garcia Campos.
+
+        Provide a new simple API to synchronously try to get the favicon
+        associated with a WebView, if any, and to keep track of changes on
+        it, through a new GObject property.
+
+        * UIProcess/API/gtk/WebKitWebView.cpp:
+        (_WebKitWebViewPrivate):
+        (webkitWebViewIconReadyCallback): Callback to handle the
+        'icon-ready' signal coming from WebKitFaviconDatabase.
+        (webkitWebViewWatchForChangesInFavicon): Connects to the
+        'icon-ready' signal from WebKitFaviconDatabase, to keep track of
+        changes in favicons, that must be related to the current view.
+        (webkitWebViewDisconnectFaviconDatabaseSignalHandlers):
+        Disconnects the handler for 'icon-ready' if needed.
+        (webkitWebViewGetProperty): Updated for the new "favicon" property .
+        (webkitWebViewFinalize): Disconnect the new signal handler.
+        (webkit_web_view_class_init): Definition of the new property.
+        (webkitWebViewEmitLoadChanged): Make sure we will be watching for
+        changes in the favicon from WEBKIT_LOAD_STARTED on.
+        (webkit_web_view_get_favicon): New API funtcion, returning the
+        current favicon for the WebView, if any, or NULL otherwise.
+        * UIProcess/API/gtk/WebKitWebView.h:
+
+        Internally expose a way to try to get the favicon associated to a
+        page URL synchronously, through WebKitFaviconDatabase.
+
+        * UIProcess/API/gtk/WebKitFaviconDatabase.cpp:
+        (webkitFaviconDatabaseGetFaviconSync): New internal function, it
+        will return either 0 or a valid pointer to a cairo_surface_t.
+        * UIProcess/API/gtk/WebKitFaviconDatabasePrivate.h:
+
+        Add unit tests for checking this new API.
+
+        * UIProcess/API/gtk/tests/TestWebKitFaviconDatabase.cpp:
+        (testWebViewFavicon): New unit test.
+        (beforeAll): Add the test to the test suite.
+
+2012-09-30  Mario Sanchez Prada  <msanc...@igalia.com>
+
         [WK2][GTK] Fix issues with WebKitFaviconDatabase in debug builds
         https://bugs.webkit.org/show_bug.cgi?id=97966
 

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitFaviconDatabase.cpp (129993 => 129994)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitFaviconDatabase.cpp	2012-09-30 16:28:36 UTC (rev 129993)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitFaviconDatabase.cpp	2012-09-30 18:38:48 UTC (rev 129994)
@@ -183,6 +183,18 @@
     return faviconDatabase;
 }
 
+cairo_surface_t* webkitFaviconDatabaseGetFavicon(WebKitFaviconDatabase* database, const CString& pageURL)
+{
+    ASSERT(WEBKIT_IS_FAVICON_DATABASE(database));
+    ASSERT(!pageURL.isNull());
+
+    cairo_surface_t* iconSurface = getIconSurfaceSynchronously(database, String::fromUTF8(pageURL.data()));
+    if (!iconSurface)
+        return 0;
+
+    return cairo_surface_reference(iconSurface);
+}
+
 static PendingIconRequestVector* getOrCreatePendingIconRequests(WebKitFaviconDatabase* database, const String& pageURL)
 {
     PendingIconRequestVector* icons = database->priv->pendingIconRequests.get(pageURL);

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitFaviconDatabasePrivate.h (129993 => 129994)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitFaviconDatabasePrivate.h	2012-09-30 16:28:36 UTC (rev 129993)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitFaviconDatabasePrivate.h	2012-09-30 18:38:48 UTC (rev 129994)
@@ -22,9 +22,11 @@
 
 #include "WebIconDatabase.h"
 #include "WebKitFaviconDatabase.h"
+#include <wtf/text/CString.h>
 
 using namespace WebKit;
 
 WebKitFaviconDatabase* webkitFaviconDatabaseCreate(WebIconDatabase*);
+cairo_surface_t* webkitFaviconDatabaseGetFavicon(WebKitFaviconDatabase*, const CString&);
 
 #endif // WebKitFaviconDatabasePrivate_h

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp (129993 => 129994)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp	2012-09-30 16:28:36 UTC (rev 129993)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp	2012-09-30 18:38:48 UTC (rev 129994)
@@ -30,6 +30,7 @@
 #include "WebKitContextMenuPrivate.h"
 #include "WebKitEnumTypes.h"
 #include "WebKitError.h"
+#include "WebKitFaviconDatabasePrivate.h"
 #include "WebKitFormClient.h"
 #include "WebKitFullscreenClient.h"
 #include "WebKitHitTestResultPrivate.h"
@@ -102,6 +103,7 @@
     PROP_WEB_CONTEXT,
     PROP_TITLE,
     PROP_ESTIMATED_LOAD_PROGRESS,
+    PROP_FAVICON,
     PROP_URI,
     PROP_ZOOM_LEVEL,
     PROP_IS_LOADING
@@ -120,6 +122,7 @@
 
     bool waitingForMainResource;
     gulong mainResourceResponseHandlerID;
+    gulong watchForChangesInFaviconHandlerID;
     WebKitLoadEvent lastDelayedEvent;
 
     GRefPtr<WebKitBackForwardList> backForwardList;
@@ -260,6 +263,15 @@
     getPage(webView)->setCustomUserAgent(String::fromUTF8(webkit_settings_get_user_agent(settings)));
 }
 
+static void iconReadyCallback(WebKitFaviconDatabase *database, const char *uri, WebKitWebView *webView)
+{
+    // Consider only the icon matching the active URI for this webview.
+    if (webView->priv->activeURI != uri)
+        return;
+
+    g_object_notify(G_OBJECT(webView), "favicon");
+}
+
 static void webkitWebViewSetSettings(WebKitWebView* webView, WebKitSettings* settings)
 {
     webView->priv->settings = settings;
@@ -285,6 +297,29 @@
     priv->mainResourceResponseHandlerID = 0;
 }
 
+static void webkitWebViewWatchForChangesInFavicon(WebKitWebView* webView)
+{
+    WebKitWebViewPrivate* priv = webView->priv;
+    WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context);
+
+    // Make sure we only connect to this signal once per view.
+    if (priv->watchForChangesInFaviconHandlerID)
+        return;
+
+    priv->watchForChangesInFaviconHandlerID =
+        g_signal_connect(database, "favicon-ready", G_CALLBACK(iconReadyCallback), webView);
+}
+
+static void webkitWebViewDisconnectFaviconDatabaseSignalHandlers(WebKitWebView* webView)
+{
+    WebKitWebViewPrivate* priv = webView->priv;
+    WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context);
+
+    if (priv->watchForChangesInFaviconHandlerID)
+        g_signal_handler_disconnect(database, priv->watchForChangesInFaviconHandlerID);
+    priv->watchForChangesInFaviconHandlerID = 0;
+}
+
 static void fileChooserDialogResponseCallback(GtkDialog* dialog, gint responseID, WebKitFileChooserRequest* request)
 {
     GRefPtr<WebKitFileChooserRequest> adoptedRequest = adoptGRef(request);
@@ -385,6 +420,9 @@
     case PROP_ESTIMATED_LOAD_PROGRESS:
         g_value_set_double(value, webkit_web_view_get_estimated_load_progress(webView));
         break;
+    case PROP_FAVICON:
+        g_value_set_pointer(value, webkit_web_view_get_favicon(webView));
+        break;
     case PROP_URI:
         g_value_set_string(value, webkit_web_view_get_uri(webView));
         break;
@@ -413,6 +451,7 @@
 
     webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(webView);
     webkitWebViewDisconnectSettingsSignalHandlers(webView);
+    webkitWebViewDisconnectFaviconDatabaseSignalHandlers(webView);
 
     priv->~WebKitWebViewPrivate();
     G_OBJECT_CLASS(webkit_web_view_parent_class)->finalize(object);
@@ -500,6 +539,18 @@
                                                         0.0, 1.0, 0.0,
                                                         WEBKIT_PARAM_READABLE));
     /**
+     * WebKitWebView:favicon:
+     *
+     * The favicon currently associated to the #WebKitWebView.
+     * See webkit_web_view_get_favicon() for more details.
+     */
+    g_object_class_install_property(gObjectClass,
+                                    PROP_FAVICON,
+                                    g_param_spec_pointer("favicon",
+                                                         _("Favicon"),
+                                                         _("The favicon associated to the view, if any"),
+                                                         WEBKIT_PARAM_READABLE));
+    /**
      * WebKitWebView:uri:
      *
      * The current active URI of the #WebKitWebView.
@@ -1158,9 +1209,10 @@
 
 static void webkitWebViewEmitLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent)
 {
-    if (loadEvent == WEBKIT_LOAD_STARTED)
+    if (loadEvent == WEBKIT_LOAD_STARTED) {
         webkitWebViewSetIsLoading(webView, true);
-    else if (loadEvent == WEBKIT_LOAD_FINISHED) {
+        webkitWebViewWatchForChangesInFavicon(webView);
+    } else if (loadEvent == WEBKIT_LOAD_FINISHED) {
         webkitWebViewSetIsLoading(webView, false);
         webView->priv->waitingForMainResource = false;
         webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(webView);
@@ -1850,6 +1902,27 @@
 }
 
 /**
+ * webkit_web_view_get_favicon:
+ * @web_view: a #WebKitWebView
+ *
+ * Returns favicon currently associated to @web_view, if any. You can
+ * connect to notify::favicon signal of @web_view to be notified when
+ * the favicon is available.
+ *
+ * Returns: (transfer full): a pointer to a #cairo_surface_t with the
+ *    favicon or %NULL if there's no icon associated with @web_view.
+ */
+cairo_surface_t* webkit_web_view_get_favicon(WebKitWebView* webView)
+{
+    g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
+    if (webView->priv->activeURI.isNull())
+        return 0;
+
+    WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(webView->priv->context);
+    return webkitFaviconDatabaseGetFavicon(database, webView->priv->activeURI);
+}
+
+/**
  * webkit_web_view_get_custom_charset:
  * @web_view: a #WebKitWebView
  *

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h (129993 => 129994)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h	2012-09-30 16:28:36 UTC (rev 129993)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h	2012-09-30 18:38:48 UTC (rev 129994)
@@ -262,6 +262,9 @@
 WEBKIT_API const gchar *
 webkit_web_view_get_uri                            (WebKitWebView             *web_view);
 
+WEBKIT_API cairo_surface_t *
+webkit_web_view_get_favicon                        (WebKitWebView             *web_view);
+
 WEBKIT_API const gchar *
 webkit_web_view_get_custom_charset                 (WebKitWebView             *web_view);
 

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt (129993 => 129994)


--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt	2012-09-30 16:28:36 UTC (rev 129993)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt	2012-09-30 18:38:48 UTC (rev 129994)
@@ -101,6 +101,7 @@
 webkit_web_view_get_back_forward_list
 webkit_web_view_go_to_back_forward_list_item
 webkit_web_view_get_uri
+webkit_web_view_get_favicon
 webkit_web_view_set_settings
 webkit_web_view_get_settings
 webkit_web_view_get_window_properties

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitFaviconDatabase.cpp (129993 => 129994)


--- trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitFaviconDatabase.cpp	2012-09-30 16:28:36 UTC (rev 129993)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitFaviconDatabase.cpp	2012-09-30 18:38:48 UTC (rev 129994)
@@ -37,6 +37,7 @@
         , m_favicon(0)
         , m_error(0)
         , m_iconReadySignalReceived(false)
+        , m_faviconNotificationReceived(false)
     {
     }
 
@@ -52,6 +53,13 @@
         test->m_iconReadySignalReceived = true;
     }
 
+    static void faviconChangedCallback(WebKitWebView* webView, GParamSpec* pspec, gpointer data)
+    {
+        FaviconDatabaseTest* test = static_cast<FaviconDatabaseTest*>(data);
+        g_assert(test->m_webView == webView);
+        test->m_faviconNotificationReceived = true;
+    }
+
     static void getFaviconCallback(GObject* sourceObject, GAsyncResult* result, void* data)
     {
         FaviconDatabaseTest* test = static_cast<FaviconDatabaseTest*>(data);
@@ -68,6 +76,7 @@
         webkit_favicon_database_get_favicon(database, kServer->getURIForPath("/").data(), 0, getFaviconCallback, this);
 
         g_signal_connect(database, "favicon-ready", G_CALLBACK(iconReadyCallback), this);
+        g_signal_connect(m_webView, "notify::favicon", G_CALLBACK(faviconChangedCallback), this);
 
         g_main_loop_run(m_mainLoop);
     }
@@ -83,6 +92,7 @@
     cairo_surface_t* m_favicon;
     GOwnPtr<GError> m_error;
     bool m_iconReadySignalReceived;
+    bool m_faviconNotificationReceived;
 };
 
 static void
@@ -167,6 +177,25 @@
     g_assert_cmpstr(iconURI.get(), ==, kServer->getURIForPath("/favicon.ico").data());
 }
 
+static void testWebViewFavicon(FaviconDatabaseTest* test, gconstpointer)
+{
+    cairo_surface_t* iconFromWebView = webkit_web_view_get_favicon(test->m_webView);
+    g_assert(!iconFromWebView);
+
+    test->loadURI(kServer->getURIForPath("/").data());
+    test->waitUntilLoadFinished();
+
+    test->m_faviconNotificationReceived = false;
+    test->askForIconAndWaitUntilReady();
+    g_assert(test->m_faviconNotificationReceived);
+
+    iconFromWebView = webkit_web_view_get_favicon(test->m_webView);
+    g_assert(iconFromWebView);
+    g_assert(cairo_image_surface_get_width(iconFromWebView) > 0);
+    g_assert(cairo_image_surface_get_height(iconFromWebView) > 0);
+    cairo_surface_destroy(iconFromWebView);
+}
+
 void beforeAll()
 {
     // Start a soup server for testing.
@@ -181,6 +210,7 @@
     FaviconDatabaseTest::add("WebKitFaviconDatabase", "get-favicon", testGetFavicon);
     FaviconDatabaseTest::add("WebKitFaviconDatabase", "get-favicon-uri", testGetFaviconURI);
     FaviconDatabaseTest::add("WebKitFaviconDatabase", "clear-database", testClearDatabase);
+    FaviconDatabaseTest::add("WebKitWebView", "favicon", testWebViewFavicon);
 }
 
 static void webkitFaviconDatabaseFinalizedCallback(gpointer, GObject*)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to