2 * (C) Copyright 2008 Jeremy Maitin-Shepard
4 * Portions of this file were derived from Mozilla,
5 * (C) Copyright 1998-2008 Mozilla Foundation.
7 * Use, modification, and distribution are subject to the terms specified in the
13 const favicon_service = Cc["@mozilla.org/browser/favicon-service;1"]
14 .getService(Ci.nsIFaviconService);
17 define_variable("favicon_image_max_size", 1024,
18 "Maximum (pixel) width and height of an image document that "+
19 "is considered for use as a favicon.");
21 define_buffer_local_hook("buffer_favicon_change_hook");
24 function favicon_set (buffer, icon_url) {
25 buffer.favicon = icon_url.spec;
26 favicon_service.setAndLoadFaviconForPage(buffer.current_uri,
28 buffer_favicon_change_hook.run(buffer);
32 function favicon_content_buffer_started_loading (buffer) {
33 var old = buffer.favicon;
34 buffer.favicon = null;
36 buffer_favicon_change_hook.run(buffer);
38 add_hook("content_buffer_started_loading_hook",
39 favicon_content_buffer_started_loading);
42 function favicon_content_buffer_finished_loading (buffer) {
43 if (buffer.favicon != null)
46 if (buffer.document instanceof Ci.nsIImageDocument) {
47 var req = buffer.document.imageRequest;
48 if (req && req.image &&
49 req.image.width <= favicon_image_max_size &&
50 req.image.height <= favicon_image_max_size)
52 favicon_set(buffer, buffer.current_uri);
57 var uri = buffer.current_uri;
58 // Only load favicons for http and https
59 if (!uri.schemeIs("http") && !uri.schemeIs("https"))
62 var icon_url = make_uri(uri.prePath + "/favicon.ico");
63 if (!favicon_service.isFailedFavicon(icon_url))
64 favicon_set(buffer, icon_url);
66 add_hook("content_buffer_finished_loading_hook",
67 favicon_content_buffer_finished_loading);
70 function favicon_content_buffer_dom_link_added (buffer, event) {
71 var link = event.originalTarget;
73 if (!link || !link.ownerDocument || !link.rel || !link.href)
76 var rel = link.rel.toLowerCase();
77 var rel_strings = rel.split(/\s+/);
78 if (rel_strings.indexOf("icon") == -1)
81 /* FIXME: perhaps worry about newURI throwing an exception */
82 var target_doc = link.ownerDocument;
83 var ios = Cc["@mozilla.org/network/io-service;1"]
84 .getService(Ci.nsIIOService);
85 var uri = ios.newURI(link.href, target_doc.characterSet, null);
87 if (favicon_service.isFailedFavicon(uri))
90 // Verify that the load of this icon is legal.
91 // error pages can load their favicon, to be on the safe side,
92 // only allow chrome:// favicons
93 const about_neterr = "about:neterror?";
94 if (target_doc.documentURI.substr(0, about_neterr.length) != about_neterr
95 || !uri.schemeIs("chrome"))
97 var ssm = Cc["@mozilla.org/scriptsecuritymanager;1"]
98 .getService(Ci.nsIScriptSecurityManager);
100 ssm.checkLoadURIWithPrincipal(
101 target_doc.nodePrincipal, uri,
102 Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
110 return; // Refuse to load if we can't do a security check.
113 // Security says okay, now ask content policy
114 var content_policy_service = Cc["@mozilla.org/layout/content-policy;1"]
115 .getService(Ci.nsIContentPolicy);
116 if (content_policy_service.shouldLoad(Ci.nsIContentPolicy.TYPE_IMAGE,
117 uri, target_doc.documentURIObject,
118 link, link.type, null)
119 != Ci.nsIContentPolicy.ACCEPT)
124 favicon_set(buffer, uri);
126 add_hook("content_buffer_dom_link_added_hook",
127 favicon_content_buffer_dom_link_added);