1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/components/tabview/favicons.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,141 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +let FavIcons = { 1.9 + // Pref that controls whether to display site icons. 1.10 + PREF_CHROME_SITE_ICONS: "browser.chrome.site_icons", 1.11 + 1.12 + // Pref that controls whether to display fav icons. 1.13 + PREF_CHROME_FAVICONS: "browser.chrome.favicons", 1.14 + 1.15 + // Lazy getter for pref browser.chrome.site_icons. 1.16 + get _prefSiteIcons() { 1.17 + delete this._prefSiteIcons; 1.18 + this._prefSiteIcons = Services.prefs.getBoolPref(this.PREF_CHROME_SITE_ICONS); 1.19 + }, 1.20 + 1.21 + // Lazy getter for pref browser.chrome.favicons. 1.22 + get _prefFavicons() { 1.23 + delete this._prefFavicons; 1.24 + this._prefFavicons = Services.prefs.getBoolPref(this.PREF_CHROME_FAVICONS); 1.25 + }, 1.26 + 1.27 + get defaultFavicon() this._favIconService.defaultFavicon.spec, 1.28 + 1.29 + init: function FavIcons_init() { 1.30 + XPCOMUtils.defineLazyServiceGetter(this, "_favIconService", 1.31 + "@mozilla.org/browser/favicon-service;1", "nsIFaviconService"); 1.32 + 1.33 + Services.prefs.addObserver(this.PREF_CHROME_SITE_ICONS, this, false); 1.34 + Services.prefs.addObserver(this.PREF_CHROME_FAVICONS, this, false); 1.35 + }, 1.36 + 1.37 + uninit: function FavIcons_uninit() { 1.38 + Services.prefs.removeObserver(this.PREF_CHROME_SITE_ICONS, this); 1.39 + Services.prefs.removeObserver(this.PREF_CHROME_FAVICONS, this); 1.40 + }, 1.41 + 1.42 + observe: function FavIcons_observe(subject, topic, data) { 1.43 + let value = Services.prefs.getBoolPref(data); 1.44 + 1.45 + if (data == this.PREF_CHROME_SITE_ICONS) 1.46 + this._prefSiteIcons = value; 1.47 + else if (data == this.PREF_CHROME_FAVICONS) 1.48 + this._prefFavicons = value; 1.49 + }, 1.50 + 1.51 + // ---------- 1.52 + // Function: getFavIconUrlForTab 1.53 + // Gets the "favicon link URI" for the given xul:tab, or null if unavailable. 1.54 + getFavIconUrlForTab: function FavIcons_getFavIconUrlForTab(tab, callback) { 1.55 + this._isImageDocument(tab, function (isImageDoc) { 1.56 + if (isImageDoc) { 1.57 + callback(tab.pinned ? tab.image : null); 1.58 + } else { 1.59 + this._getFavIconForNonImageDocument(tab, callback); 1.60 + } 1.61 + }.bind(this)); 1.62 + }, 1.63 + 1.64 + // ---------- 1.65 + // Function: _getFavIconForNonImageDocument 1.66 + // Retrieves the favicon for a tab containing a non-image document. 1.67 + _getFavIconForNonImageDocument: 1.68 + function FavIcons_getFavIconForNonImageDocument(tab, callback) { 1.69 + 1.70 + if (tab.image) 1.71 + this._getFavIconFromTabImage(tab, callback); 1.72 + else if (this._shouldLoadFavIcon(tab)) 1.73 + this._getFavIconForHttpDocument(tab, callback); 1.74 + else 1.75 + callback(null); 1.76 + }, 1.77 + 1.78 + // ---------- 1.79 + // Function: _getFavIconFromTabImage 1.80 + // Retrieves the favicon for tab with a tab image. 1.81 + _getFavIconFromTabImage: 1.82 + function FavIcons_getFavIconFromTabImage(tab, callback) { 1.83 + 1.84 + let tabImage = gBrowser.getIcon(tab); 1.85 + 1.86 + // If the tab image's url starts with http(s), fetch icon from favicon 1.87 + // service via the moz-anno protocol. 1.88 + if (/^https?:/.test(tabImage)) { 1.89 + let tabImageURI = gWindow.makeURI(tabImage); 1.90 + tabImage = this._favIconService.getFaviconLinkForIcon(tabImageURI).spec; 1.91 + } 1.92 + 1.93 + callback(tabImage); 1.94 + }, 1.95 + 1.96 + // ---------- 1.97 + // Function: _getFavIconForHttpDocument 1.98 + // Retrieves the favicon for tab containg a http(s) document. 1.99 + _getFavIconForHttpDocument: 1.100 + function FavIcons_getFavIconForHttpDocument(tab, callback) { 1.101 + 1.102 + let {currentURI} = tab.linkedBrowser; 1.103 + this._favIconService.getFaviconURLForPage(currentURI, function (uri) { 1.104 + if (uri) { 1.105 + callback(this._favIconService.getFaviconLinkForIcon(uri).spec); 1.106 + } else { 1.107 + callback(this.defaultFavicon); 1.108 + } 1.109 + }.bind(this)); 1.110 + }, 1.111 + 1.112 + // ---------- 1.113 + // Function: _isImageDocument 1.114 + // Checks whether an image is loaded into the given tab. 1.115 + _isImageDocument: function UI__isImageDocument(tab, callback) { 1.116 + let mm = tab.linkedBrowser.messageManager; 1.117 + let message = "Panorama:isImageDocument"; 1.118 + 1.119 + mm.addMessageListener(message, function onMessage(cx) { 1.120 + mm.removeMessageListener(cx.name, onMessage); 1.121 + callback(cx.json.isImageDocument); 1.122 + }); 1.123 + 1.124 + mm.sendAsyncMessage(message); 1.125 + }, 1.126 + 1.127 + // ---------- 1.128 + // Function: _shouldLoadFavIcon 1.129 + // Checks whether fav icon should be loaded for a given tab. 1.130 + _shouldLoadFavIcon: function FavIcons_shouldLoadFavIcon(tab) { 1.131 + // No need to load a favicon if the user doesn't want site or favicons. 1.132 + if (!this._prefSiteIcons || !this._prefFavicons) 1.133 + return false; 1.134 + 1.135 + let uri = tab.linkedBrowser.currentURI; 1.136 + 1.137 + // Stop here if we don't have a valid nsIURI. 1.138 + if (!uri || !(uri instanceof Ci.nsIURI)) 1.139 + return false; 1.140 + 1.141 + // Load favicons for http(s) pages only. 1.142 + return uri.schemeIs("http") || uri.schemeIs("https"); 1.143 + } 1.144 +};