зеркало из https://github.com/mozilla/gecko-dev.git
Bug 457809 - Speculatively load images from preloading. r=mrbkap, sr=bzbarsky
This commit is contained in:
Родитель
909cc48b7b
Коммит
136ecf84de
|
@ -81,6 +81,7 @@ class nsIURI;
|
|||
class imgIDecoderObserver;
|
||||
class imgIRequest;
|
||||
class imgILoader;
|
||||
class imgICache;
|
||||
class nsIPrefBranch;
|
||||
class nsIImage;
|
||||
class nsIImageLoadingContent;
|
||||
|
@ -647,6 +648,11 @@ public:
|
|||
PRInt32 aLoadFlags,
|
||||
imgIRequest** aRequest);
|
||||
|
||||
/**
|
||||
* Returns whether the given URI is in the image cache.
|
||||
*/
|
||||
static PRBool IsImageInCache(nsIURI* aURI);
|
||||
|
||||
/**
|
||||
* Method to get an nsIImage from an image loading content
|
||||
*
|
||||
|
@ -1504,6 +1510,7 @@ private:
|
|||
static nsIPref *sPref;
|
||||
|
||||
static imgILoader* sImgLoader;
|
||||
static imgICache* sImgCache;
|
||||
|
||||
static nsIConsoleService* sConsoleService;
|
||||
|
||||
|
|
|
@ -105,8 +105,8 @@ class nsIBoxObject;
|
|||
|
||||
// IID for the nsIDocument interface
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{0x2c155ed0, 0x3302, 0x4cff, \
|
||||
{0x9d, 0xb3, 0xed, 0x0c, 0xcd, 0xfc, 0x50, 0x06 } }
|
||||
{ 0x46003091, 0x7f99, 0x420f, \
|
||||
{ 0x95, 0xbc, 0x28, 0xd7, 0xd5, 0x01, 0x5a, 0x41 } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
|
@ -1148,6 +1148,14 @@ public:
|
|||
PRUint32 EventHandlingSuppressed() const { return mEventsSuppressed; }
|
||||
|
||||
PRBool IsDNSPrefetchAllowed() const { return mAllowDNSPrefetch; }
|
||||
|
||||
/**
|
||||
* 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 MaybePreLoadImage(nsIURI* uri) = 0;
|
||||
|
||||
protected:
|
||||
~nsIDocument()
|
||||
{
|
||||
|
|
|
@ -179,6 +179,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
|
|||
#include "nsIConsoleService.h"
|
||||
|
||||
#include "mozAutoDocUpdate.h"
|
||||
#include "imgICache.h"
|
||||
#include "jsinterp.h"
|
||||
|
||||
const char kLoadAsData[] = "loadAsData";
|
||||
|
@ -200,6 +201,7 @@ nsIXTFService *nsContentUtils::sXTFService = nsnull;
|
|||
nsIPrefBranch *nsContentUtils::sPrefBranch = nsnull;
|
||||
nsIPref *nsContentUtils::sPref = nsnull;
|
||||
imgILoader *nsContentUtils::sImgLoader;
|
||||
imgICache *nsContentUtils::sImgCache;
|
||||
nsIConsoleService *nsContentUtils::sConsoleService;
|
||||
nsDataHashtable<nsISupportsHashKey, EventNameMapping>* nsContentUtils::sEventTable = nsnull;
|
||||
nsIStringBundleService *nsContentUtils::sStringBundleService;
|
||||
|
@ -330,6 +332,10 @@ nsContentUtils::Init()
|
|||
if (NS_FAILED(rv)) {
|
||||
// no image loading for us. Oh, well.
|
||||
sImgLoader = nsnull;
|
||||
sImgCache = nsnull;
|
||||
} else {
|
||||
if (NS_FAILED(CallGetService("@mozilla.org/image/cache;1", &sImgCache )))
|
||||
sImgCache = nsnull;
|
||||
}
|
||||
|
||||
sPtrsToPtrsToRelease = new nsTArray<nsISupports**>();
|
||||
|
@ -893,6 +899,7 @@ nsContentUtils::Shutdown()
|
|||
NS_IF_RELEASE(sXTFService);
|
||||
#endif
|
||||
NS_IF_RELEASE(sImgLoader);
|
||||
NS_IF_RELEASE(sImgCache);
|
||||
NS_IF_RELEASE(sPrefBranch);
|
||||
NS_IF_RELEASE(sPref);
|
||||
#ifdef IBMBIDI
|
||||
|
@ -2383,6 +2390,19 @@ nsContentUtils::CanLoadImage(nsIURI* aURI, nsISupports* aContext,
|
|||
return NS_FAILED(rv) ? PR_FALSE : NS_CP_ACCEPTED(decision);
|
||||
}
|
||||
|
||||
// static
|
||||
PRBool
|
||||
nsContentUtils::IsImageInCache(nsIURI* aURI)
|
||||
{
|
||||
if (!sImgCache) return PR_FALSE;
|
||||
|
||||
// If something unexpected happened we return false, otherwise if props
|
||||
// is set, the image is cached and we return true
|
||||
nsCOMPtr<nsIProperties> props;
|
||||
nsresult rv = sImgCache->FindEntryProperties(aURI, getter_AddRefs(props));
|
||||
return (NS_SUCCEEDED(rv) && props);
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
|
||||
|
|
|
@ -1780,6 +1780,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDocument)
|
|||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mStyleSheets)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mCatalogSheets)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mVisitednessChangedURIs)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mPreloadingImages)
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
// Traverse animation components
|
||||
|
@ -1824,6 +1825,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
|
|||
|
||||
tmp->mParentDocument = nsnull;
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mPreloadingImages)
|
||||
|
||||
// nsDocument has a pretty complex destructor, so we're going to
|
||||
// assume that *most* cycles you actually want to break somewhere
|
||||
// else, and not unlink an awful lot here.
|
||||
|
@ -3863,6 +3866,9 @@ nsDocument::DispatchContentLoadedEvents()
|
|||
// If you add early returns from this method, make sure you're
|
||||
// calling UnblockOnload properly.
|
||||
|
||||
// Unpin references to preloaded images
|
||||
mPreloadingImages.Clear();
|
||||
|
||||
// Fire a DOM event notifying listeners that this document has been
|
||||
// loaded (excluding images and other loads initiated by this
|
||||
// document).
|
||||
|
@ -7485,6 +7491,34 @@ FireOrClearDelayedEvents(nsTArray<nsCOMPtr<nsIDocument> >& aDocuments,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::MaybePreLoadImage(nsIURI* uri)
|
||||
{
|
||||
// Early exit if the img is already present in the img-cache
|
||||
// which indicates that the "real" load has already started and
|
||||
// that we shouldn't preload it.
|
||||
if (nsContentUtils::IsImageInCache(uri)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Image not in cache - trigger preload
|
||||
nsCOMPtr<imgIRequest> request;
|
||||
nsresult rv =
|
||||
nsContentUtils::LoadImage(uri,
|
||||
this,
|
||||
NodePrincipal(),
|
||||
mDocumentURI, // uri of document used as referrer
|
||||
nsnull, // no observer
|
||||
nsIRequest::LOAD_NORMAL,
|
||||
getter_AddRefs(request));
|
||||
|
||||
// Pin image-reference to avoid evicting it from the img-cache before
|
||||
// the "real" load occurs. Unpinned in DispatchContentLoadedEvents and
|
||||
// unlink
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mPreloadingImages.AppendObject(request);
|
||||
}
|
||||
}
|
||||
class nsDelayedEventDispatcher : public nsRunnable
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -116,6 +116,7 @@
|
|||
#include "nsIProgressEventSink.h"
|
||||
#include "nsISecurityEventSink.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "imgIRequest.h"
|
||||
|
||||
#define XML_DECLARATION_BITS_DECLARATION_EXISTS (1 << 0)
|
||||
#define XML_DECLARATION_BITS_ENCODING_EXISTS (1 << 1)
|
||||
|
@ -1006,6 +1007,8 @@ public:
|
|||
void MaybeInitializeFinalizeFrameLoaders();
|
||||
|
||||
void MaybeEndOutermostXBLUpdate();
|
||||
|
||||
virtual void MaybePreLoadImage(nsIURI* uri);
|
||||
protected:
|
||||
|
||||
void RegisterNamedItems(nsIContent *aContent);
|
||||
|
@ -1264,6 +1267,9 @@ private:
|
|||
|
||||
nsExternalResourceMap mExternalResourceMap;
|
||||
|
||||
// All images in process of being preloaded
|
||||
nsCOMArray<imgIRequest> mPreloadingImages;
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
nsAutoPtr<nsSMILAnimationController> mAnimationController;
|
||||
#endif // MOZ_SMIL
|
||||
|
|
|
@ -382,6 +382,9 @@ nsPreloadURIs::PreloadURIs(const nsAutoTArray<nsSpeculativeScriptThread::Prefetc
|
|||
case nsSpeculativeScriptThread::SCRIPT:
|
||||
doc->ScriptLoader()->PreloadURI(uri, pe.charset, pe.elementType);
|
||||
break;
|
||||
case nsSpeculativeScriptThread::IMAGE:
|
||||
doc->MaybePreLoadImage(uri);
|
||||
break;
|
||||
case nsSpeculativeScriptThread::STYLESHEET: {
|
||||
nsCOMPtr<nsICSSLoaderObserver> obs = new nsDummyCSSLoaderObserver();
|
||||
doc->CSSLoader()->LoadSheet(uri, doc->NodePrincipal(),
|
||||
|
@ -389,9 +392,6 @@ nsPreloadURIs::PreloadURIs(const nsAutoTArray<nsSpeculativeScriptThread::Prefetc
|
|||
obs);
|
||||
break;
|
||||
}
|
||||
case nsSpeculativeScriptThread::IMAGE:
|
||||
NS_NOTREACHED("We don't scan these yet");
|
||||
break;
|
||||
case nsSpeculativeScriptThread::NONE:
|
||||
NS_NOTREACHED("Uninitialized preload entry?");
|
||||
break;
|
||||
|
@ -601,6 +601,10 @@ nsSpeculativeScriptThread::ProcessToken(CToken *aToken)
|
|||
ptype = STYLESHEET;
|
||||
break;
|
||||
|
||||
case eHTMLTag_img:
|
||||
ptype = IMAGE;
|
||||
break;
|
||||
|
||||
case eHTMLTag_script:
|
||||
ptype = SCRIPT;
|
||||
break;
|
||||
|
|
Загрузка…
Ссылка в новой задаче