mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-03 02:25:34 +00:00
b=174265 (also 252288, 253161): favicon handling merge from aviary branch
This commit is contained in:
parent
e715f98c50
commit
33f488f5ea
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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("'")))
|
||||
{
|
||||
text.Cut(offset, 5);
|
||||
text.Insert(PRUnichar('\''), offset);
|
||||
else if (Substring(text, offset, 5).Equals(NS_LITERAL_STRING("'")))
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -154,10 +154,6 @@ protected:
|
||||
|
||||
nsresult exportBookmarks(nsISupportsArray *aArguments);
|
||||
|
||||
nsresult ProcessCachedBookmarkIcon(nsIRDFResource* aSource,
|
||||
const PRUnichar *iconURL,
|
||||
nsIRDFNode** aTarget);
|
||||
|
||||
void AnnotateBookmarkSchedule(nsIRDFResource* aSource,
|
||||
PRBool scheduleFlag);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
]]>
|
||||
|
Loading…
Reference in New Issue
Block a user