2 * (C) Copyright 2008 Jeremy Maitin-Shepard
3 * (C) Copyright 2010 John J. Foerch
5 * Portions of this file were derived from Mozilla,
6 * (C) Copyright 1998-2008 Mozilla Foundation.
8 * Use, modification, and distribution are subject to the terms specified in the
12 const favicon_service = Cc["@mozilla.org/browser/favicon-service;1"]
13 .getService(Ci.nsIFaviconService);
15 define_variable("favicon_image_max_size", 1024,
16 "Maximum (pixel) width and height of an image document that "+
17 "is considered for use as a favicon.");
21 let favicon_set_internal;
22 if (version_compare(get_mozilla_version(), "18.0") >= 0) {
23 favicon_set_internal = function (buffer, icon_url) {
24 favicon_service.setAndFetchFaviconForPage(
25 buffer.current_uri, icon_url, false,
26 favicon_service.FAVICON_LOAD_NON_PRIVATE);
29 favicon_set_internal = function (buffer, icon_url) {
30 favicon_service.setAndLoadFaviconForPage(
31 buffer.current_uri, icon_url, false);
34 var favicon_set = function favicon_set (buffer, icon_url) {
35 favicon_set_internal(buffer, icon_url);
36 buffer.icon = icon_url.spec;
41 function favicon_content_buffer_started_loading (buffer) {
46 function favicon_content_buffer_finished_loading (buffer) {
47 if (buffer.icon != null)
50 if (buffer.document instanceof Ci.nsIImageDocument) {
51 var req = buffer.document.imageRequest;
52 if (req && req.image &&
53 req.image.width <= favicon_image_max_size &&
54 req.image.height <= favicon_image_max_size)
56 favicon_set(buffer, buffer.current_uri);
61 var uri = buffer.current_uri;
62 // Only load favicons for http and https
63 if (!uri.schemeIs("http") && !uri.schemeIs("https"))
66 var icon_url = make_uri(uri.prePath + "/favicon.ico");
67 if (!favicon_service.isFailedFavicon(icon_url))
68 favicon_set(buffer, icon_url);
72 function favicon_content_buffer_dom_link_added (buffer, event) {
73 var link = event.originalTarget;
74 if (!link || !link.ownerDocument || !link.rel || !link.href ||
75 link.ownerDocument != buffer.document)
79 var rel = link.rel.toLowerCase();
80 var rel_strings = rel.split(/\s+/);
81 if (rel_strings.indexOf("icon") == -1)
84 /* FIXME: perhaps worry about newURI throwing an exception */
85 var target_doc = link.ownerDocument;
86 var ios = Cc["@mozilla.org/network/io-service;1"]
87 .getService(Ci.nsIIOService);
88 var uri = ios.newURI(link.href, target_doc.characterSet, null);
90 if (favicon_service.isFailedFavicon(uri))
93 // Verify that the load of this icon is legal.
94 // error pages can load their favicon, to be on the safe side,
95 // only allow chrome:// favicons
96 const about_neterr = "about:neterror?";
97 if (target_doc.documentURI.substr(0, about_neterr.length) != about_neterr
98 || !uri.schemeIs("chrome"))
100 var ssm = Cc["@mozilla.org/scriptsecuritymanager;1"]
101 .getService(Ci.nsIScriptSecurityManager);
103 ssm.checkLoadURIWithPrincipal(
104 target_doc.nodePrincipal, uri,
105 Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
113 return; // Refuse to load if we can't do a security check.
116 // Security says okay, now ask content policy
117 var content_policy_service = Cc["@mozilla.org/layout/content-policy;1"]
118 .getService(Ci.nsIContentPolicy);
119 if (content_policy_service.shouldLoad(Ci.nsIContentPolicy.TYPE_IMAGE,
120 uri, target_doc.documentURIObject,
121 link, link.type, null)
122 != Ci.nsIContentPolicy.ACCEPT)
127 favicon_set(buffer, uri);
131 add_hook("content_buffer_started_loading_hook",
132 favicon_content_buffer_started_loading);
134 add_hook("content_buffer_finished_loading_hook",
135 favicon_content_buffer_finished_loading);
137 add_hook("content_buffer_dom_link_added_hook",
138 favicon_content_buffer_dom_link_added);