diff -r 000000000000 -r 6474c204b198 browser/components/tabview/favicons.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/browser/components/tabview/favicons.js Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,141 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +let FavIcons = { + // Pref that controls whether to display site icons. + PREF_CHROME_SITE_ICONS: "browser.chrome.site_icons", + + // Pref that controls whether to display fav icons. + PREF_CHROME_FAVICONS: "browser.chrome.favicons", + + // Lazy getter for pref browser.chrome.site_icons. + get _prefSiteIcons() { + delete this._prefSiteIcons; + this._prefSiteIcons = Services.prefs.getBoolPref(this.PREF_CHROME_SITE_ICONS); + }, + + // Lazy getter for pref browser.chrome.favicons. + get _prefFavicons() { + delete this._prefFavicons; + this._prefFavicons = Services.prefs.getBoolPref(this.PREF_CHROME_FAVICONS); + }, + + get defaultFavicon() this._favIconService.defaultFavicon.spec, + + init: function FavIcons_init() { + XPCOMUtils.defineLazyServiceGetter(this, "_favIconService", + "@mozilla.org/browser/favicon-service;1", "nsIFaviconService"); + + Services.prefs.addObserver(this.PREF_CHROME_SITE_ICONS, this, false); + Services.prefs.addObserver(this.PREF_CHROME_FAVICONS, this, false); + }, + + uninit: function FavIcons_uninit() { + Services.prefs.removeObserver(this.PREF_CHROME_SITE_ICONS, this); + Services.prefs.removeObserver(this.PREF_CHROME_FAVICONS, this); + }, + + observe: function FavIcons_observe(subject, topic, data) { + let value = Services.prefs.getBoolPref(data); + + if (data == this.PREF_CHROME_SITE_ICONS) + this._prefSiteIcons = value; + else if (data == this.PREF_CHROME_FAVICONS) + this._prefFavicons = value; + }, + + // ---------- + // Function: getFavIconUrlForTab + // Gets the "favicon link URI" for the given xul:tab, or null if unavailable. + getFavIconUrlForTab: function FavIcons_getFavIconUrlForTab(tab, callback) { + this._isImageDocument(tab, function (isImageDoc) { + if (isImageDoc) { + callback(tab.pinned ? tab.image : null); + } else { + this._getFavIconForNonImageDocument(tab, callback); + } + }.bind(this)); + }, + + // ---------- + // Function: _getFavIconForNonImageDocument + // Retrieves the favicon for a tab containing a non-image document. + _getFavIconForNonImageDocument: + function FavIcons_getFavIconForNonImageDocument(tab, callback) { + + if (tab.image) + this._getFavIconFromTabImage(tab, callback); + else if (this._shouldLoadFavIcon(tab)) + this._getFavIconForHttpDocument(tab, callback); + else + callback(null); + }, + + // ---------- + // Function: _getFavIconFromTabImage + // Retrieves the favicon for tab with a tab image. + _getFavIconFromTabImage: + function FavIcons_getFavIconFromTabImage(tab, callback) { + + let tabImage = gBrowser.getIcon(tab); + + // If the tab image's url starts with http(s), fetch icon from favicon + // service via the moz-anno protocol. + if (/^https?:/.test(tabImage)) { + let tabImageURI = gWindow.makeURI(tabImage); + tabImage = this._favIconService.getFaviconLinkForIcon(tabImageURI).spec; + } + + callback(tabImage); + }, + + // ---------- + // Function: _getFavIconForHttpDocument + // Retrieves the favicon for tab containg a http(s) document. + _getFavIconForHttpDocument: + function FavIcons_getFavIconForHttpDocument(tab, callback) { + + let {currentURI} = tab.linkedBrowser; + this._favIconService.getFaviconURLForPage(currentURI, function (uri) { + if (uri) { + callback(this._favIconService.getFaviconLinkForIcon(uri).spec); + } else { + callback(this.defaultFavicon); + } + }.bind(this)); + }, + + // ---------- + // Function: _isImageDocument + // Checks whether an image is loaded into the given tab. + _isImageDocument: function UI__isImageDocument(tab, callback) { + let mm = tab.linkedBrowser.messageManager; + let message = "Panorama:isImageDocument"; + + mm.addMessageListener(message, function onMessage(cx) { + mm.removeMessageListener(cx.name, onMessage); + callback(cx.json.isImageDocument); + }); + + mm.sendAsyncMessage(message); + }, + + // ---------- + // Function: _shouldLoadFavIcon + // Checks whether fav icon should be loaded for a given tab. + _shouldLoadFavIcon: function FavIcons_shouldLoadFavIcon(tab) { + // No need to load a favicon if the user doesn't want site or favicons. + if (!this._prefSiteIcons || !this._prefFavicons) + return false; + + let uri = tab.linkedBrowser.currentURI; + + // Stop here if we don't have a valid nsIURI. + if (!uri || !(uri instanceof Ci.nsIURI)) + return false; + + // Load favicons for http(s) pages only. + return uri.schemeIs("http") || uri.schemeIs("https"); + } +};