Commit 15626016 authored by carlosgc@webkit.org's avatar carlosgc@webkit.org
Browse files

[GTK] WebKitWebView doesn't emit notify:favicon when it changes in some cases in WebKit2

https://bugs.webkit.org/show_bug.cgi?id=98153

Reviewed by Martin Robinson.

The main problem is that it relies on icon-ready signal to be
emitted by the favicon database, but that signal is only emitted
when the icon is loaded from the network or imported from the
database, but not when the icon is already in memory. The way to
detect if a web page doesn't have a favicon or it's unknown it's
also incorrectly done and the wrong error is returned for pages
not having a favicon.

* UIProcess/API/gtk/WebKitFaviconDatabase.cpp:
(GetFaviconSurfaceAsyncData): Add a GError field.
(getIconSurfaceSynchronously): Add a GError parameter and fill it
accordingly. Use imageForPageURL() instead of
nativeImageForPageURL() because the latter always returns NULL for
empty images, so it's not possible to know whether it's an empty
image or not. If the image is empty is because the web page is
known by the database and it doesn't have a favicon.
(processPendingIconsForURI): Pass the data error to
getIconSurfaceSynchronously(). Don't set the icon if the request
has been cancelled.
(webkitFaviconDatabaseGetFavicon): Pass NULL as error to
getIconSurfaceSynchronously().
(setErrorForAsyncResult): Fill also error for
WEBKIT_FAVICON_DATABASE_ERROR_FAVICON_UNKNOWN.
(webkit_favicon_database_get_favicon): If we get NULL as icon in
the first place, check the error code returned by
getIconSurfaceSynchronously() and return early if the page doesn't
have a favicon. Remove the cancelled signal to avoid race
conditions.
(webkit_favicon_database_get_favicon_finish): Errors are processed
before now, so simply propagate the error if any or return the
favicon.
* UIProcess/API/gtk/WebKitWebView.cpp:
(_WebKitWebViewPrivate): Keep a reference of the favicon.
(webkitWebViewCancelFaviconRequest): Cancel any async operation to
get the favicon.
(webkitWebViewUpdateFavicon): Check if favicon has changed and
save it emitting also notify::favicon signal.
(iconReadyCallback): Only update the favicon if we don't have one
already.
(webkitWebViewFinalize): Call webkitWebViewCancelFaviconRequest().
(getFaviconReadyCallback): Update the favicon.
(webkitWebViewRequestFavicon): Request a new favicon.
(webkitWebViewLoadChanged): Try to get the favicon when the load
has been committed and the URI is the final one.
(webkit_web_view_get_favicon): Return the cached favicon.
* UIProcess/API/gtk/tests/TestWebKitFaviconDatabase.cpp:
(serverCallback):
(testSetDirectory):
(testGetFavicon):
(testWebViewFavicon):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@130279 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent c7b06dfb
2012-10-03 Carlos Garcia Campos <cgarcia@igalia.com>
[GTK] WebKitWebView doesn't emit notify:favicon when it changes in some cases in WebKit2
https://bugs.webkit.org/show_bug.cgi?id=98153
Reviewed by Martin Robinson.
The main problem is that it relies on icon-ready signal to be
emitted by the favicon database, but that signal is only emitted
when the icon is loaded from the network or imported from the
database, but not when the icon is already in memory. The way to
detect if a web page doesn't have a favicon or it's unknown it's
also incorrectly done and the wrong error is returned for pages
not having a favicon.
* UIProcess/API/gtk/WebKitFaviconDatabase.cpp:
(GetFaviconSurfaceAsyncData): Add a GError field.
(getIconSurfaceSynchronously): Add a GError parameter and fill it
accordingly. Use imageForPageURL() instead of
nativeImageForPageURL() because the latter always returns NULL for
empty images, so it's not possible to know whether it's an empty
image or not. If the image is empty is because the web page is
known by the database and it doesn't have a favicon.
(processPendingIconsForURI): Pass the data error to
getIconSurfaceSynchronously(). Don't set the icon if the request
has been cancelled.
(webkitFaviconDatabaseGetFavicon): Pass NULL as error to
getIconSurfaceSynchronously().
(setErrorForAsyncResult): Fill also error for
WEBKIT_FAVICON_DATABASE_ERROR_FAVICON_UNKNOWN.
(webkit_favicon_database_get_favicon): If we get NULL as icon in
the first place, check the error code returned by
getIconSurfaceSynchronously() and return early if the page doesn't
have a favicon. Remove the cancelled signal to avoid race
conditions.
(webkit_favicon_database_get_favicon_finish): Errors are processed
before now, so simply propagate the error if any or return the
favicon.
* UIProcess/API/gtk/WebKitWebView.cpp:
(_WebKitWebViewPrivate): Keep a reference of the favicon.
(webkitWebViewCancelFaviconRequest): Cancel any async operation to
get the favicon.
(webkitWebViewUpdateFavicon): Check if favicon has changed and
save it emitting also notify::favicon signal.
(iconReadyCallback): Only update the favicon if we don't have one
already.
(webkitWebViewFinalize): Call webkitWebViewCancelFaviconRequest().
(getFaviconReadyCallback): Update the favicon.
(webkitWebViewRequestFavicon): Request a new favicon.
(webkitWebViewLoadChanged): Try to get the favicon when the load
has been committed and the URI is the final one.
(webkit_web_view_get_favicon): Return the cached favicon.
* UIProcess/API/gtk/tests/TestWebKitFaviconDatabase.cpp:
(serverCallback):
(testSetDirectory):
(testGetFavicon):
(testWebViewFavicon):
2012-10-02 Carlos Garcia Campos <cgarcia@igalia.com>
[GTK] Add API to get the web view that initiated a custom URI request to WebKit2 GTK+
......
......@@ -28,6 +28,7 @@
#include <WebCore/RefPtrCairo.h>
#include <glib/gi18n-lib.h>
#include <wtf/MainThread.h>
#include <wtf/gobject/GOwnPtr.h>
#include <wtf/gobject/GRefPtr.h>
#include <wtf/text/CString.h>
......@@ -109,28 +110,30 @@ struct GetFaviconSurfaceAsyncData {
GRefPtr<WebKitFaviconDatabase> faviconDatabase;
String pageURL;
RefPtr<cairo_surface_t> icon;
GOwnPtr<GError> error;
GRefPtr<GCancellable> cancellable;
unsigned long cancelledId;
~GetFaviconSurfaceAsyncData()
{
if (cancelledId)
g_cancellable_disconnect(cancellable.get(), cancelledId);
}
};
WEBKIT_DEFINE_ASYNC_DATA_STRUCT(GetFaviconSurfaceAsyncData)
static cairo_surface_t* getIconSurfaceSynchronously(WebKitFaviconDatabase* database, const String& pageURL)
static cairo_surface_t* getIconSurfaceSynchronously(WebKitFaviconDatabase* database, const String& pageURL, GError** error)
{
ASSERT(isMainThread());
// The exact size we pass is irrelevant to the iconDatabase code.
// We must pass something greater than 0x0 to get an icon.
WebCore::NativeImagePtr icon = database->priv->iconDatabase->nativeImageForPageURL(pageURL, WebCore::IntSize(1, 1));
if (!icon)
WebCore::Image* iconImage = database->priv->iconDatabase->imageForPageURL(pageURL, WebCore::IntSize(1, 1));
if (!iconImage) {
g_set_error(error, WEBKIT_FAVICON_DATABASE_ERROR, WEBKIT_FAVICON_DATABASE_ERROR_FAVICON_UNKNOWN, _("Unknown favicon for page %s"), pageURL.utf8().data());
return 0;
}
return icon ? icon->surface() : 0;
WebCore::NativeImagePtr icon = iconImage->nativeImageForCurrentFrame();
if (!icon) {
g_set_error(error, WEBKIT_FAVICON_DATABASE_ERROR, WEBKIT_FAVICON_DATABASE_ERROR_FAVICON_NOT_FOUND, _("Page %s does not have a favicon"), pageURL.utf8().data());
return 0;
}
return icon->surface();
}
static void deletePendingIconRequests(WebKitFaviconDatabase* database, PendingIconRequestVector* requests, const String& pageURL)
......@@ -148,7 +151,8 @@ static void processPendingIconsForURI(WebKitFaviconDatabase* database, const Str
for (size_t i = 0; i < icons->size(); ++i) {
GSimpleAsyncResult* result = icons->at(i).get();
GetFaviconSurfaceAsyncData* data = static_cast<GetFaviconSurfaceAsyncData*>(g_simple_async_result_get_op_res_gpointer(result));
data->icon = getIconSurfaceSynchronously(database, pageURL);
if (!g_cancellable_is_cancelled(data->cancellable.get()))
data->icon = getIconSurfaceSynchronously(database, pageURL, &data->error.outPtr());
g_simple_async_result_complete(result);
}
......@@ -188,7 +192,7 @@ cairo_surface_t* webkitFaviconDatabaseGetFavicon(WebKitFaviconDatabase* database
ASSERT(WEBKIT_IS_FAVICON_DATABASE(database));
ASSERT(!pageURL.isNull());
cairo_surface_t* iconSurface = getIconSurfaceSynchronously(database, String::fromUTF8(pageURL.data()));
cairo_surface_t* iconSurface = getIconSurfaceSynchronously(database, String::fromUTF8(pageURL.data()), 0);
if (!iconSurface)
return 0;
......@@ -206,34 +210,6 @@ static PendingIconRequestVector* getOrCreatePendingIconRequests(WebKitFaviconDat
return icons;
}
static void getIconSurfaceCancelled(void* userData)
{
GSimpleAsyncResult* result = static_cast<GSimpleAsyncResult*>(userData);
// Get the data we might need and complete the request.
GetFaviconSurfaceAsyncData* data = static_cast<GetFaviconSurfaceAsyncData*>(g_simple_async_result_get_op_res_gpointer(result));
WebKitFaviconDatabase* database = data->faviconDatabase.get();
String pageURL = data->pageURL;
g_simple_async_result_complete(result);
PendingIconRequestVector* icons = database->priv->pendingIconRequests.get(pageURL);
if (!icons)
return;
size_t itemIndex = icons->find(result);
if (itemIndex != notFound)
icons->remove(itemIndex);
if (icons->isEmpty())
deletePendingIconRequests(database, icons, pageURL);
}
static void getIconSurfaceCancelledCallback(GCancellable* cancellable, GSimpleAsyncResult* result)
{
// Handle cancelled in a in idle since it might be called from any thread.
callOnMainThread(getIconSurfaceCancelled, result);
}
static void setErrorForAsyncResult(GSimpleAsyncResult* result, WebKitFaviconDatabaseError error, const String& pageURL = String())
{
ASSERT(result);
......@@ -247,6 +223,10 @@ static void setErrorForAsyncResult(GSimpleAsyncResult* result, WebKitFaviconData
g_simple_async_result_set_error(result, WEBKIT_FAVICON_DATABASE_ERROR, error, _("Page %s does not have a favicon"), pageURL.utf8().data());
break;
case WEBKIT_FAVICON_DATABASE_ERROR_FAVICON_UNKNOWN:
g_simple_async_result_set_error(result, WEBKIT_FAVICON_DATABASE_ERROR, error, _("Unknown favicon for page %s"), pageURL.utf8().data());
break;
default:
ASSERT_NOT_REACHED();
}
......@@ -280,16 +260,13 @@ void webkit_favicon_database_get_favicon(WebKitFaviconDatabase* database, const
g_return_if_fail(pageURI);
GRefPtr<GSimpleAsyncResult> result = adoptGRef(g_simple_async_result_new(G_OBJECT(database), callback, userData, reinterpret_cast<gpointer>(webkit_favicon_database_get_favicon)));
g_simple_async_result_set_check_cancellable(result.get(), cancellable);
GetFaviconSurfaceAsyncData* data = createGetFaviconSurfaceAsyncData();
g_simple_async_result_set_op_res_gpointer(result.get(), data, reinterpret_cast<GDestroyNotify>(destroyGetFaviconSurfaceAsyncData));
data->faviconDatabase = database;
data->pageURL = String::fromUTF8(pageURI);
data->cancellable = cancellable;
if (cancellable) {
data->cancelledId =
g_cancellable_connect(cancellable, G_CALLBACK(getIconSurfaceCancelledCallback), result.get(), 0);
g_simple_async_result_set_check_cancellable(result.get(), cancellable);
}
WebKitFaviconDatabasePrivate* priv = database->priv;
WebIconDatabase* iconDatabaseImpl = priv->iconDatabase.get();
......@@ -307,7 +284,18 @@ void webkit_favicon_database_get_favicon(WebKitFaviconDatabase* database, const
// We ask for the icon directly. If we don't get the icon data now,
// we'll be notified later (even if the database is still importing icons).
data->icon = getIconSurfaceSynchronously(database, data->pageURL);
GOwnPtr<GError> error;
data->icon = getIconSurfaceSynchronously(database, data->pageURL, &error.outPtr());
if (data->icon) {
g_simple_async_result_complete_in_idle(result.get());
return;
}
if (g_error_matches(error.get(), WEBKIT_FAVICON_DATABASE_ERROR, WEBKIT_FAVICON_DATABASE_ERROR_FAVICON_NOT_FOUND)) {
g_simple_async_result_take_error(result.get(), error.release());
g_simple_async_result_complete_in_idle(result.get());
return;
}
// If there's not a valid icon, but there's an iconURL registered,
// or it's still not registered but the import process hasn't
......@@ -315,21 +303,14 @@ void webkit_favicon_database_get_favicon(WebKitFaviconDatabase* database, const
// called before making and informed decision.
String iconURLForPageURL;
iconDatabaseImpl->synchronousIconURLForPageURL(data->pageURL, iconURLForPageURL);
if (!data->icon && (!iconURLForPageURL.isEmpty() || !iconDatabaseImpl->isUrlImportCompleted())) {
if (!iconURLForPageURL.isEmpty() || !iconDatabaseImpl->isUrlImportCompleted()) {
PendingIconRequestVector* icons = getOrCreatePendingIconRequests(database, data->pageURL);
ASSERT(icons);
icons->append(result);
return;
}
// If we reached this point without a valid icon, which means that
// there's no iconURL registered for this pageURI and the
// urlImport process has already finished, or do have a valid icon
// but it's an empty image, that means there's no favicon.
if (!data->icon || !cairo_image_surface_get_data(data->icon.get()))
setErrorForAsyncResult(result.get(), WEBKIT_FAVICON_DATABASE_ERROR_FAVICON_NOT_FOUND, data->pageURL);
// Complete the asynchronous process;
setErrorForAsyncResult(result.get(), WEBKIT_FAVICON_DATABASE_ERROR_FAVICON_UNKNOWN, data->pageURL);
g_simple_async_result_complete_in_idle(result.get());
}
......@@ -354,28 +335,12 @@ cairo_surface_t* webkit_favicon_database_get_favicon_finish(WebKitFaviconDatabas
GetFaviconSurfaceAsyncData* data = static_cast<GetFaviconSurfaceAsyncData*>(g_simple_async_result_get_op_res_gpointer(simpleResult));
ASSERT(data);
if (data->icon)
return cairo_surface_reference(data->icon.get());
// If the icon is not available at this stage, investigate why
// and come up with a descriptive, and hopefully helpful, error.
String iconURLForPageURL;
database->priv->iconDatabase->synchronousIconURLForPageURL(data->pageURL, iconURLForPageURL);
if (iconURLForPageURL.isEmpty()) {
// If there's no icon URL in the database at this point, we can
// conclude there's no favicon at all for the requested page URL.
g_set_error(error, WEBKIT_FAVICON_DATABASE_ERROR, WEBKIT_FAVICON_DATABASE_ERROR_FAVICON_NOT_FOUND,
_("Page %s does not have a favicon"), data->pageURL.utf8().data());
} else {
// If the icon URL is known it obviously means that the icon data
// hasn't been retrieved yet, so report that it's 'unknown'.
g_set_error(error, WEBKIT_FAVICON_DATABASE_ERROR, WEBKIT_FAVICON_DATABASE_ERROR_FAVICON_UNKNOWN,
_("Unknown favicon for page %s"), data->pageURL.utf8().data());
if (data->error) {
g_propagate_error(error, data->error.release());
return 0;
}
return 0;
return cairo_surface_reference(data->icon.get());
}
/**
......
......@@ -57,6 +57,7 @@
#include <WebCore/DragIcon.h>
#include <WebCore/GOwnPtrGtk.h>
#include <WebCore/GtkUtilities.h>
#include <WebCore/RefPtrCairo.h>
#include <glib/gi18n-lib.h>
#include <wtf/gobject/GOwnPtr.h>
#include <wtf/gobject/GRefPtr.h>
......@@ -142,6 +143,9 @@ struct _WebKitWebViewPrivate {
ResourcesMap subresourcesMap;
GRefPtr<WebKitWebInspector> inspector;
RefPtr<cairo_surface_t> favicon;
GRefPtr<GCancellable> faviconCancellable;
};
static guint signals[LAST_SIGNAL] = { 0, };
......@@ -263,13 +267,35 @@ static void userAgentChanged(WebKitSettings* settings, GParamSpec*, WebKitWebVie
getPage(webView)->setCustomUserAgent(String::fromUTF8(webkit_settings_get_user_agent(settings)));
}
static void iconReadyCallback(WebKitFaviconDatabase *database, const char *uri, WebKitWebView *webView)
static void webkitWebViewCancelFaviconRequest(WebKitWebView* webView)
{
if (!webView->priv->faviconCancellable)
return;
g_cancellable_cancel(webView->priv->faviconCancellable.get());
webView->priv->faviconCancellable = 0;
}
static void webkitWebViewUpdateFavicon(WebKitWebView* webView, cairo_surface_t* favicon)
{
if (webView->priv->favicon.get() == favicon)
return;
webView->priv->favicon = favicon;
g_object_notify(G_OBJECT(webView), "favicon");
}
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");
// Update the favicon only if we don't have one already.
if (!webView->priv->favicon) {
RefPtr<cairo_surface_t> favicon = adoptRef(webkitFaviconDatabaseGetFavicon(database, webView->priv->activeURI));
webkitWebViewUpdateFavicon(webView, favicon.get());
}
}
static void webkitWebViewSetSettings(WebKitWebView* webView, WebKitSettings* settings)
......@@ -449,6 +475,7 @@ static void webkitWebViewFinalize(GObject* object)
if (priv->modalLoop && g_main_loop_is_running(priv->modalLoop.get()))
g_main_loop_quit(priv->modalLoop.get());
webkitWebViewCancelFaviconRequest(webView);
webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(webView);
webkitWebViewDisconnectSettingsSignalHandlers(webView);
webkitWebViewDisconnectFaviconDatabaseSignalHandlers(webView);
......@@ -1234,16 +1261,39 @@ static void webkitWebViewEmitDelayedLoadEvents(WebKitWebView* webView)
priv->waitingForMainResource = false;
}
static void getFaviconReadyCallback(GObject* object, GAsyncResult* result, gpointer userData)
{
GOwnPtr<GError> error;
RefPtr<cairo_surface_t> favicon = adoptRef(webkit_favicon_database_get_favicon_finish(WEBKIT_FAVICON_DATABASE(object), result, &error.outPtr()));
if (!g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
WebKitWebView* webView = WEBKIT_WEB_VIEW(userData);
webkitWebViewUpdateFavicon(webView, favicon.get());
webView->priv->faviconCancellable = 0;
}
}
static void webkitWebViewRequestFavicon(WebKitWebView* webView)
{
WebKitWebViewPrivate* priv = webView->priv;
WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context);
priv->faviconCancellable = adoptGRef(g_cancellable_new());
webkit_favicon_database_get_favicon(database, priv->activeURI.data(), priv->faviconCancellable.get(), getFaviconReadyCallback, webView);
}
void webkitWebViewLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent)
{
WebKitWebViewPrivate* priv = webView->priv;
if (loadEvent == WEBKIT_LOAD_STARTED) {
// Finish a possible previous load waiting for main resource.
webkitWebViewEmitDelayedLoadEvents(webView);
webkitWebViewCancelFaviconRequest(webView);
webView->priv->loadingResourcesMap.clear();
webView->priv->mainResource = 0;
webView->priv->waitingForMainResource = false;
} else if (loadEvent == WEBKIT_LOAD_COMMITTED) {
webkitWebViewRequestFavicon(webView);
webView->priv->subresourcesMap.clear();
if (!webView->priv->mainResource) {
// When a page is loaded from the history cache, the main resource load callbacks
......@@ -1909,7 +1959,7 @@ const gchar* webkit_web_view_get_uri(WebKitWebView* webView)
* 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
* Returns: (transfer none): 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)
......@@ -1918,8 +1968,7 @@ cairo_surface_t* webkit_web_view_get_favicon(WebKitWebView* webView)
if (webView->priv->activeURI.isNull())
return 0;
WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(webView->priv->context);
return webkitFaviconDatabaseGetFavicon(database, webView->priv->activeURI);
return webView->priv->favicon.get();
}
/**
......
......@@ -39,10 +39,18 @@ public:
, m_iconReadySignalReceived(false)
, m_faviconNotificationReceived(false)
{
if (!g_str_equal(webkit_web_context_get_favicon_database_directory(m_webContext), kTempDirectory))
webkit_web_context_set_favicon_database_directory(m_webContext, kTempDirectory);
WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(m_webContext);
g_signal_connect(database, "favicon-ready", G_CALLBACK(iconReadyCallback), this);
}
~FaviconDatabaseTest()
{
if (m_favicon)
cairo_surface_destroy(m_favicon);
WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(m_webContext);
g_signal_handlers_disconnect_matched(database, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
}
......@@ -58,31 +66,32 @@ public:
FaviconDatabaseTest* test = static_cast<FaviconDatabaseTest*>(data);
g_assert(test->m_webView == webView);
test->m_faviconNotificationReceived = true;
test->quitMainLoop();
}
static void getFaviconCallback(GObject* sourceObject, GAsyncResult* result, void* data)
{
FaviconDatabaseTest* test = static_cast<FaviconDatabaseTest*>(data);
WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(test->m_webContext);
test->m_error.clear();
test->m_favicon = webkit_favicon_database_get_favicon_finish(database, result, &test->m_error.outPtr());
g_main_loop_quit(test->m_mainLoop);
test->quitMainLoop();
}
void askForIconAndWaitUntilReady()
void waitUntilFaviconChanged()
{
WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(m_webContext);
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);
m_faviconNotificationReceived = false;
unsigned long handlerID = g_signal_connect(m_webView, "notify::favicon", G_CALLBACK(faviconChangedCallback), this);
g_main_loop_run(m_mainLoop);
g_signal_handler_disconnect(m_webView, handlerID);
}
void askAndWaitForFavicon(const char* pageURI)
void getFaviconForPageURIAndWaitUntilReady(const char* pageURI)
{
m_error.clear();
if (m_favicon) {
cairo_surface_destroy(m_favicon);
m_favicon = 0;
}
WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(m_webContext);
webkit_favicon_database_get_favicon(database, pageURI, 0, getFaviconCallback, this);
g_main_loop_run(m_mainLoop);
......@@ -102,7 +111,6 @@ serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHash
soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED);
return;
}
soup_message_set_status(message, SOUP_STATUS_OK);
char* contents;
gsize length;
......@@ -118,13 +126,13 @@ serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHash
length = strlen(contents);
}
soup_message_set_status(message, SOUP_STATUS_OK);
soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, contents, length);
soup_message_body_complete(message->response_body);
}
static void testSetDirectory(FaviconDatabaseTest* test, gconstpointer)
{
webkit_web_context_set_favicon_database_directory(test->m_webContext, kTempDirectory);
g_assert_cmpstr(kTempDirectory, ==, webkit_web_context_get_favicon_database_directory(test->m_webContext));
}
......@@ -142,30 +150,29 @@ static void testGetFavicon(FaviconDatabaseTest* test, gconstpointer)
// We need to load the page first to ensure the icon data will be
// in the database in case there's an associated favicon.
test->loadURI(kServer->getURIForPath("/").data());
test->waitUntilLoadFinished();
// Check the WebKitFaviconDatabase::icon-ready signal.
test->m_iconReadySignalReceived = false;
test->askForIconAndWaitUntilReady();
test->waitUntilFaviconChanged();
g_assert(test->m_iconReadySignalReceived);
// Check the API retrieving a valid favicon.
test->askAndWaitForFavicon(kServer->getURIForPath("/").data());
test->m_iconReadySignalReceived = false;
test->getFaviconForPageURIAndWaitUntilReady(kServer->getURIForPath("/").data());
g_assert(test->m_favicon);
g_assert(!test->m_error);
g_assert(!test->m_iconReadySignalReceived);
// Check that width and height match those from blank.ico (16x16 favicon).
g_assert_cmpint(cairo_image_surface_get_width(test->m_favicon), ==, 16);
g_assert_cmpint(cairo_image_surface_get_height(test->m_favicon), ==, 16);
cairo_surface_destroy(test->m_favicon);
// Check the API retrieving an invalid favicon.
test->loadURI(kServer->getURIForPath("/nofavicon").data());
test->waitUntilLoadFinished();
test->waitUntilFaviconChanged();
g_assert(!test->m_iconReadySignalReceived);
test->askAndWaitForFavicon(kServer->getURIForPath("/nofavicon/").data());
test->getFaviconForPageURIAndWaitUntilReady(kServer->getURIForPath("/nofavicon/").data());
g_assert(!test->m_favicon);
g_assert(test->m_error && (test->m_error->code & WEBKIT_FAVICON_DATABASE_ERROR_FAVICON_NOT_FOUND));
g_assert(test->m_error);
g_assert(!test->m_iconReadySignalReceived);
}
static void testGetFaviconURI(FaviconDatabaseTest* test, gconstpointer)
......@@ -183,17 +190,13 @@ static void testWebViewFavicon(FaviconDatabaseTest* test, gconstpointer)
g_assert(!iconFromWebView);
test->loadURI(kServer->getURIForPath("/").data());
test->waitUntilLoadFinished();
test->m_faviconNotificationReceived = false;
test->askForIconAndWaitUntilReady();
test->waitUntilFaviconChanged();
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);
g_assert_cmpuint(cairo_image_surface_get_width(iconFromWebView), ==, 16);
g_assert_cmpuint(cairo_image_surface_get_height(iconFromWebView), ==, 16);
}
void beforeAll()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment