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

This commit is contained in:
bjarne@runitsoft.com 2009-03-30 11:31:16 -04:00
Родитель 2c0514ea69
Коммит 46b3066e19
3 изменённых файлов: 99 добавлений и 65 удалений

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

@ -102,8 +102,8 @@ class nsIBoxObject;
// IID for the nsIDocument interface
#define NS_IDOCUMENT_IID \
{ 0x62579239, 0xb619, 0x4bf2, \
{ 0x8d, 0x39, 0x0b, 0x73, 0xe8, 0x66, 0x3a, 0x85 } }
{ 0x46003091, 0x7f99, 0x420f, \
{ 0x95, 0xbc, 0x28, 0xd7, 0xd5, 0x01, 0x5a, 0x41 } }
// Flag for AddStyleSheet().
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
@ -1138,6 +1138,13 @@ public:
virtual void UnsuppressEventHandlingAndFireEvents(PRBool aFireEvents) = 0;
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"
@ -7550,3 +7551,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 its 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,18 @@ nsPreloadURIs::PreloadURIs(const nsAutoTArray<nsSpeculativeScriptThread::Prefetc
alreadyPreloaded.Put(spec, PR_TRUE);
doc->ScriptLoader()->PreloadURI(uri, pe.charset, pe.elementType);
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,84 +578,73 @@ nsSpeculativeScriptThread::ProcessToken(CToken *aToken)
nsAutoString src;
nsAutoString elementType;
nsAutoString charset;
PrefetchType ptype = SCRIPT;
nsAutoString href;
nsAutoString rel;
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");
case eHTMLTag_link:
ptype = STYLESHEET;
break;
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:
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;
for (; i < attrs; ++i) {
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) {
// 1. loop over all attributes to extract relevant info
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 (attr->GetKey().EqualsLiteral("rel")) {
rel.Assign(attr->GetValue());
} else if (attr->GetKey().EqualsLiteral("href")) {
href.Assign(attr->GetValue());
} else if (attr->GetKey().EqualsLiteral("src")) {
src.Assign(attr->GetValue());
} else if (attr->GetKey().EqualsLiteral("charset")) {
charset.Assign(attr->GetValue());
} else if (attr->GetKey().EqualsLiteral("type")) {
elementType.Assign(attr->GetValue());
}
IF_FREE(attr, &mTokenAllocator);
}
// 2. ensure we have the right kind if it's a link-element
if (ptype == STYLESHEET) {
if (rel.EqualsLiteral("stylesheet")) {
src = href; // src is the important variable below
} else {
src.Truncate(); // clear src if wrong kind of link
}
}
// 3. add to list if we have a valid src
if (!src.IsEmpty()) {
AddToPrefetchList(src, charset, elementType, ptype);
}
break;
default:
break;
} else {
// Irrelevant tag, but pop and free all its attributes in any case
for (; i < attrs ; ++i) {
CToken *attr = mTokenizer->PopToken();
IF_FREE(attr, &mTokenAllocator);
}
}
for (; i < attrs; ++i) {
CToken *attr = mTokenizer->PopToken();
if (!attr) {
break;
}
NS_ASSERTION(attr->GetTokenType() == eToken_attribute, "Weird token");
IF_FREE(attr, &mTokenAllocator);
}
break;
}