зеркало из https://github.com/mozilla/gecko-dev.git
fixes bug 166647 "allow link prefetching from a META tag + other fixes"
r=dougt,hixie sr=rpotts
This commit is contained in:
Родитель
425dbd86db
Коммит
f83410ff28
|
@ -47,6 +47,7 @@ REQUIRES = xpcom \
|
|||
uconv \
|
||||
pref \
|
||||
uriloader \
|
||||
prefetch \
|
||||
rdf \
|
||||
chardet \
|
||||
nkcache \
|
||||
|
|
|
@ -101,6 +101,7 @@
|
|||
#include "nsICharsetAlias.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsCPrefetchService.h"
|
||||
|
||||
#include "nsIWebShell.h"
|
||||
#include "nsIDocShell.h"
|
||||
|
@ -446,11 +447,16 @@ public:
|
|||
|
||||
void AddBaseTagInfo(nsIHTMLContent* aContent);
|
||||
|
||||
nsresult ProcessLink(nsIHTMLContent* aElement, const nsAString& aLinkData);
|
||||
nsresult ProcessStyleLink(nsIHTMLContent* aElement,
|
||||
nsresult ProcessLinkHeader(nsIHTMLContent* aElement, const nsAString& aLinkData);
|
||||
nsresult ProcessLink(nsIHTMLContent* aElement,
|
||||
const nsString& aHref, const nsString& aRel,
|
||||
const nsString& aTitle, const nsString& aType,
|
||||
const nsString& aMedia);
|
||||
nsresult ProcessStyleLink(nsIHTMLContent* aElement,
|
||||
const nsString& aHref, const nsStringArray& aLinkTypes,
|
||||
const nsString& aTitle, const nsString& aType,
|
||||
const nsString& aMedia);
|
||||
void ProcessNextLink(const nsAString &aRel);
|
||||
|
||||
void ProcessBaseHref(const nsAString& aBaseHref);
|
||||
void ProcessBaseTarget(const nsAString& aBaseTarget);
|
||||
|
@ -4167,7 +4173,7 @@ const PRUnichar kLessThanCh = PRUnichar('<');
|
|||
const PRUnichar kGreaterThanCh = PRUnichar('>');
|
||||
|
||||
nsresult
|
||||
HTMLContentSink::ProcessLink(nsIHTMLContent* aElement, const nsAString& aLinkData)
|
||||
HTMLContentSink::ProcessLinkHeader(nsIHTMLContent* aElement, const nsAString& aLinkData)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
|
||||
|
@ -4282,8 +4288,8 @@ HTMLContentSink::ProcessLink(nsIHTMLContent* aElement, const nsAString& aLinkDat
|
|||
}
|
||||
}
|
||||
if (kCommaCh == endCh) { // hit a comma, process what we've got so far
|
||||
if (!href.IsEmpty()) {
|
||||
result = ProcessStyleLink(aElement, href, rel, title, type, media);
|
||||
if (!href.IsEmpty() && !rel.IsEmpty()) {
|
||||
result = ProcessLink(aElement, href, rel, title, type, media);
|
||||
if (NS_ERROR_HTMLPARSER_BLOCK == result) {
|
||||
didBlock = PR_TRUE;
|
||||
}
|
||||
|
@ -4298,8 +4304,8 @@ HTMLContentSink::ProcessLink(nsIHTMLContent* aElement, const nsAString& aLinkDat
|
|||
start = ++end;
|
||||
}
|
||||
|
||||
if (!href.IsEmpty()) {
|
||||
result = ProcessStyleLink(aElement, href, rel, title, type, media);
|
||||
if (!href.IsEmpty() && !rel.IsEmpty()) {
|
||||
result = ProcessLink(aElement, href, rel, title, type, media);
|
||||
if (NS_SUCCEEDED(result) && didBlock) {
|
||||
result = NS_ERROR_HTMLPARSER_BLOCK;
|
||||
}
|
||||
|
@ -4308,25 +4314,38 @@ HTMLContentSink::ProcessLink(nsIHTMLContent* aElement, const nsAString& aLinkDat
|
|||
}
|
||||
|
||||
nsresult
|
||||
HTMLContentSink::ProcessStyleLink(nsIHTMLContent* aElement,
|
||||
HTMLContentSink::ProcessLink(nsIHTMLContent* aElement,
|
||||
const nsString& aHref, const nsString& aRel,
|
||||
const nsString& aTitle, const nsString& aType,
|
||||
const nsString& aMedia)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
|
||||
if (aHref.IsEmpty()) {
|
||||
// if href is empty then just bail
|
||||
// XXX seems overkill to generate this string array
|
||||
nsStringArray linkTypes;
|
||||
nsStyleLinkElement::ParseLinkTypes(aRel, linkTypes);
|
||||
|
||||
if (-1 != linkTypes.IndexOf(NS_LITERAL_STRING("next"))) { // is it a next link?
|
||||
ProcessNextLink(aHref);
|
||||
}
|
||||
|
||||
if (-1 != linkTypes.IndexOf(NS_LITERAL_STRING("stylesheet"))) { // is it a stylesheet link?
|
||||
result = ProcessStyleLink(aElement, aHref, linkTypes, aTitle, aType, aMedia);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsStringArray linkTypes;
|
||||
nsStyleLinkElement::ParseLinkTypes(aRel, linkTypes);
|
||||
nsresult
|
||||
HTMLContentSink::ProcessStyleLink(nsIHTMLContent* aElement,
|
||||
const nsString& aHref, const nsStringArray& aLinkTypes,
|
||||
const nsString& aTitle, const nsString& aType,
|
||||
const nsString& aMedia)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
PRBool isAlternate = PR_FALSE;
|
||||
|
||||
if (-1 != linkTypes.IndexOf(NS_LITERAL_STRING("stylesheet"))) { // is it a stylesheet link?
|
||||
|
||||
if (-1 != linkTypes.IndexOf(NS_LITERAL_STRING("alternate"))) { // if alternate, does it have title?
|
||||
if (-1 != aLinkTypes.IndexOf(NS_LITERAL_STRING("alternate"))) { // if alternate, does it have title?
|
||||
if (0 == aTitle.Length()) { // alternates must have title
|
||||
return NS_OK; //return without error, for now
|
||||
} else {
|
||||
|
@ -4371,7 +4390,7 @@ HTMLContentSink::ProcessStyleLink(nsIHTMLContent* aElement,
|
|||
return NS_OK; // The URL is bad, move along, don't propagate the error (for now)
|
||||
}
|
||||
|
||||
if (-1 == linkTypes.IndexOf(NS_LITERAL_STRING("alternate"))) {
|
||||
if (!isAlternate) {
|
||||
if (!aTitle.IsEmpty()) { // possibly preferred sheet
|
||||
nsAutoString preferredStyle;
|
||||
mDocument->GetHeaderData(nsHTMLAtoms::headerDefaultStyle, preferredStyle);
|
||||
|
@ -4406,10 +4425,28 @@ HTMLContentSink::ProcessStyleLink(nsIHTMLContent* aElement,
|
|||
result = NS_ERROR_HTMLPARSER_BLOCK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLContentSink::ProcessNextLink(const nsAString &aHref)
|
||||
{
|
||||
nsCOMPtr<nsIPrefetchService> prefetchService(
|
||||
do_GetService(NS_PREFETCHSERVICE_CONTRACTID));
|
||||
if (prefetchService) {
|
||||
// construct URI using document charset
|
||||
nsAutoString charset;
|
||||
mDocument->GetDocumentCharacterSet(charset);
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
NS_NewURI(getter_AddRefs(uri), aHref,
|
||||
charset.IsEmpty() ? nsnull
|
||||
: NS_LossyConvertUCS2toASCII(charset).get(),
|
||||
mDocumentBaseURL);
|
||||
if (uri)
|
||||
prefetchService->PrefetchURI(uri);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
|
||||
{
|
||||
|
@ -4462,6 +4499,22 @@ HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
|
|||
mStyleSheetCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// look for <link rel="next" href="url">
|
||||
nsAutoString relVal;
|
||||
element->GetAttr(kNameSpaceID_None, nsHTMLAtoms::rel, relVal);
|
||||
if (!relVal.IsEmpty()) {
|
||||
// XXX seems overkill to generate this string array
|
||||
nsStringArray linkTypes;
|
||||
nsStyleLinkElement::ParseLinkTypes(relVal, linkTypes);
|
||||
if (-1 != linkTypes.IndexOf(NS_LITERAL_STRING("next"))) {
|
||||
nsAutoString hrefVal;
|
||||
element->GetAttr(kNameSpaceID_None, nsHTMLAtoms::href, hrefVal);
|
||||
if (!hrefVal.IsEmpty()) {
|
||||
ProcessNextLink(hrefVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -4668,7 +4721,7 @@ HTMLContentSink::ProcessHeaderData(nsIAtom* aHeader,const nsAString& aValue,nsIH
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
} // END set-cookie
|
||||
else if (aHeader == nsHTMLAtoms::link) {
|
||||
rv = ProcessLink(aContent, aValue);
|
||||
rv = ProcessLinkHeader(aContent, aValue);
|
||||
}
|
||||
else if (mParser) {
|
||||
// we also need to report back HTTP-EQUIV headers to the channel
|
||||
|
|
|
@ -72,7 +72,7 @@ static const nsModuleComponentInfo components[] = {
|
|||
{ "Netscape Default Protocol Handler", NS_EXTERNALPROTOCOLHANDLER_CID, NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX"default",
|
||||
nsExternalProtocolHandlerConstructor, },
|
||||
{ NS_PREFETCHSERVICE_CLASSNAME, NS_PREFETCHSERVICE_CID, NS_PREFETCHSERVICE_CONTRACTID,
|
||||
nsPrefetchServiceConstructor, nsPrefetchService::RegisterProc, nsPrefetchService::UnregisterProc },
|
||||
nsPrefetchServiceConstructor, },
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -44,14 +44,11 @@
|
|||
#include "nsIDocCharset.h"
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsCURILoader.h"
|
||||
#include "nsINetModuleMgr.h"
|
||||
#include "nsICachingChannel.h"
|
||||
#include "nsICacheVisitor.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIParserService.h"
|
||||
#include "nsParserCIID.h"
|
||||
#include "nsString.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsReadableUtils.h"
|
||||
|
@ -75,8 +72,6 @@ static PRLogModuleInfo *gPrefetchLog;
|
|||
#define LOG_ENABLED() PR_LOG_TEST(gPrefetchLog, 4)
|
||||
|
||||
static NS_DEFINE_IID(kDocLoaderServiceCID, NS_DOCUMENTLOADER_SERVICE_CID);
|
||||
static NS_DEFINE_IID(kParserServiceCID, NS_PARSERSERVICE_CID);
|
||||
static NS_DEFINE_IID(kNetModuleMgrCID, NS_NETMODULEMGR_CID);
|
||||
static NS_DEFINE_IID(kPrefServiceCID, NS_PREFSERVICE_CID);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -96,50 +91,6 @@ PRTimeToSeconds(PRTime t_usec)
|
|||
|
||||
#define NowInSeconds() PRTimeToSeconds(PR_Now())
|
||||
|
||||
//
|
||||
// parses an attribute value pair (e.g., attr=value). allows
|
||||
// double-quotation marks surrounding value. input must be null
|
||||
// terminated, and will be updated to point past the attribute
|
||||
// value pair on success or the next whitespace character or comma
|
||||
// on failure.
|
||||
//
|
||||
static PRBool
|
||||
ParseAttrValue(const char *&input,
|
||||
const char *&ab,
|
||||
const char *&ae,
|
||||
const char *&vb,
|
||||
const char *&ve)
|
||||
{
|
||||
const char *p = PL_strpbrk(input, " \t=,");
|
||||
if (!p) {
|
||||
input += strlen(input);
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (*p == ',' || *p == ' ' || *p == '\t') {
|
||||
input = p;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// else, we located the equals sign...
|
||||
ab = input;
|
||||
ae = p;
|
||||
vb = p+1;
|
||||
|
||||
if (*vb == '"')
|
||||
++vb;
|
||||
|
||||
ve = PL_strpbrk(p+1, " \t,");
|
||||
if (!ve)
|
||||
ve = input + strlen(input);
|
||||
input = ve;
|
||||
|
||||
// only ignore trailing quote if there was a leading one
|
||||
if (ve > vb && *(vb-1) == '"' && *(ve-1) == '"')
|
||||
--ve;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsPrefetchListener <public>
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -247,6 +198,7 @@ nsPrefetchListener::OnStopRequest(nsIRequest *aRequest,
|
|||
nsPrefetchService::nsPrefetchService()
|
||||
: mQueueHead(nsnull)
|
||||
, mQueueTail(nsnull)
|
||||
, mStopCount(0)
|
||||
, mDisabled(PR_FALSE)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
|
@ -267,12 +219,6 @@ nsPrefetchService::Init()
|
|||
gPrefetchLog = PR_NewLogModule("nsPrefetch");
|
||||
#endif
|
||||
|
||||
static const eHTMLTags watchTags[] =
|
||||
{
|
||||
eHTMLTag_link,
|
||||
eHTMLTag_unknown
|
||||
};
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// Verify that "network.prefetch-next" preference is set to true. Skip
|
||||
|
@ -299,21 +245,6 @@ nsPrefetchService::Init()
|
|||
rv = observerServ->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Register as an observer for HTTP headers
|
||||
nsCOMPtr<nsINetModuleMgr> netModuleMgr(do_GetService(kNetModuleMgrCID, &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = netModuleMgr->RegisterModule(
|
||||
NS_NETWORK_MODULE_MANAGER_HTTP_RESPONSE_CONTRACTID, this);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Register as an observer for HTML "link" tags
|
||||
nsCOMPtr<nsIParserService> parserServ(do_GetService(kParserServiceCID, &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = parserServ->RegisterObserver(this, NS_LITERAL_STRING("text/html"), watchTags);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Register as an observer for the document loader
|
||||
nsCOMPtr<nsIWebProgress> progress(do_GetService(kDocLoaderServiceCID, &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -321,46 +252,6 @@ nsPrefetchService::Init()
|
|||
return progress->AddProgressListener(this, nsIWebProgress::NOTIFY_STATE_DOCUMENT);
|
||||
}
|
||||
|
||||
//
|
||||
// we register ourselves with the parser service category to ensure that
|
||||
// we'll be initialized before the first page is read.
|
||||
//
|
||||
NS_METHOD
|
||||
nsPrefetchService::RegisterProc(nsIComponentManager *aCompMgr,
|
||||
nsIFile *aPath,
|
||||
const char *registryLocation,
|
||||
const char *componentType,
|
||||
const nsModuleComponentInfo *info)
|
||||
{
|
||||
nsCOMPtr<nsICategoryManager> catman(
|
||||
do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
|
||||
if (catman) {
|
||||
nsXPIDLCString prevEntry;
|
||||
catman->AddCategoryEntry("parser-service-category",
|
||||
NS_PREFETCHSERVICE_CLASSNAME,
|
||||
NS_PREFETCHSERVICE_CONTRACTID,
|
||||
PR_TRUE, PR_TRUE,
|
||||
getter_Copies(prevEntry));
|
||||
}
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsPrefetchService::UnregisterProc(nsIComponentManager *aCompMgr,
|
||||
nsIFile *aPath,
|
||||
const char *registryLocation,
|
||||
const nsModuleComponentInfo *info)
|
||||
{
|
||||
nsCOMPtr<nsICategoryManager> catman(
|
||||
do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
|
||||
if (catman)
|
||||
catman->DeleteCategoryEntry("parser-service-category",
|
||||
NS_PREFETCHSERVICE_CONTRACTID,
|
||||
PR_TRUE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsPrefetchService::ProcessNextURI()
|
||||
{
|
||||
|
@ -453,49 +344,45 @@ nsPrefetchService::EmptyQueue()
|
|||
void
|
||||
nsPrefetchService::StartPrefetching()
|
||||
{
|
||||
LOG(("StartPrefetching\n"));
|
||||
//
|
||||
// at initialization time we might miss the first DOCUMENT START
|
||||
// notification, so we have to be careful to avoid letting our
|
||||
// stop count go negative.
|
||||
//
|
||||
if (mStopCount > 0)
|
||||
mStopCount--;
|
||||
|
||||
if (!mCurrentChannel)
|
||||
LOG(("StartPrefetching [stopcount=%d]\n", mStopCount));
|
||||
|
||||
// only start prefetching after we've received enough DOCUMENT
|
||||
// STOP notifications. we do this inorder to defer prefetching
|
||||
// until after all sub-frames have finished loading.
|
||||
if (mStopCount == 0 && !mCurrentChannel)
|
||||
ProcessNextURI();
|
||||
}
|
||||
|
||||
void
|
||||
nsPrefetchService::StopPrefetching()
|
||||
{
|
||||
LOG(("StopPrefetching\n"));
|
||||
mStopCount++;
|
||||
|
||||
LOG(("StopPrefetching [stopcount=%d]\n", mStopCount));
|
||||
|
||||
// only kill the prefetch queue if we've actually started prefetching.
|
||||
if (!mCurrentChannel)
|
||||
return;
|
||||
|
||||
if (mCurrentChannel) {
|
||||
mCurrentChannel->Cancel(NS_BINDING_ABORTED);
|
||||
mCurrentChannel = nsnull;
|
||||
}
|
||||
|
||||
EmptyQueue();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPrefetchService::GetDocumentCharset(nsISupports *aWebshell, nsACString &aCharset)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIDocCharset> docCharset(do_QueryInterface(aWebshell, &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsXPIDLString uCharset;
|
||||
rv = docCharset->GetCharset(getter_Copies(uCharset));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
CopyUCS2toASCII(uCharset, aCharset);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsPrefetchService::nsISupports
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS7(nsPrefetchService,
|
||||
NS_IMPL_ISUPPORTS4(nsPrefetchService,
|
||||
nsIPrefetchService,
|
||||
nsIHttpNotify,
|
||||
nsINetNotify,
|
||||
nsIElementObserver,
|
||||
nsIWebProgressListener,
|
||||
nsIObserver,
|
||||
nsISupportsWeakReference)
|
||||
|
@ -585,139 +472,6 @@ nsPrefetchService::PrefetchURI(nsIURI *aURI)
|
|||
return EnqueueURI(aURI);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsPrefetchService::nsIHttpNotify
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrefetchService::OnModifyRequest(nsIHttpChannel *aHttpChannel)
|
||||
{
|
||||
// ignored
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrefetchService::OnExamineResponse(nsIHttpChannel *aHttpChannel)
|
||||
{
|
||||
// look for Link: rel=next href=http://foo.com/blah
|
||||
|
||||
nsCAutoString linkVal;
|
||||
aHttpChannel->GetResponseHeader(NS_LITERAL_CSTRING("link"), linkVal);
|
||||
if (!linkVal.IsEmpty()) {
|
||||
LOG(("nsPrefetchService::OnExamineResponse [Link: %s]\n", linkVal.get()));
|
||||
|
||||
// verify rel=next or rel="next" and extract href value
|
||||
|
||||
const char *it = linkVal.get();
|
||||
const char *hrefBeg = nsnull;
|
||||
const char *hrefEnd = nsnull;
|
||||
PRBool haveRelNext = PR_FALSE;
|
||||
|
||||
for (; *it; ++it) {
|
||||
if (*it == ',') {
|
||||
haveRelNext = PR_FALSE;
|
||||
hrefBeg = nsnull;
|
||||
hrefEnd = nsnull;
|
||||
}
|
||||
// skip over whitespace
|
||||
if (*it != ' ' && *it != '\t' && !(haveRelNext && hrefBeg)) {
|
||||
// looking for attribute=value
|
||||
const char *attrBeg, *attrEnd, *valBeg, *valEnd;
|
||||
if (ParseAttrValue(it, attrBeg, attrEnd, valBeg, valEnd)) {
|
||||
if (!haveRelNext && !PL_strncasecmp(attrBeg, "rel", attrEnd - attrBeg))
|
||||
haveRelNext = PR_TRUE;
|
||||
else if (!hrefBeg && !PL_strncasecmp(attrBeg, "href", attrEnd - attrBeg)) {
|
||||
hrefBeg = valBeg;
|
||||
hrefEnd = valEnd;
|
||||
}
|
||||
}
|
||||
if (haveRelNext && hrefBeg) {
|
||||
// ok, we got something to prefetch...
|
||||
nsCOMPtr<nsIURI> uri, baseURI;
|
||||
aHttpChannel->GetURI(getter_AddRefs(baseURI));
|
||||
NS_NewURI(getter_AddRefs(uri),
|
||||
Substring(hrefBeg, hrefEnd),
|
||||
nsnull, baseURI);
|
||||
if (uri)
|
||||
PrefetchURI(uri);
|
||||
}
|
||||
continue; // do not increment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsPrefetchService::nsIElementObserver
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrefetchService::Notify(PRUint32 aDocumentID, eHTMLTags aTag,
|
||||
PRUint32 numOfAttributes, const PRUnichar* nameArray[],
|
||||
const PRUnichar* valueArray[])
|
||||
{
|
||||
// ignored
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrefetchService::Notify(PRUint32 aDocumentID, const PRUnichar* aTag,
|
||||
PRUint32 numOfAttributes, const PRUnichar* nameArray[],
|
||||
const PRUnichar *valueArray[])
|
||||
{
|
||||
// ignored
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrefetchService::Notify(nsISupports *aWebShell,
|
||||
nsISupports *aChannel,
|
||||
const PRUnichar *aTag,
|
||||
const nsStringArray *aKeys,
|
||||
const nsStringArray *aValues,
|
||||
const PRUint32 aFlags)
|
||||
{
|
||||
LOG(("nsPrefetchService::Notify\n"));
|
||||
|
||||
PRInt32 count = aKeys->Count();
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
PRBool relNext = PR_FALSE;
|
||||
|
||||
// check for <link rel=next href="http://blah">
|
||||
for (PRInt32 i=0; i<count; ++i) {
|
||||
nsString *key = aKeys->StringAt(i);
|
||||
if (!relNext && key->EqualsIgnoreCase("rel")) {
|
||||
if (aValues->StringAt(i)->EqualsIgnoreCase("next")) {
|
||||
relNext = PR_TRUE;
|
||||
if (uri)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!uri && key->EqualsIgnoreCase("href")) {
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aChannel));
|
||||
if (channel) {
|
||||
channel->GetURI(getter_AddRefs(baseURI));
|
||||
// need to pass document charset to necko...
|
||||
nsCAutoString docCharset;
|
||||
GetDocumentCharset(aWebShell, docCharset);
|
||||
NS_NewURI(getter_AddRefs(uri), *aValues->StringAt(i),
|
||||
docCharset.IsEmpty() ? nsnull : docCharset.get(),
|
||||
baseURI);
|
||||
if (uri && relNext)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (relNext && uri)
|
||||
PrefetchURI(uri);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsPrefetchService::nsIWebProgressListener
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -42,8 +42,6 @@
|
|||
#include "nsIGenericFactory.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIElementObserver.h"
|
||||
#include "nsIHttpNotify.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIURI.h"
|
||||
|
@ -59,8 +57,6 @@ class nsPrefetchNode;
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
class nsPrefetchService : public nsIPrefetchService
|
||||
, public nsIHttpNotify
|
||||
, public nsIElementObserver
|
||||
, public nsIWebProgressListener
|
||||
, public nsIObserver
|
||||
, public nsSupportsWeakReference
|
||||
|
@ -68,7 +64,6 @@ class nsPrefetchService : public nsIPrefetchService
|
|||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPREFETCHSERVICE
|
||||
NS_DECL_NSIHTTPNOTIFY
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
|
@ -78,31 +73,6 @@ public:
|
|||
nsresult Init();
|
||||
void ProcessNextURI();
|
||||
|
||||
// nsIElementObserver methods
|
||||
NS_IMETHOD Notify(PRUint32 aDocumentID, eHTMLTags aTag,
|
||||
PRUint32 numOfAttributes, const PRUnichar* nameArray[],
|
||||
const PRUnichar* valueArray[]);
|
||||
NS_IMETHOD Notify(PRUint32 aDocumentID, const PRUnichar* aTag,
|
||||
PRUint32 numOfAttributes, const PRUnichar* nameArray[],
|
||||
const PRUnichar* valueArray[]);
|
||||
NS_IMETHOD Notify(nsISupports* aWebShell,
|
||||
nsISupports* aChannel,
|
||||
const PRUnichar* aTag,
|
||||
const nsStringArray* aKeys,
|
||||
const nsStringArray* aValues,
|
||||
const PRUint32 aFlags);
|
||||
|
||||
// XPCOM component registration methods
|
||||
static NS_METHOD RegisterProc(nsIComponentManager *aCompMgr,
|
||||
nsIFile *aPath,
|
||||
const char *registryLocation,
|
||||
const char *componentType,
|
||||
const nsModuleComponentInfo *info);
|
||||
static NS_METHOD UnregisterProc(nsIComponentManager *aCompMgr,
|
||||
nsIFile *aPath,
|
||||
const char *registryLocation,
|
||||
const nsModuleComponentInfo *info);
|
||||
|
||||
private:
|
||||
|
||||
nsresult EnqueueURI(nsIURI *aURI);
|
||||
|
@ -110,11 +80,11 @@ private:
|
|||
void EmptyQueue();
|
||||
void StartPrefetching();
|
||||
void StopPrefetching();
|
||||
nsresult GetDocumentCharset(nsISupports *aWebshell, nsACString &);
|
||||
|
||||
nsPrefetchNode *mQueueHead;
|
||||
nsPrefetchNode *mQueueTail;
|
||||
nsCOMPtr<nsIChannel> mCurrentChannel;
|
||||
PRInt32 mStopCount;
|
||||
PRBool mDisabled;
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче