whitespace
[conkeror/arlinius.git] / modules / favicon.js
blob744538b1e0d48f05cc8ea25218771620885b4950
1 /**
2  * (C) Copyright 2008 Jeremy Maitin-Shepard
3  *
4  * Portions of this file were derived from Mozilla,
5  * (C) Copyright 1998-2008 Mozilla Foundation.
6  *
7  * Use, modification, and distribution are subject to the terms specified in the
8  * COPYING file.
9 **/
11 const favicon_service = Cc["@mozilla.org/browser/favicon-service;1"]
12     .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.");
19 define_buffer_local_hook("buffer_favicon_change_hook");
22 function favicon_set (buffer, icon_url) {
23     buffer.favicon = icon_url.spec;
24     favicon_service.setAndLoadFaviconForPage(buffer.current_uri,
25                                              icon_url, false);
26     buffer_favicon_change_hook.run(buffer);
30 function favicon_content_buffer_started_loading (buffer) {
31     var old = buffer.favicon;
32     buffer.favicon = null;
33     if (old != null)
34         buffer_favicon_change_hook.run(buffer);
36 add_hook("content_buffer_started_loading_hook",
37          favicon_content_buffer_started_loading);
40 function favicon_content_buffer_finished_loading (buffer) {
41     if (buffer.favicon != null)
42         return;
44     if (buffer.document instanceof Ci.nsIImageDocument) {
45         var req = buffer.document.imageRequest;
46         if (req && req.image &&
47             req.image.width <= favicon_image_max_size  &&
48             req.image.height <= favicon_image_max_size)
49         {
50             favicon_set(buffer, buffer.current_uri);
51             return;
52         }
53     }
55     var uri = buffer.current_uri;
56     // Only load favicons for http and https
57     if (!uri.schemeIs("http") && !uri.schemeIs("https"))
58         return;
60     var icon_url = make_uri(uri.prePath + "/favicon.ico");
61     if (!favicon_service.isFailedFavicon(icon_url))
62         favicon_set(buffer, icon_url);
64 add_hook("content_buffer_finished_loading_hook",
65          favicon_content_buffer_finished_loading);
68 function favicon_content_buffer_dom_link_added (buffer, event) {
69    var link = event.originalTarget;
71     if (!link || !link.ownerDocument || !link.rel || !link.href)
72         return;
74     var rel = link.rel.toLowerCase();
75     var rel_strings = rel.split(/\s+/);
76     if (rel_strings.indexOf("icon") == -1)
77         return;
79     /* FIXME: perhaps worry about newURI throwing an exception */
80     var target_doc = link.ownerDocument;
81     var ios = Cc["@mozilla.org/network/io-service;1"]
82         .getService(Ci.nsIIOService);
83     var uri = ios.newURI(link.href, target_doc.characterSet, null);
85     if (favicon_service.isFailedFavicon(uri))
86         return;
88     // Verify that the load of this icon is legal.
89     // error pages can load their favicon, to be on the safe side,
90     // only allow chrome:// favicons
91     const about_neterr = "about:neterror?";
92     if (target_doc.documentURI.substr(0, about_neterr.length) != about_neterr
93         || !uri.schemeIs("chrome"))
94     {
95         var ssm = Cc["@mozilla.org/scriptsecuritymanager;1"]
96             .getService(Ci.nsIScriptSecurityManager);
97         try {
98             ssm.checkLoadURIWithPrincipal(
99                 target_doc.nodePrincipal, uri,
100                 Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
101         } catch(e) {
102             return;
103         }
104     }
106     try {
107     } catch(e) {
108         return; // Refuse to load if we can't do a security check.
109     }
111     // Security says okay, now ask content policy
112     var content_policy_service = Cc["@mozilla.org/layout/content-policy;1"]
113         .getService(Ci.nsIContentPolicy);
114     if (content_policy_service.shouldLoad(Ci.nsIContentPolicy.TYPE_IMAGE,
115                                           uri, target_doc.documentURIObject,
116                                           link, link.type, null)
117         != Ci.nsIContentPolicy.ACCEPT)
118     {
119         return;
120     }
122     favicon_set(buffer, uri);
124 add_hook("content_buffer_dom_link_added_hook",
125          favicon_content_buffer_dom_link_added);