зеркало из https://github.com/mozilla/pjs.git
Bug 521495 - moz-icon:// protocol does not work with SVG icons. r=joe
--HG-- extra : rebase_source : 4db9f6f86c2a2811d2b21dc28a4ede4216f4e705
This commit is contained in:
Родитель
93ff88f202
Коммит
c464338f46
|
@ -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));
|
||||
}
|
||||
}
|
||||
};
|
Загрузка…
Ссылка в новой задаче