Bug 521495 - moz-icon:// protocol does not work with SVG icons. r=joe

--HG--
extra : rebase_source : 4db9f6f86c2a2811d2b21dc28a4ede4216f4e705
This commit is contained in:
Nils Maier 2010-07-15 10:14:11 +02:00
Родитель 93ff88f202
Коммит c464338f46
2 изменённых файлов: 114 добавлений и 15 удалений

Просмотреть файл

@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Nils Maier <MaierMan@web.de>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -73,8 +74,6 @@ typedef char* (*_GnomeIconLookup_fn)(GtkIconTheme *icon_theme, GnomeThumbnailFac
const char *file_uri, const char *custom_icon, GnomeVFSFileInfo *file_info,
const char *mime_type, GnomeIconLookupFlags flags, GnomeIconLookupResultFlags *result);
typedef GnomeIconTheme* (*_GnomeIconThemeNew_fn)(void);
typedef char* (*_GnomeIconThemeLookupIcon_fn)(GnomeIconTheme *theme, const char *icon_name, int size,
const GnomeIconData **icon_data, int *base_size);
typedef int (*_GnomeInit_fn)(const char *app_id, const char *app_version, int argc, char **argv, const struct poptOption *options,
int flags, poptContext *return_ctx);
typedef GnomeProgram* (*_GnomeProgramGet_fn)(void);
@ -88,7 +87,6 @@ static PRBool gTriedToLoadGnomeLibs = PR_FALSE;
static _GnomeIconLookup_fn _gnome_icon_lookup = nsnull;
static _GnomeIconThemeNew_fn _gnome_icon_theme_new = nsnull;
static _GnomeIconThemeLookupIcon_fn _gnome_icon_theme_lookup_icon = nsnull;
static _GnomeInit_fn _gnome_init = nsnull;
static _GnomeProgramGet_fn _gnome_program_get = nsnull;
static _GnomeVFSGetFileInfo_fn _gnome_vfs_get_file_info = nsnull;
@ -209,9 +207,8 @@ ensure_libgnomeui()
_gnome_init = (_GnomeInit_fn)PR_FindFunctionSymbol(gLibGnomeUI, "gnome_init_with_popt_table");
_gnome_icon_theme_new = (_GnomeIconThemeNew_fn)PR_FindFunctionSymbol(gLibGnomeUI, "gnome_icon_theme_new");
_gnome_icon_lookup = (_GnomeIconLookup_fn)PR_FindFunctionSymbol(gLibGnomeUI, "gnome_icon_lookup");
_gnome_icon_theme_lookup_icon = (_GnomeIconThemeLookupIcon_fn)PR_FindFunctionSymbol(gLibGnomeUI, "gnome_icon_theme_lookup_icon");
if (!_gnome_init || !_gnome_icon_theme_new || !_gnome_icon_lookup || !_gnome_icon_theme_lookup_icon) {
if (!_gnome_init || !_gnome_icon_theme_new || !_gnome_icon_lookup) {
PR_UnloadLibrary(gLibGnomeUI);
gLibGnomeUI = nsnull;
return NS_ERROR_NOT_AVAILABLE;
@ -298,6 +295,7 @@ moz_gtk_icon_size(const char *name)
nsresult
nsIconChannel::InitWithGnome(nsIMozIconURI *aIconURI)
{
#if GTK_CHECK_VERSION(2,4,0)
nsresult rv;
if (NS_FAILED(ensure_libgnomeui()) || NS_FAILED(ensure_libgnome()) || NS_FAILED(ensure_libgnomevfs())) {
@ -392,7 +390,6 @@ nsIconChannel::InitWithGnome(nsIMozIconURI *aIconURI)
ms->GetTypeFromExtension(fileExt, type);
}
}
// Get the icon theme
if (!gIconTheme) {
gIconTheme = _gnome_icon_theme_new();
@ -410,17 +407,19 @@ nsIconChannel::InitWithGnome(nsIMozIconURI *aIconURI)
_gnome_vfs_file_info_clear(&fileInfo);
if (!name)
return NS_ERROR_NOT_AVAILABLE;
// Get the default theme associated with the screen
// Do NOT free.
GtkIconTheme *theme = gtk_icon_theme_get_default();
if (!theme) {
g_free(name);
return NS_ERROR_UNEXPECTED;
}
char* file = _gnome_icon_theme_lookup_icon(gIconTheme, name, iconSize,
NULL, NULL);
g_free(name);
if (!file)
return NS_ERROR_NOT_AVAILABLE;
// Create a GdkPixbuf buffer and scale it
GError *err = nsnull;
GdkPixbuf* buf = gdk_pixbuf_new_from_file(file, &err);
g_free(file);
GdkPixbuf* buf = gtk_icon_theme_load_icon(theme, name, iconSize, (GtkIconLookupFlags)0, &err);
g_free(name);
if (!buf) {
if (err)
g_error_free(err);
@ -444,6 +443,9 @@ nsIconChannel::InitWithGnome(nsIMozIconURI *aIconURI)
getter_AddRefs(mRealChannel));
g_object_unref(scaled);
return rv;
#else // GTK_CHECK_VERSION(2,4,0)
return NS_ERROR_NOT_AVAILABLE;
#endif // GTK_CHECK_VERSION(2,4,0)
}
#endif

Просмотреть файл

@ -0,0 +1,97 @@
/**
* Basic tests for the moz-icon:// protocol
* Tests will try to load icons for a set of given extensions.
* Different icon sizes will be tested as well.
*
* Some systems use svg icons. Those svg icons are also
* expected to load just fine.
*
*
* Written by Nils Maier <MaierMan@web.de>
* Code is in the public domain; Copyrights are disclaimed
*/
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const Ctor = Components.Constructor;
const Exception = Components.Exception;
const URIDEFAULT = "moz-icon://file.%e";
const URISIZE = "moz-icon://file.%e?size=%s";
const IOService = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
// These file extensions should be tested
// All systems should provide some kind of icon
var extensions = [
'png', 'jpg', 'jpeg',
'pdf',
'mpg', 'avi', 'mov',
'zip', 'rar', 'tar.gz', 'tar.bz2',
];
// What sizes to test
var sizes = [
16,
24,
32,
48,
64
];
// Stream listener for the channels
function Listener() {}
Listener.prototype = {
_dataReceived: false,
QueryInterface: function(iid) {
if (iid.equals(Ci.nsIStreamListener)
|| iid.equals(Ci.nsIRequestObserver)
|| iid.equals(Ci.nsISupports)) {
return this;
}
throw Cr.NS_ERROR_NO_INTERFACE;
},
onStopRequest: function(aRequest, aContext, aStatusCode) {
// Usually newChannel will throw
// However, better be safe than sorry and check
// the channel actually returned data
do_check_true(!!this._dataReceived);
do_test_finished();
},
onStartRequest: function() {},
onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) {
this._dataReceived |= aInputStream.available() > 0;
aRequest.cancel(0x804B0002); // binding aborted
}
};
// test a single url for all extensions
function verifyChannelFor(aExt, aURI) {
var uri = aURI.replace(/%e/g, aExt);
try {
var channel = IOService.newChannel(uri, null, null);
channel.asyncOpen(new Listener(), null);
do_test_pending();
}
catch (ex) {
// If moz-icon: cannot "resolve" an icon then newChannel will throw.
do_throw("Cannot open channel for " + uri + " Error: " + ex);
}
}
// runs the test
function run_test() {
for each (let ext in extensions) {
verifyChannelFor(ext, URIDEFAULT);
for each (let size in sizes) {
verifyChannelFor(ext, URISIZE.replace(/%s/g, size));
}
}
};