- 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*)