Bug 457809 and bug 457810 - Speculatively load images and stylesheets (respectively). r=mrbkap, sr=bz

This commit is contained in:
bjarne@runitsoft.com 2009-03-24 12:52:00 -04:00
Родитель 485447dbe3
Коммит 28637b1d1c
3 изменённых файлов: 85 добавлений и 54 удалений

Просмотреть файл

@ -1131,6 +1131,13 @@ public:
}
PRUint32 EventHandlingSuppressed() { return mEventsSuppressed; }
/**
* Called by nsParser to preload images. Can be removed and code moved
* to nsPreloadURIs::PreloadURIs() in file nsParser.cpp whenever the
* parser-module is linked with gklayout-module.
*/
virtual void PreLoadImage(nsIURI* uri);
protected:
~nsIDocument()
{

Просмотреть файл

@ -168,6 +168,7 @@ static NS_DEFINE_CID(kDOMEventGroupCID, NS_DOMEVENTGROUP_CID);
#include "nsIPropertyBag2.h"
#include "nsFrameLoader.h"
#include "imgIRequest.h"
#include "mozAutoDocUpdate.h"
@ -7517,3 +7518,15 @@ nsDocument::UnsuppressEventHandlingAndFireEvents(PRBool aFireEvents)
}
}
void
nsIDocument::PreLoadImage(nsIURI* uri)
{
nsCOMPtr<imgIRequest> request;
nsContentUtils::LoadImage(uri,
this,
NodePrincipal(),
GetDocumentURI(), // should be ok for referrer
nsnull, // no observer
nsIRequest::LOAD_NORMAL,
getter_AddRefs(request));
}

Просмотреть файл

