Bug 534293 - Make speculative loads initiated by the HTML5 parser take <base> into account. r=jst, a=blocking2.0-betaN.

--HG--
extra : rebase_source : 71cd318e90c56cf8f718fb4a4572d17f3ba1a9f3
This commit is contained in:
Henri Sivonen 2010-07-26 14:18:43 +03:00
parent 02a35de34e
commit e19b8f27e1
5 changed files with 50 additions and 1 deletions

View File

@ -57,6 +57,9 @@ void
nsHtml5SpeculativeLoad::Perform(nsHtml5TreeOpExecutor* aExecutor)
{
switch (mOpCode) {
case eSpeculativeLoadBase:
aExecutor->SetSpeculationBase(mUrl);
break;
case eSpeculativeLoadImage:
aExecutor->PreloadImage(mUrl);
break;

View File

@ -46,6 +46,7 @@ enum eHtml5SpeculativeLoad {
#ifdef DEBUG
eSpeculativeLoadUninitialized,
#endif
eSpeculativeLoadBase,
eSpeculativeLoadImage,
eSpeculativeLoadScript,
eSpeculativeLoadStyle,
@ -57,6 +58,13 @@ class nsHtml5SpeculativeLoad {
nsHtml5SpeculativeLoad();
~nsHtml5SpeculativeLoad();
inline void InitBase(const nsAString& aUrl) {
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadBase;
mUrl.Assign(aUrl);
}
inline void InitImage(const nsAString& aUrl) {
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");

View File

@ -149,6 +149,14 @@ nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5Htm
if (url) {
mSpeculativeLoadQueue.AppendElement()->InitManifest(*url);
}
} else if (nsHtml5Atoms::base == aName &&
(mode == NS_HTML5TREE_BUILDER_IN_HEAD ||
mode == NS_HTML5TREE_BUILDER_AFTER_HEAD)) {
nsString* url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
if (url) {
mSpeculativeLoadQueue.AppendElement()->InitBase(*url);
}
}
break;
case kNameSpaceID_SVG:

View File

@ -830,7 +830,18 @@ nsHtml5TreeOpExecutor::InitializeDocWriteParserState(nsAHtml5TreeBuilderState* a
already_AddRefed<nsIURI>
nsHtml5TreeOpExecutor::ConvertIfNotPreloadedYet(const nsAString& aURL)
{
nsIURI* base = mDocument->GetDocBaseURI();
// The URL of the document without <base>
nsIURI* documentURI = mDocument->GetDocumentURI();
// The URL of the document with non-speculative <base>
nsIURI* documentBaseURI = mDocument->GetDocBaseURI();
// If the two above are different, use documentBaseURI. If they are the
// same, the document object isn't aware of a <base>, so attempt to use the
// mSpeculationBaseURI or, failing, that, documentURI.
nsIURI* base = (documentURI == documentBaseURI) ?
(mSpeculationBaseURI ?
mSpeculationBaseURI.get() : documentURI)
: documentBaseURI;
const nsCString& charset = mDocument->GetDocumentCharacterSet();
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, charset.get(), base);
@ -882,6 +893,21 @@ nsHtml5TreeOpExecutor::PreloadImage(const nsAString& aURL)
mDocument->MaybePreLoadImage(uri);
}
void
nsHtml5TreeOpExecutor::SetSpeculationBase(const nsAString& aURL)
{
if (mSpeculationBaseURI) {
// the first one wins
return;
}
const nsCString& charset = mDocument->GetDocumentCharacterSet();
nsresult rv = NS_NewURI(getter_AddRefs(mSpeculationBaseURI), aURL,
charset.get(), mDocument->GetDocumentURI());
if (NS_FAILED(rv)) {
NS_WARNING("Failed to create a URI");
}
}
#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
PRUint32 nsHtml5TreeOpExecutor::sAppendBatchMaxSize = 0;
PRUint32 nsHtml5TreeOpExecutor::sAppendBatchSlotsExamined = 0;

View File

@ -109,6 +109,8 @@ class nsHtml5TreeOpExecutor : public nsContentSink,
*/
nsCStringHashSet mPreloadedURLs;
nsCOMPtr<nsIURI> mSpeculationBaseURI;
/**
* Whether the parser has started
*/
@ -395,6 +397,8 @@ class nsHtml5TreeOpExecutor : public nsContentSink,
void PreloadImage(const nsAString& aURL);
void SetSpeculationBase(const nsAString& aURL);
private:
nsHtml5Tokenizer* GetTokenizer();