File: favicon.js

package info (click to toggle)
conkeror 0.9~git080629-2
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 1,132 kB
  • ctags: 906
  • sloc: sh: 340; ansic: 246; xml: 105; makefile: 77
file content (107 lines) | stat: -rw-r--r-- 3,866 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/**
 * (C) Copyright 2008 Jeremy Maitin-Shepard
 *
 * Portions of this file were derived from Mozilla,
 * (C) Copyright 1998-2008 Mozilla Foundation.
 *
 * Use, modification, and distribution are subject to the terms specified in the
 * COPYING file.
**/

const favicon_service = Cc["@mozilla.org/browser/favicon-service;1"].getService(Ci.nsIFaviconService);

define_buffer_local_hook("buffer_favicon_change_hook");

function favicon_content_buffer_started_loading(buffer) {
    var old = buffer.favicon;
    buffer.favicon = null;
    if (old != null)
        buffer_favicon_change_hook.run(buffer);
}
add_hook("content_buffer_started_loading_hook", favicon_content_buffer_started_loading);

define_variable("favicon_image_max_size", 1024, "Maximum (pixel) width and height of an image document that is considered for use as a favicon.");
var favicon_image_max_size = 1024;

function favicon_content_buffer_finished_loading(buffer) {
    if (buffer.favicon != null)
        return;

    if (buffer.document instanceof Ci.nsIImageDocument) {
        var req = buffer.document.imageRequest;
        if (req && req.image &&
            req.image.width <= favicon_image_max_size  &&
            req.image.height <= favicon_image_max_size) {
            favicon_set(buffer, buffer.current_URI);
            return;
        }
    }

    var uri = buffer.current_URI;
    // Only load favicons for http and https
    if (!uri.schemeIs("http") && !uri.schemeIs("https"))
        return;

    var icon_url = makeURL(uri.prePath + "/favicon.ico");
    if (!favicon_service.isFailedFavicon(icon_url))
        favicon_set(buffer, icon_url);
}
add_hook("content_buffer_finished_loading_hook", favicon_content_buffer_finished_loading);

var content_policy_service = Cc["@mozilla.org/layout/content-policy;1"].getService(Ci.nsIContentPolicy);

function favicon_content_buffer_dom_link_added(buffer, event) {
    var link = event.originalTarget;

    if (!link || !link.ownerDocument || !link.rel || !link.href)
        return;

    var rel = link.rel.toLowerCase();
    var rel_strings = rel.split(/\s+/);
    if (rel_strings.indexOf("icon") == -1)
        return;

    /* FIXME: perhaps worry about newURI throwing an exception */
    var target_doc = link.ownerDocument;
    var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
    var uri = ios.newURI(link.href, target_doc.characterSet, null);

    if (favicon_service.isFailedFavicon(uri))
        return;

    // Verify that the load of this icon is legal.
    // error pages can load their favicon, to be on the safe side,
    // only allow chrome:// favicons
    const about_neterr = "about:neterror?";
    if (target_doc.documentURI.substr(0, about_neterr.length) != about_neterr || !uri.schemeIs("chrome")) {
        var ssm = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
        try {
            ssm.checkLoadURIWithPrincipal(target_doc.nodePrincipal, uri,
                                          Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
        } catch(e) {
            return;
        }
    }

    try {
    } catch(e) {
        return; // Refuse to load if we can't do a security check.
    }

    // Security says okay, now ask content policy
    if (content_policy_service.shouldLoad(Ci.nsIContentPolicy.TYPE_IMAGE,
                                          uri, target_doc.documentURIObject,
                                          link, link.type, null)
        != Ci.nsIContentPolicy.ACCEPT)
        return;

    favicon_set(buffer, uri);
}
add_hook("content_buffer_dom_link_added_hook", favicon_content_buffer_dom_link_added);

function favicon_set(buffer, icon_url) {
    buffer.favicon = icon_url.spec;

    favicon_service.setAndLoadFaviconForPage(buffer.current_URI, icon_url, false);
    buffer_favicon_change_hook.run(buffer);
}