@ -71,6 +71,9 @@
#include "nsDataHashtable.h"
#include "nsIThreadPool.h"
#include "nsXPCOMCIDInternal.h"
#include "nsICSSStyleSheet.h"
#include "nsICSSLoaderObserver.h"
#include "nsICSSLoader.h"
#ifdef MOZ_VIEW_SOURCE
#include "nsViewSourceHTML.h"
@ -221,7 +224,7 @@ public:
nsresult StartParsing(nsParser *aParser);
void StopParsing(PRBool aFromDocWrite);
enum PrefetchType { SCRIPT, STYLESHEET, IMAGE };
enum PrefetchType { NONE, SCRIPT, STYLESHEET, IMAGE };
struct PrefetchEntry {
PrefetchType type;
nsString uri;
@ -291,6 +294,21 @@ private:
PRBool mTerminated;
};
/**
* Used if we need to pass an nsICSSLoaderObserver as parameter,
* but don't really need it's services
*/
class nsDummyCSSLoaderObserver : public nsICSSLoaderObserver {
public:
NS_IMETHOD
StyleSheetLoaded(nsICSSStyleSheet* aSheet, PRBool aWasAlternate, nsresult aStatus) {
return NS_OK;
}
NS_DECL_ISUPPORTS
};
NS_IMPL_ISUPPORTS1(nsDummyCSSLoaderObserver, nsICSSLoaderObserver)
class nsPreloadURIs : public nsIRunnable {
public:
nsPreloadURIs(nsAutoTArray<nsSpeculativeScriptThread::PrefetchEntry, 5> &aURIs,
@ -343,10 +361,6 @@ nsPreloadURIs::PreloadURIs(const nsAutoTArray<nsSpeculativeScriptThread::Prefetc
aScriptThread->GetPreloadedURIs();
for (PRUint32 i = 0, e = aURIs.Length(); i < e; ++i) {
const nsSpeculativeScriptThread::PrefetchEntry &pe = aURIs[i];
if (pe.type != nsSpeculativeScriptThread::SCRIPT) {
continue;
}
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_NewURI(getter_AddRefs(uri), pe.uri, charset.get(), base);
if (NS_FAILED(rv)) {
@ -364,7 +378,19 @@ nsPreloadURIs::PreloadURIs(const nsAutoTArray<nsSpeculativeScriptThread::Prefetc
alreadyPreloaded.Put(spec, PR_TRUE);
nsCAutoString aReferrer;
switch(pe.type) {
case nsSpeculativeScriptThread::SCRIPT:
doc->ScriptLoader()->PreloadURI(uri, pe.charset, pe.elementType);
break;
case nsSpeculativeScriptThread::IMAGE:
doc->PreLoadImage(uri);
break;
case nsSpeculativeScriptThread::STYLESHEET:
nsCOMPtr<nsICSSLoaderObserver> obs = new nsDummyCSSLoaderObserver();
doc->CSSLoader()->LoadSheet(uri, doc->NodePrincipal(), obs);
break;
}
}
}
@ -553,57 +579,45 @@ nsSpeculativeScriptThread::ProcessToken(CToken *aToken)
nsAutoString src;
nsAutoString elementType;
nsAutoString charset;
PrefetchType ptype = SCRIPT;
PrefetchType ptype = NONE;
switch (tag) {
#if 0 // TODO Support stylesheet and image preloading.
case eHTMLTag_link: {
// If this is a <link rel=stylesheet> find the src.
PRBool isRelStylesheet = PR_FALSE;
for (; i < attrs; ++i) {
CAttributeToken *attr = static_cast<CAttributeToken *>(mTokenizer->PopToken());
NS_ASSERTION(attr->GetTokenType() == eToken_attribute, "Weird token");
if (attr->GetKey().EqualsLiteral("rel")) {
if (!attr->GetValue().EqualsLiteral("stylesheet")) {
IF_FREE(attr, &mTokenAllocator);
break;
}
isRelStylesheet = PR_TRUE;
} else if (attr->GetKey().EqualsLiteral("src")) {
src.Assign(attr->GetValue());
if (isRelStylesheet) {
IF_FREE(attr, &mTokenAllocator);
break;
}
}
IF_FREE(attr, &mTokenAllocator);
}
if (isRelStylesheet && !src.IsEmpty()) {
AddToPrefetchList(src, STYLESHEET);
}
break;
}
case eHTMLTag_style:
case eHTMLTag_link:
ptype = STYLESHEET;
/* FALL THROUGH */
case eHTMLTag_img:
if (tag == eHTMLTag_img)
ptype = IMAGE;
/* FALL THROUGH */
#endif
case eHTMLTag_script:
if (tag == eHTMLTag_script)
ptype = SCRIPT;
break;
case eHTMLTag_img:
ptype = IMAGE;
break;
case eHTMLTag_script:
ptype = SCRIPT;
break;
default:
break;
}
// We currently handle the following element/attribute combos :
// <link rel="stylesheet" href= charset= type>
// <img src= >
// <script src= charset= type=>
if (ptype != NONE) {
// Extract attributes
for (; i < attrs; ++i) {
CAttributeToken *attr = static_cast<CAttributeToken *>(mTokenizer->PopToken());
NS_ASSERTION(attr->GetTokenType() == eToken_attribute, "Weird token");
if (attr->GetKey().EqualsLiteral("src")) {
if (ptype == STYLESHEET && attr->GetKey().EqualsLiteral("rel")) {
// early break from loop if this is not a stylesheet
if (!attr->GetValue().EqualsLiteral("stylesheet")) {
ptype = NONE;
IF_FREE(attr, &mTokenAllocator);
break;
}
} else if (ptype == STYLESHEET && attr->GetKey().EqualsLiteral("href")) {
src.Assign(attr->GetValue());
} else if (ptype != STYLESHEET && attr->GetKey().EqualsLiteral("src")) {
src.Assign(attr->GetValue());
} else if (attr->GetKey().EqualsLiteral("charset")) {
charset.Assign(attr->GetValue());
@ -613,13 +627,10 @@ nsSpeculativeScriptThread::ProcessToken(CToken *aToken)
IF_FREE(attr, &mTokenAllocator);
}
// Add to list if we found the src
if (!src.IsEmpty()) {
AddToPrefetchList(src, charset, elementType, ptype);
}
break;
default:
break;
}
for (; i < attrs; ++i) {