b=174265 (also 252288, 253161): favicon handling merge from aviary branch

This commit is contained in:
vladimir%pobox.com 2004-07-29 23:49:31 +00:00
parent e715f98c50
commit 33f488f5ea
7 changed files with 328 additions and 217 deletions

View File

@ -108,6 +108,27 @@ function loadEventHandlers(event)
charsetLoadListener(event);
updatePageTheme();
}
// some event handlers want to be told what the original browser is
var targetBrowser = null;
if (gBrowser.mTabbedMode) {
// var targetBrowserIndex = gBrowser.getBrowserIndexForDocument(event.originalTarget);
// if (targetBrowserIndex == -1)
// return;
// targetBrowser = gBrowser.getBrowserAtIndex(targetBrowserIndex);
for (var i = 0; i < gBrowser.mPanelContainer.childNodes.length; i++) {
if (gBrowser.mPanelContainer.childNodes[i].contentDocument == event.originalTarget) {
targetBrowser = gBrowser.mPanelContainer.childNodes[i];
break;
}
}
} else if (gBrowser.mCurrentBrowser.contentDocument == event.originalTarget) {
targetBrowser = gBrowser.mCurrentBrowser;
}
if (targetBrowser == null)
return;
updatePageFavIcon(targetBrowser);
}
/**
@ -134,18 +155,6 @@ function UpdateBookmarksLastVisitedDate(event)
}
}
function HandleBookmarkIcon(iconURL, addFlag)
{
var url = getWebNavigation().currentURI.spec
if (url) {
// update URL with new icon reference
if (addFlag)
BMSVC.updateBookmarkIcon(url, iconURL);
else
BMSVC.removeBookmarkIcon(url, iconURL);
}
}
function UpdateBackForwardButtons()
{
var backBroadcaster = document.getElementById("Browser:Back");
@ -1525,24 +1534,26 @@ function SetPageProxyState(aState, aURI)
gProxyButton.setAttribute("pageproxystate", aState);
// the page proxy state is set to valid via OnLocationChange, which
// gets called when we switch tabs. We'll let updatePageFavIcon
// take care of updating the mFavIconURL because it knows exactly
// for which tab to update things, instead of confusing the issue
// here.
if (aState == "valid") {
gLastValidURLStr = gURLBar.value;
gURLBar.addEventListener("input", UpdatePageProxyState, false);
if (gBrowser.shouldLoadFavIcon(aURI)) {
var favStr = gBrowser.buildFavIconString(aURI);
if (favStr != gProxyFavIcon.src) {
gBrowser.loadFavIcon(aURI, "src", gProxyFavIcon);
gProxyDeck.selectedIndex = 0;
}
else gProxyDeck.selectedIndex = 1;
}
else {
if (gBrowser.mCurrentBrowser.mFavIconURL != null) {
gProxyFavIcon.setAttribute("src", gBrowser.mCurrentBrowser.mFavIconURL);
gProxyDeck.selectedIndex = 1;
} else {
gProxyDeck.selectedIndex = 0;
gProxyFavIcon.removeAttribute("src");
}
} else if (aState == "invalid") {
gURLBar.removeEventListener("input", UpdatePageProxyState, false);
gProxyDeck.selectedIndex = 0;
gProxyFavIcon.removeAttribute("src");
}
}
@ -2391,13 +2402,15 @@ nsBrowserStatusHandler.prototype =
}
},
onLinkIconAvailable : function(aHref)
onLinkIconAvailable : function(aBrowser, aHref)
{
var browser = getBrowser()
if (gProxyFavIcon) {
if (browser.userTypedValue === null)
gProxyFavIcon.setAttribute("src", aHref);
if (gProxyFavIcon &&
gBrowser.mCurrentBrowser == aBrowser &&
getBrowser().userTypedValue === null) {
gProxyFavIcon.setAttribute("src", aHref);
}
aBrowser.mFavIconURL = aHref;
},
onProgressChange : function (aWebProgress, aRequest,
@ -2521,6 +2534,9 @@ nsBrowserStatusHandler.prototype =
if (browser.userTypedClear)
browser.userTypedValue = null;
// reset any favicon set for the browser
browser.mFavIconURL = null;
//XXXBlake don't we have to reinit this.urlBar, etc.
// when the toolbar changes?
var userTypedValue = browser.userTypedValue;
@ -4734,3 +4750,29 @@ function AddKeywordForSearchField()
false, "", true, postData);
}
function updatePageFavIcon(aBrowser) {
var uri = aBrowser.currentURI;
if (!gBrowser.shouldLoadFavIcon(uri))
return;
// if we made it here with this null, then no <link> was found for
// the page load. We try to fetch a generic favicon.ico.
if (aBrowser.mFavIconURL == null)
aBrowser.mFavIconURL = gBrowser.buildFavIconString(uri);
dump ("updatePageFavIcon: " + uri.spec + " => " + aBrowser.mFavIconURL + "\n");
if (aBrowser == gBrowser.mCurrentBrowser) {
if (gProxyFavIcon.src != aBrowser.mFavIconURL) {
gProxyFavIcon.setAttribute("src", aBrowser.mFavIconURL);
gProxyDeck.selectedIndex = 0;
} else {
gProxyDeck.selectedIndex = 1;
}
}
if (aBrowser.mFavIconURL != null) {
BookmarksUtils.loadFavIcon(uri.spec, aBrowser.mFavIconURL);
}
}

View File

@ -210,9 +210,9 @@
ondraggesture="PageProxyDragGesture(event);"
onload="this.parentNode.selectedIndex = 1;
event.stopPropagation();
event.preventBubble();
HandleBookmarkIcon(this.src, true);"
onerror="gBrowser.addToMissedIconCache(this.src); HandleBookmarkIcon(this.src, false);
event.preventBubble();"
onerror="gBrowser.addToMissedIconCache(this.src);
this.removeAttribute('src');
this.parentNode.selectedIndex = 0;"
tooltiptext="&proxyIcon.tooltip;"/>
</deck>

View File

@ -73,6 +73,10 @@ var kDSContractID;
var kDSIID;
var DS;
var kIOContractID;
var kIOIID;
var IOSVC;
// should be moved in a separate file
function initServices()
{
@ -113,6 +117,9 @@ function initServices()
kDSIID = Components.interfaces.nsIDragService;
DS = Components.classes[kDSContractID].getService(kDSIID);
kIOContractID = "@mozilla.org/network/io-service;1";
kIOIID = Components.interfaces.nsIIOService;
IOSVC = Components.classes[kIOContractID].getService(kIOIID);
}
function initBMService()
@ -1351,6 +1358,32 @@ var BookmarksUtils = {
openDialog("chrome://browser/content/bookmarks/addBookmark2.xul", "",
"centerscreen,chrome,dialog,resizable,dependent", aTitle, aURL, null, aCharset,
null, null, aIsWebPanel);
},
loadFavIcon: function (aURL, aFavIconURL) {
var urlLiteral = RDF.GetLiteral(aURL);
// don't do anything if this URI isn't bookmarked
var bmResources = BMSVC.GetSources(RDF.GetResource(NC_NS+"URL"), urlLiteral, true);
var toUpdate = 0;
while (bmResources.hasMoreElements()) {
var bmResource = bmResources.getNext();
// don't flag this as needing update if it already has a data: icon url set
var oldIcon = BMDS.GetTarget(bmResource, RDF.GetResource(NC_NS+"Icon"), true);
if (oldIcon && (oldIcon.QueryInterface(kRDFLITIID).Value.substring(0,5) == "data:"))
continue;
toUpdate++;
}
if (toUpdate == 0)
return;
var chan = IOSVC.newChannel(aFavIconURL, null, null);
var listener = new bookmarksFavIconLoadListener (aURL, aFavIconURL, chan);
chan.notificationCallbacks = listener;
chan.asyncOpen(listener, null);
}
}
@ -1612,6 +1645,94 @@ var BookmarkEditMenuTxnListener =
}
}
// favicon loaders
function bookmarksFavIconLoadListener(uri, faviconurl, channel) {
this.mURI = uri;
this.mFavIconURL = faviconurl;
this.mCountRead = 0;
this.mChannel = channel;
}
bookmarksFavIconLoadListener.prototype = {
mURI : null,
mFavIconURL : null,
mCountRead : null,
mChannel : null,
mBytes : "",
mStream : null,
QueryInterface: function (iid) {
if (!iid.equals(Components.interfaces.nsISupports) &&
!iid.equals(Components.interfaces.nsIInterfaceRequestor) &&
!iid.equals(Components.interfaces.nsIRequestObserver) &&
!iid.equals(Components.interfaces.nsIHttpEventSink) &&
!iid.equals(Components.interfaces.nsIProgressEventSink) && // see below
!iid.equals(Components.interfaces.nsIStreamListener)) {
throw Components.results.NS_ERROR_NO_INTERFACE;
}
return this;
},
// nsIInterfaceRequestor
getInterface: function (iid) {
try {
return this.QueryInterface(iid);
} catch (e) {
throw Components.results.NS_NOINTERFACE;
}
},
// nsIRequestObserver
onStartRequest : function (aRequest, aContext) {
this.mStream = Components.classes['@mozilla.org/binaryinputstream;1'].createInstance(Components.interfaces.nsIBinaryInputStream);
},
onStopRequest : function (aRequest, aContext, aStatusCode) {
var httpChannel = this.mChannel.QueryInterface(Components.interfaces.nsIHttpChannel);
if ((httpChannel && httpChannel.requestSucceeded) &&
Components.isSuccessCode(aStatusCode) &&
this.mCountRead > 0)
{
var dataurl;
// XXX - arbitrary size beyond which we won't store a favicon. This is /extremely/
// generous, and is probably too high.
if (this.mCountRead > 16384) {
dataurl = "data:"; // hack meaning "pretend this doesn't exist"
} else {
// build a data URL for the favicon
// we can't really trust contentType, but then, the image loader doesn't
// trust it either.
dataurl = "data:" + this.mChannel.contentType + ";base64," + btoa(this.mBytes);
}
BMSVC.updateBookmarkIcon(this.mURI, dataurl);
}
this.mChannel = null;
},
// nsIStreamObserver
onDataAvailable : function (aRequest, aContext, aInputStream, aOffset, aCount) {
// we could get a different aInputStream, so we don't save this;
// it's unlikely we'll get more than one onDataAvailable for a
// favicon anyway
this.mStream.setInputStream(aInputStream);
this.mBytes += this.mStream.readBytes(aCount);
this.mCountRead += aCount;
},
// nsIHttpEventSink
onRedirect : function (aHttpChannel, aNewChannel) {
this.mChannel = aNewChannel;
},
// nsIProgressEventSink: the only reason we support
// nsIProgressEventSink is to shut up a whole slew of xpconnect
// warnings in debug builds. (see bug #253127)
onProgress : function (aRequest, aContext, aProgress, aProgressMax) { },
onStatus : function (aRequest, aContext, aStatus, aStatusArg) { }
}
#ifdef 0
var _dumpTIME;

View File

@ -86,7 +86,7 @@ interface nsIBookmarksService : nsISupports
void setBookmarksToolbarFolder(in nsIRDFResource aSource);
void updateBookmarkIcon(in string aURL, in wstring aIconURL);
void removeBookmarkIcon(in string aURL, in wstring aIconURL);
void removeBookmarkIcon(in string aURL);
void updateLastVisitedDate(in string aURL, in wstring docCharset);

View File

@ -28,6 +28,7 @@
* Pierre Chanial <chanial@noos.fr>
* Jan Varga <varga@nixcorp.com>
* Benjamin Smedberg <bsmedberg@covad.net>
* Vladimir Vukicevic <vladimir@pobox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -57,6 +58,7 @@
#include "nsIRDFService.h"
#include "nsIRDFXMLSerializer.h"
#include "nsIRDFXMLSource.h"
#include "nsIRDFPropagatableDataSource.h"
#include "nsRDFCID.h"
#include "nsISupportsPrimitives.h"
#include "rdf.h"
@ -970,10 +972,10 @@ BookmarkParser::Unescape(nsString &text)
text.Cut(offset, 6);
text.Insert(PRUnichar('\"'), offset);
}
else if (Substring(text, offset, 5).Equals(NS_LITERAL_STRING("&#39;")))
{
text.Cut(offset, 5);
text.Insert(PRUnichar('\''), offset);
else if (Substring(text, offset, 5).Equals(NS_LITERAL_STRING("&#39;")))
{
text.Cut(offset, 5);
text.Insert(PRUnichar('\''), offset);
}
++offset;
@ -2862,7 +2864,7 @@ nsBookmarksService::UpdateBookmarkIcon(const char *aURL, const PRUnichar *aIconU
return rv;
nsCOMPtr<nsISimpleEnumerator> bookmarks;
rv = GetSources(kNC_URL, urlLiteral, PR_TRUE, getter_AddRefs(bookmarks));
rv = mInner->GetSources(kNC_URL, urlLiteral, PR_TRUE, getter_AddRefs(bookmarks));
if (NS_FAILED(rv))
return rv;
@ -2877,15 +2879,38 @@ nsBookmarksService::UpdateBookmarkIcon(const char *aURL, const PRUnichar *aIconU
nsCOMPtr<nsIRDFResource> bookmark = do_QueryInterface(supports);
if (bookmark) {
nsCOMPtr<nsIRDFNode> iconNode;
rv = ProcessCachedBookmarkIcon(bookmark, aIconURL,
getter_AddRefs(iconNode));
rv = mInner->GetTarget(bookmark, kNC_Icon, PR_TRUE, getter_AddRefs(iconNode));
if (NS_SUCCEEDED(rv) && rv != NS_RDF_NO_VALUE) {
(void) mInner->Unassert(bookmark, kNC_Icon, iconNode);
}
// create a new literal for the url
nsCOMPtr<nsIRDFLiteral> urlLiteral;
rv = gRDF->GetLiteral(aIconURL, getter_AddRefs(urlLiteral));
if (NS_FAILED(rv))
return rv;
if (iconNode) {
// Yes, that's right. Fake out RDF observers.
(void)OnAssert(this, bookmark, kNC_Icon, iconNode);
if (nsDependentString(aIconURL).Equals(NS_LITERAL_STRING("data:"))) {
// if it's just "data:", then don't send notifications, otherwise
// things will update with a null icon
nsCOMPtr<nsIRDFPropagatableDataSource> propDS = do_QueryInterface(mInner);
PRBool oldPropChanges = PR_TRUE;
if (propDS) {
(void) propDS->GetPropagateChanges(&oldPropChanges);
(void) propDS->SetPropagateChanges(PR_FALSE);
}
rv = mInner->Assert(bookmark, kNC_Icon, urlLiteral, PR_TRUE);
if (propDS)
(void) propDS->SetPropagateChanges(oldPropChanges);
} else {
rv = mInner->Assert(bookmark, kNC_Icon, urlLiteral, PR_TRUE);
}
if (NS_FAILED(rv))
return rv;
mDirty = PR_TRUE;
}
}
@ -2893,7 +2918,7 @@ nsBookmarksService::UpdateBookmarkIcon(const char *aURL, const PRUnichar *aIconU
}
NS_IMETHODIMP
nsBookmarksService::RemoveBookmarkIcon(const char *aURL, const PRUnichar *aIconURL)
nsBookmarksService::RemoveBookmarkIcon(const char *aURL)
{
nsCOMPtr<nsIRDFLiteral> urlLiteral;
nsresult rv = gRDF->GetLiteral(NS_ConvertUTF8toUCS2(aURL).get(),
@ -2902,7 +2927,7 @@ nsBookmarksService::RemoveBookmarkIcon(const char *aURL, const PRUnichar *aIconU
return rv;
nsCOMPtr<nsISimpleEnumerator> bookmarks;
rv = GetSources(kNC_URL, urlLiteral, PR_TRUE, getter_AddRefs(bookmarks));
rv = mInner->GetSources(kNC_URL, urlLiteral, PR_TRUE, getter_AddRefs(bookmarks));
if (NS_FAILED(rv))
return rv;
@ -2916,19 +2941,28 @@ nsBookmarksService::RemoveBookmarkIcon(const char *aURL, const PRUnichar *aIconU
nsCOMPtr<nsIRDFResource> bookmark = do_QueryInterface(supports);
if (bookmark) {
nsCOMPtr<nsIRDFLiteral> iconLiteral;
rv = gRDF->GetLiteral(aIconURL, getter_AddRefs(iconLiteral));
if (NS_FAILED(rv))
nsCOMPtr<nsISimpleEnumerator> iconEnumerator;
rv = mInner->GetTargets(bookmark, kNC_Icon, PR_TRUE, getter_AddRefs(iconEnumerator));
if (NS_FAILED(rv))
return rv;
PRBool hasThisIconURL = PR_FALSE;
rv = mInner->HasAssertion(bookmark, kNC_Icon, iconLiteral, PR_TRUE,
&hasThisIconURL);
if (NS_FAILED(rv))
PRBool hasMore = PR_FALSE;
rv = iconEnumerator->HasMoreElements(&hasMore);
if (NS_FAILED(rv))
return rv;
while (hasMore) {
nsCOMPtr<nsISupports> supports;
rv = iconEnumerator->GetNext(getter_AddRefs(supports));
if (NS_FAILED(rv))
return rv;
if (hasThisIconURL) {
(void)mInner->Unassert(bookmark, kNC_Icon, iconLiteral);
nsCOMPtr<nsIRDFNode> targetNode = do_QueryInterface(supports);
if (targetNode)
(void)mInner->Unassert(bookmark, kNC_Icon, targetNode);
rv = iconEnumerator->HasMoreElements(&hasMore);
if (NS_FAILED(rv))
return rv;
}
}
}
@ -3401,8 +3435,47 @@ nsBookmarksService::GetTarget(nsIRDFResource* aSource,
}
else if (aProperty == kNC_Icon)
{
rv = ProcessCachedBookmarkIcon(aSource, nsnull, aTarget);
return rv;
if (!mBrowserIcons) {
// if the user has favicons turned off, don't return anything
return NS_RDF_NO_VALUE;
} else {
// the user doesn't have favicons turned off, but might have
// old non-data URLs for icons. We only want to return the
// value if it's a data url.
rv = mInner->GetTarget(aSource, aProperty, aTruthValue, aTarget);
if (NS_FAILED(rv) || rv == NS_RDF_NO_VALUE)
return rv;
nsCOMPtr<nsIRDFLiteral> iconLiteral = do_QueryInterface(*aTarget);
if (!iconLiteral) {
// erm, shouldn't happen
aTarget = nsnull;
return NS_RDF_NO_VALUE;
}
const PRUnichar *url = nsnull;
iconLiteral->GetValueConst(&url);
nsDependentString urlStr(url);
// if it's a data: url, all is well
if (Substring(urlStr, 0, 5).Equals(NS_LITERAL_STRING("data:"))) {
// XXX hack warning! Sometimes we want to indicate that a site
// should have no favicon even though it wants to feed us goop.
// To avoid reloading said goop each time, we stick in a URL
// consisting of purely "data:". So, if that's what we have,
// we pretend it has no icon.
if (urlStr.Length() == 5) {
aTarget = nsnull;
return NS_RDF_NO_VALUE;
}
return NS_OK;
}
// no data:? no icon!
aTarget = nsnull;
return NS_RDF_NO_VALUE;
}
}
rv = mInner->GetTarget(aSource, aProperty, aTruthValue, aTarget);
@ -3431,140 +3504,16 @@ nsBookmarksService::GetTargets(nsIRDFResource* aSource,
return GetLastModifiedFolders(aTargets);
}
if ((aProperty == kNC_Icon) && !mBrowserIcons) {
// if the user has favicons turned off, don't return anything
return NS_NewEmptyEnumerator(aTargets);
}
return mInner->GetTargets(aSource, aProperty, aTruthValue, aTargets);
}
nsresult
nsBookmarksService::ProcessCachedBookmarkIcon(nsIRDFResource* aSource,
const PRUnichar *iconURL, nsIRDFNode** aTarget)
{
*aTarget = nsnull;
if (!mBrowserIcons)
{
return NS_RDF_NO_VALUE;
}
// if it is in fact a bookmark or favorite (but NOT a folder, or a separator, etc)...
nsCOMPtr<nsIRDFNode> nodeType;
GetSynthesizedType(aSource, getter_AddRefs(nodeType));
if ((nodeType != kNC_Bookmark) && (nodeType != kNC_IEFavorite))
{
return NS_RDF_NO_VALUE;
}
nsresult rv;
nsCAutoString path;
nsCOMPtr<nsIRDFNode> oldIconNode;
// if we have a new icon URL, save it away into our internal graph
if (iconURL)
{
path.AssignWithConversion(iconURL);
nsCOMPtr<nsIRDFLiteral> iconLiteral;
if (NS_FAILED(rv = gRDF->GetLiteral(iconURL, getter_AddRefs(iconLiteral))))
{
return rv;
}
rv = mInner->GetTarget(aSource, kNC_Icon, PR_TRUE, getter_AddRefs(oldIconNode));
if (NS_SUCCEEDED(rv) && (rv != NS_RDF_NO_VALUE) && (oldIconNode))
{
(void)mInner->Unassert(aSource, kNC_Icon, oldIconNode);
}
(void)mInner->Assert(aSource, kNC_Icon, iconLiteral, PR_TRUE);
}
else
{
// otherwise, just check and see if we have an internal icon reference
rv = mInner->GetTarget(aSource, kNC_Icon, PR_TRUE, getter_AddRefs(oldIconNode));
}
if (oldIconNode)
{
nsCOMPtr<nsIRDFLiteral> tempLiteral = do_QueryInterface(oldIconNode);
if (tempLiteral)
{
const PRUnichar *uni = nsnull;
tempLiteral->GetValueConst(&uni);
if (uni) path.AssignWithConversion(uni);
}
}
// if no internal icon reference, try and synthesize a URL
if (path.IsEmpty())
{
const char *uri;
if (NS_FAILED(rv = aSource->GetValueConst( &uri )))
{
return rv;
}
nsCOMPtr<nsIURI> nsURI;
if (NS_FAILED(rv = mNetService->NewURI(nsDependentCString(uri), nsnull, nsnull, getter_AddRefs(nsURI))))
{
return rv;
}
// only allow http/https URLs for favicon
PRBool isHTTP = PR_FALSE;
nsURI->SchemeIs("http", &isHTTP);
if (!isHTTP)
{
nsURI->SchemeIs("https", &isHTTP);
}
if (!isHTTP)
{
return NS_RDF_NO_VALUE;
}
nsCAutoString prePath;
if (NS_FAILED(rv = nsURI->GetPrePath(prePath)))
{
return rv;
}
path.Assign(prePath);
path.Append("/favicon.ico");
}
// only return favicon reference if its in the cache
// (that is, never go out onto the net)
if (!mCacheSession)
{
return NS_RDF_NO_VALUE;
}
nsCOMPtr<nsICacheEntryDescriptor> entry;
rv = mCacheSession->OpenCacheEntry(path.get(), nsICache::ACCESS_READ,
nsICache::NON_BLOCKING, getter_AddRefs(entry));
if (NS_FAILED(rv) || (!entry))
{
return NS_RDF_NO_VALUE;
}
if (entry)
{
PRUint32 expTime;
entry->GetExpirationTime(&expTime);
if (expTime != PR_UINT32_MAX)
entry->SetExpirationTime(PR_UINT32_MAX);
}
entry->Close();
// ok, have a cached icon entry, so return the URL's associated favicon
nsAutoString litStr;
litStr.AssignWithConversion(path.get());
nsCOMPtr<nsIRDFLiteral> literal;
if (NS_FAILED(rv = gRDF->GetLiteral(litStr.get(), getter_AddRefs(literal))))
{
return rv;
}
*aTarget = literal;
NS_IF_ADDREF(*aTarget);
return NS_OK;
}
void
nsBookmarksService::AnnotateBookmarkSchedule(nsIRDFResource* aSource, PRBool scheduleFlag)
{

View File

@ -154,10 +154,6 @@ protected:
nsresult exportBookmarks(nsISupportsArray *aArguments);
nsresult ProcessCachedBookmarkIcon(nsIRDFResource* aSource,
const PRUnichar *iconURL,
nsIRDFNode** aTarget);
void AnnotateBookmarkSchedule(nsIRDFResource* aSource,
PRBool scheduleFlag);

View File

@ -477,7 +477,7 @@
p.onSecurityChange(webProgress, null, securityUI.state);
var listener = this.mTabListeners[this.mPanelContainer.selectedIndex];
if (listener.mIcon)
p.onLinkIconAvailable(listener.mIcon);
p.onLinkIconAvailable(newBrowser, listener.mIcon);
}
}
this.mCurrentBrowser.userTypedClear = userTypedClear;
@ -579,10 +579,11 @@
if (!href)
return;
const nsIContentPolicy = Components.interfaces.nsIContentPolicy;
try {
var contentPolicy =
Components.classes['@mozilla.org/layout/content-policy;1']
.getService(Components.interfaces.nsIContentPolicy);
.getService(nsIContentPolicy);
} catch(e) {
return; // Refuse to load if we can't do a security check.
}
@ -615,40 +616,42 @@
return;
}
var notifyListeners = true;
var i;
// Security says okay, now ask content policy
if (tabBrowser.mTabbedMode) {
// We need to update a tab.
for (i = 0; i < this.childNodes.length; i++) {
if (this.childNodes[i].contentDocument == event.target.ownerDocument) {
if (contentPolicy.shouldLoad(Components.interfaces.nsIContentPolicy.TYPE_IMAGE,
uri, origURI, event.target,
safeGetProperty(event.target, "type"),
null) != Components.interfaces.nsIContentPolicy.ACCEPT)
return;
var listener = tabBrowser.mTabListeners[i];
listener.mIcon = href;
break;
}
}
notifyListeners = (this.childNodes[i] == tabBrowser.mCurrentBrowser);
}
else if ((this.contentDocument != safeGetProperty(event.originalTarget, "ownerDocument")) ||
(contentPolicy.shouldLoad(Components.interfaces.nsIContentPolicy.TYPE_IMAGE,
uri, origURI, event.target,
safeGetProperty(event.target, "type"),
null) != Components.interfaces.nsIContentPolicy.ACCEPT))
if (contentPolicy.shouldLoad(nsIContentPolicy.TYPE_IMAGE,
uri, origURI, event.target,
safeGetProperty(event.target, "type"),
null) != nsIContentPolicy.ACCEPT)
return;
if (notifyListeners && tabBrowser.mProgressListeners) {
// var browserIndex = tabBrowser.getBrowserIndexForDocument(targetDoc);
var browserIndex = -1;
if (tabBrowser.mTabbedMode) {
for (var i = 0; i < tabBrowser.mPanelContainer.childNodes.length; i++) {
if (tabBrowser.mPanelContainer.childNodes[i].contentDocument == targetDoc) {
browserIndex = i;
break;
}
}
} else {
if (tabBrowser.mCurrentBrowser.contentDocument == targetDoc)
browserIndex = 0;
}
// no browser? no favicon.
if (browserIndex == -1)
return;
var listener = tabBrowser.mTabListeners[browserIndex];
// there's no tab listener for non-tabbed mode browser 0
if (listener)
listener.mIcon = href;
if (tabBrowser.mProgressListeners) {
var targetBrowser = tabBrowser.mTabbedMode ? tabBrowser.mPanelContainer.childNodes[i] : tabBrowser.mCurrentBrowser;
for (i = 0; i < tabBrowser.mProgressListeners.length; i++) {
var p = tabBrowser.mProgressListeners[i];
if (p)
p.onLinkIconAvailable(href);
p.onLinkIconAvailable(targetBrowser, href);
}
}
]]>