зеркало из https://github.com/mozilla/gecko-dev.git
Bug 15146. Brutal sharing, Phase III. Turn on protoype, script, and style sheet caching. r=hyatt
This commit is contained in:
Родитель
649ac66265
Коммит
676716c335
|
@ -27,6 +27,7 @@
|
|||
#define nsIXULPrototypeCache_h__
|
||||
|
||||
#include "nsISupports.h"
|
||||
class nsICSSStyleSheet;
|
||||
class nsIURI;
|
||||
class nsIXULPrototypeDocument;
|
||||
|
||||
|
@ -40,8 +41,20 @@ class nsIXULPrototypeCache : public nsISupports
|
|||
public:
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IXULPROTOTYPECACHE_IID);
|
||||
|
||||
NS_IMETHOD Get(nsIURI* aURI, nsIXULPrototypeDocument** _result) = 0;
|
||||
NS_IMETHOD Put(nsIURI* aURI, nsIXULPrototypeDocument* aDocument) = 0;
|
||||
NS_IMETHOD GetPrototype(nsIURI* aURI, nsIXULPrototypeDocument** _result) = 0;
|
||||
NS_IMETHOD PutPrototype(nsIXULPrototypeDocument* aDocument) = 0;
|
||||
|
||||
NS_IMETHOD GetStyleSheet(nsIURI* aURI, nsICSSStyleSheet** _result) = 0;
|
||||
NS_IMETHOD PutStyleSheet(nsICSSStyleSheet* aStyleSheet) = 0;
|
||||
|
||||
NS_IMETHOD GetScript(nsIURI* aURI, nsString& aScript, const char** aVersion) = 0;
|
||||
NS_IMETHOD PutScript(nsIURI* aURI, const nsString& aScript, const char* aVersion) = 0;
|
||||
|
||||
/**
|
||||
* Flush the cache; remove all XUL prototype documents, style
|
||||
* sheets, and scripts.
|
||||
*/
|
||||
NS_IMETHOD Flush() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
#include "nsIXULDocument.h"
|
||||
#include "nsIXULKeyListener.h"
|
||||
#include "nsIXULPrototypeDocument.h"
|
||||
#include "nsIXULPrototypeCache.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsNeckoUtil.h"
|
||||
#include "nsRDFCID.h"
|
||||
|
@ -102,6 +103,8 @@ static const char kXULNameSpaceURI[] = XUL_NAMESPACE_URI;
|
|||
static NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID);
|
||||
static NS_DEFINE_CID(kCSSParserCID, NS_CSSPARSER_CID);
|
||||
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
|
||||
static NS_DEFINE_CID(kXULContentUtilsCID, NS_XULCONTENTUTILS_CID);
|
||||
static NS_DEFINE_CID(kXULPrototypeCacheCID, NS_XULPROTOTYPECACHE_CID);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
|
@ -142,6 +145,8 @@ protected:
|
|||
// pseudo-constants
|
||||
static nsrefcnt gRefCnt;
|
||||
static nsINameSpaceManager* gNameSpaceManager;
|
||||
static nsIXULContentUtils* gXULUtils;
|
||||
static nsIXULPrototypeCache* gXULCache;
|
||||
|
||||
static nsIAtom* kClassAtom;
|
||||
static nsIAtom* kIdAtom;
|
||||
|
@ -240,6 +245,8 @@ protected:
|
|||
|
||||
nsrefcnt XULContentSinkImpl::gRefCnt;
|
||||
nsINameSpaceManager* XULContentSinkImpl::gNameSpaceManager;
|
||||
nsIXULContentUtils* XULContentSinkImpl::gXULUtils;
|
||||
nsIXULPrototypeCache* XULContentSinkImpl::gXULCache;
|
||||
|
||||
nsIAtom* XULContentSinkImpl::kClassAtom;
|
||||
nsIAtom* XULContentSinkImpl::kIdAtom;
|
||||
|
@ -377,6 +384,15 @@ XULContentSinkImpl::XULContentSinkImpl(nsresult& rv)
|
|||
kScriptAtom = NS_NewAtom("script");
|
||||
kStyleAtom = NS_NewAtom("style");
|
||||
kTemplateAtom = NS_NewAtom("template");
|
||||
|
||||
rv = nsServiceManager::GetService(kXULContentUtilsCID,
|
||||
NS_GET_IID(nsIXULContentUtils),
|
||||
(nsISupports**) &gXULUtils);
|
||||
if (NS_FAILED(rv)) return;
|
||||
|
||||
rv = nsServiceManager::GetService(kXULPrototypeCacheCID,
|
||||
NS_GET_IID(nsIXULPrototypeCache),
|
||||
(nsISupports**) &gXULCache);
|
||||
}
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
|
@ -390,11 +406,6 @@ XULContentSinkImpl::XULContentSinkImpl(nsresult& rv)
|
|||
|
||||
XULContentSinkImpl::~XULContentSinkImpl()
|
||||
{
|
||||
#ifdef DEBUG_REFS
|
||||
--gInstanceCount;
|
||||
fprintf(stdout, "%d - RDF: XULContentSinkImpl\n", gInstanceCount);
|
||||
#endif
|
||||
|
||||
NS_IF_RELEASE(mParser); // XXX should've been released by now, unless error.
|
||||
|
||||
{
|
||||
|
@ -475,6 +486,16 @@ XULContentSinkImpl::~XULContentSinkImpl()
|
|||
NS_IF_RELEASE(kScriptAtom);
|
||||
NS_IF_RELEASE(kStyleAtom);
|
||||
NS_IF_RELEASE(kTemplateAtom);
|
||||
|
||||
if (gXULUtils) {
|
||||
nsServiceManager::ReleaseService(kXULContentUtilsCID, gXULUtils);
|
||||
gXULUtils = nsnull;
|
||||
}
|
||||
|
||||
if (gXULCache) {
|
||||
nsServiceManager::ReleaseService(kXULPrototypeCacheCID, gXULCache);
|
||||
gXULCache = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -821,7 +842,7 @@ XULContentSinkImpl::ProcessStyleLink(nsIContent* aElement,
|
|||
{
|
||||
static const char kCSSType[] = "text/css";
|
||||
|
||||
nsresult result = NS_OK;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (aAlternate) { // if alternate, does it have title?
|
||||
if (0 == aTitle.Length()) { // alternates must have title
|
||||
|
@ -835,11 +856,35 @@ XULContentSinkImpl::ProcessStyleLink(nsIContent* aElement,
|
|||
|
||||
if ((0 == mimeType.Length()) || mimeType.EqualsIgnoreCase(kCSSType)) {
|
||||
nsCOMPtr<nsIURI> url;
|
||||
result = NS_NewURI(getter_AddRefs(url), aHref, mDocumentURL);
|
||||
if (NS_OK != result) {
|
||||
rv = NS_NewURI(getter_AddRefs(url), aHref, mDocumentURL);
|
||||
if (NS_OK != rv) {
|
||||
return NS_OK; // The URL is bad, move along, don't propagate the error (for now)
|
||||
}
|
||||
|
||||
// Add the style sheet reference to the prototype
|
||||
mPrototype->AddStyleSheetReference(url);
|
||||
|
||||
// See if the style sheet is in the style sheet cache. If so,
|
||||
// just use it.
|
||||
if (gXULUtils->UseXULCache()) {
|
||||
nsCOMPtr<nsICSSStyleSheet> sheet;
|
||||
rv = gXULCache->GetStyleSheet(url, getter_AddRefs(sheet));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && sheet) {
|
||||
nsCOMPtr<nsICSSStyleSheet> newsheet;
|
||||
rv = sheet->Clone(*getter_AddRefs(newsheet));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && newsheet) {
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
|
||||
if (doc) {
|
||||
doc->AddStyleSheet(newsheet);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Nope, we need to load it asynchronously
|
||||
PRBool blockParser = PR_FALSE;
|
||||
if (! aAlternate) {
|
||||
if (0 < aTitle.Length()) { // possibly preferred sheet
|
||||
|
@ -862,16 +907,16 @@ XULContentSinkImpl::ProcessStyleLink(nsIContent* aElement,
|
|||
// sheet in a fairly random location if we're loading an
|
||||
// overlay. Should we just use a Very Large Number?
|
||||
PRBool doneLoading;
|
||||
result = mCSSLoader->LoadStyleLink(aElement, url, aTitle, aMedia, kNameSpaceID_Unknown,
|
||||
mStyleSheetCount++,
|
||||
((blockParser) ? mParser : nsnull),
|
||||
doneLoading);
|
||||
if (NS_SUCCEEDED(result) && blockParser && (! doneLoading)) {
|
||||
result = NS_ERROR_HTMLPARSER_BLOCK;
|
||||
rv = mCSSLoader->LoadStyleLink(aElement, url, aTitle, aMedia, kNameSpaceID_Unknown,
|
||||
mStyleSheetCount++,
|
||||
((blockParser) ? mParser : nsnull),
|
||||
doneLoading);
|
||||
if (NS_SUCCEEDED(rv) && blockParser && (! doneLoading)) {
|
||||
rv = NS_ERROR_HTMLPARSER_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "nsIChromeRegistry.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsICSSStyleSheet.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
|
@ -196,7 +197,7 @@ nsINameSpaceManager* nsXULDocument::gNameSpaceManager;
|
|||
PRInt32 nsXULDocument::kNameSpaceID_XUL;
|
||||
|
||||
nsIXULContentUtils* nsXULDocument::gXULUtils;
|
||||
nsIXULPrototypeCache* nsXULDocument::gXULPrototypeCache;
|
||||
nsIXULPrototypeCache* nsXULDocument::gXULCache;
|
||||
|
||||
PRLogModuleInfo* nsXULDocument::gXULLog;
|
||||
|
||||
|
@ -330,9 +331,9 @@ nsXULDocument::~nsXULDocument()
|
|||
gXULUtils = nsnull;
|
||||
}
|
||||
|
||||
if (gXULPrototypeCache) {
|
||||
nsServiceManager::ReleaseService(kXULPrototypeCacheCID, gXULPrototypeCache);
|
||||
gXULPrototypeCache = nsnull;
|
||||
if (gXULCache) {
|
||||
nsServiceManager::ReleaseService(kXULPrototypeCacheCID, gXULCache);
|
||||
gXULCache = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -518,6 +519,10 @@ nsXULDocument::StartDocumentLoad(const char* aCommand,
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
#if defined(DEBUG_waterson) || defined(DEBUG_hyatt)
|
||||
mLoadStart = PR_Now();
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIURI> url;
|
||||
rv = aChannel->GetURI(getter_AddRefs(url));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -866,6 +871,15 @@ nsXULDocument::AddStyleSheet(nsIStyleSheet* aSheet)
|
|||
else {
|
||||
mStyleSheets.AppendElement(aSheet);
|
||||
}
|
||||
|
||||
// Put the style sheet into the XUL cache if the XUL cache is
|
||||
// actually enabled and the document is chrome.
|
||||
if (gXULUtils->UseXULCache() && IsChromeURI(mDocumentURL)) {
|
||||
nsCOMPtr<nsICSSStyleSheet> css = do_QueryInterface(aSheet);
|
||||
if (css) {
|
||||
gXULCache->PutStyleSheet(css);
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_ADDREF(aSheet);
|
||||
|
||||
|
@ -902,6 +916,16 @@ NS_IMETHODIMP
|
|||
nsXULDocument::InsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex, PRBool aNotify)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aSheet, "null ptr");
|
||||
|
||||
// Put the style sheet into the XUL cache if the XUL cache is
|
||||
// actually enabled and the document is chrome.
|
||||
if (gXULUtils->UseXULCache() && IsChromeURI(mDocumentURL)) {
|
||||
nsCOMPtr<nsICSSStyleSheet> css = do_QueryInterface(aSheet);
|
||||
if (css) {
|
||||
gXULCache->PutStyleSheet(css);
|
||||
}
|
||||
}
|
||||
|
||||
mStyleSheets.InsertElementAt(aSheet, aIndex + 1); // offset by one for attribute sheet
|
||||
|
||||
NS_ADDREF(aSheet);
|
||||
|
@ -932,6 +956,7 @@ nsXULDocument::InsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex, PRBool
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1055,6 +1080,22 @@ NS_IMETHODIMP
|
|||
nsXULDocument::EndLoad()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// Whack the prototype document into the cache so that the next
|
||||
// time somebody asks for it, they don't need to load it by hand.
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = mCurrentPrototype->GetURI(getter_AddRefs(uri));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (gXULUtils->UseXULCache() && IsChromeURI(mDocumentURL)) {
|
||||
// If it's a 'chrome:' prototype document, then put it into
|
||||
// the prototype cache; other XUL documents will be reloaded
|
||||
// each time.
|
||||
rv = gXULCache->PutPrototype(mCurrentPrototype);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
// Now walk the prototype to build content.
|
||||
rv = PrepareToWalk();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
@ -1856,10 +1897,12 @@ nsXULDocument::CreateFromPrototype(const char* aCommand,
|
|||
|
||||
rv = PrepareStyleSheets(mDocumentURL);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return NS_OK;
|
||||
|
||||
mCommand = aCommand;
|
||||
|
||||
rv = AddPrototypeSheets();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Now create the delegates from the prototype
|
||||
rv = PrepareToWalk();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -3097,7 +3140,7 @@ static const char kXULNameSpaceURI[] = XUL_NAMESPACE_URI;
|
|||
|
||||
rv = nsServiceManager::GetService(kXULPrototypeCacheCID,
|
||||
NS_GET_IID(nsIXULPrototypeCache),
|
||||
(nsISupports**) &gXULPrototypeCache);
|
||||
(nsISupports**) &gXULCache);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
|
@ -4102,14 +4145,17 @@ nsXULDocument::PrepareToWalk()
|
|||
// Push the overlay references onto our overlay processing
|
||||
// stack. GetOverlayReferences() will return an ordered array of
|
||||
// overlay references...
|
||||
nsVoidArray overlays;
|
||||
rv = mCurrentPrototype->GetOverlayReferences(overlays);
|
||||
nsCOMPtr<nsISupportsArray> overlays;
|
||||
rv = mCurrentPrototype->GetOverlayReferences(getter_AddRefs(overlays));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// ...and we preserve this ordering by appending to our
|
||||
// mUnloadedOverlays array in reverse order
|
||||
for (PRInt32 i = overlays.Count() - 1; i >= 0; --i) {
|
||||
mUnloadedOverlays->AppendElement(NS_REINTERPRET_CAST(nsIURI*, overlays[i]));
|
||||
PRUint32 count;
|
||||
overlays->Count(&count);
|
||||
for (PRInt32 i = count - 1; i >= 0; --i) {
|
||||
nsCOMPtr<nsISupports> isupports = dont_AddRef(overlays->ElementAt(i));
|
||||
mUnloadedOverlays->AppendElement(isupports);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4422,11 +4468,15 @@ nsXULDocument::ResumeWalk()
|
|||
|
||||
// Look in the prototype cache for the prototype document with
|
||||
// the specified URI.
|
||||
rv = gXULPrototypeCache->Get(uri, getter_AddRefs(mCurrentPrototype));
|
||||
rv = gXULCache->GetPrototype(uri, getter_AddRefs(mCurrentPrototype));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (mCurrentPrototype) {
|
||||
// Found the overlay's prototype in the cache: walk it!
|
||||
if (gXULUtils->UseXULCache() && mCurrentPrototype) {
|
||||
// Found the overlay's prototype in the cache.
|
||||
rv = AddPrototypeSheets();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Now prepare to walk the prototype to create its content
|
||||
rv = PrepareToWalk();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
@ -4460,6 +4510,15 @@ nsXULDocument::ResumeWalk()
|
|||
|
||||
// If we get here, there is nothing left for us to walk. The content
|
||||
// model is built and ready for layout.
|
||||
#if defined(DEBUG_waterson) || defined(DEBUG_hyatt)
|
||||
{
|
||||
nsTime finish = PR_Now();
|
||||
nsInt64 diff64 = finish - mLoadStart;
|
||||
PRInt32 diff = PRInt32(diff64 / nsInt64(1000));
|
||||
printf("***** XUL document loaded in %ldmsec\n", diff);
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = ResolveForwardReferences();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
@ -4476,6 +4535,21 @@ nsXULDocument::ResumeWalk()
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(DEBUG_waterson) || defined(DEBUG_hyatt)
|
||||
{
|
||||
nsTime finish = PR_Now();
|
||||
nsInt64 diff64 = finish - mLoadStart;
|
||||
PRInt32 diff = PRInt32(diff64 / nsInt64(1000));
|
||||
printf("***** XUL document flowed in %ldmsec\n", diff);
|
||||
}
|
||||
|
||||
{
|
||||
nsInt64 now(PR_Now());
|
||||
now /= nsInt64(1000);
|
||||
printf("### ResumeWalk complete %ld\n", PRInt32(now));
|
||||
}
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -4487,11 +4561,17 @@ nsXULDocument::LoadScript(nsIURI* aURI, const char* aVersion, PRBool* aBlock)
|
|||
nsresult rv;
|
||||
|
||||
// XXX Look in a script cache to see if we already have it
|
||||
nsAutoString script;
|
||||
const char* version;
|
||||
rv = gXULCache->GetScript(aURI, script, &version);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (gXULUtils->UseXULCache() && script.Length()) {
|
||||
// We've found it in the cache. Just re-evaluate it.
|
||||
rv = EvaluateScript(aURI, script, 1, version);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (/* cached */ PR_FALSE) {
|
||||
*aBlock = PR_FALSE;
|
||||
|
||||
// XXX brendan, shaver: do some magic here
|
||||
}
|
||||
else {
|
||||
// Set the current script URL so that the DoneLoadingScript()
|
||||
|
@ -4538,6 +4618,12 @@ nsXULDocument::DoneLoadingScript(nsIUnicharStreamLoader* aLoader,
|
|||
if (NS_SUCCEEDED(aStatus)) {
|
||||
rv = doc->EvaluateScript(doc->mCurrentScriptURL, aData, 1,
|
||||
doc->mCurrentScriptLanguageVersion);
|
||||
|
||||
if (IsChromeURI(doc->mDocumentURL)) {
|
||||
gXULCache->PutScript(doc->mCurrentScriptURL,
|
||||
aData,
|
||||
doc->mCurrentScriptLanguageVersion);
|
||||
}
|
||||
}
|
||||
|
||||
// balance the addref we added in LoadScript()
|
||||
|
@ -4842,10 +4928,23 @@ nsXULDocument::CheckTemplateBuilder(nsIContent* aElement)
|
|||
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to set builder's database");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Force construction of immediate template sub-content _now_.
|
||||
rv = builder->CreateContents(aElement);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create template contents");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsCOMPtr<nsIXULContent> xulcontent = do_QueryInterface(aElement);
|
||||
if (xulcontent) {
|
||||
// Mark the XUL element as being lazy, so the template builder
|
||||
// will run when layout first asks for these nodes.
|
||||
//
|
||||
//rv = xulcontent->ClearLazyState(eTemplateContentsBuilt | eContainerContentsBuilt);
|
||||
//if (NS_FAILED(rv)) return rv;
|
||||
|
||||
xulcontent->SetLazyState(nsIXULContent::eChildrenMustBeRebuilt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
else {
|
||||
// Force construction of immediate template sub-content _now_.
|
||||
rv = builder->CreateContents(aElement);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create template contents");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -4895,6 +4994,45 @@ nsXULDocument::CheckBroadcasterHookup(nsIContent* aElement)
|
|||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsXULDocument::AddPrototypeSheets()
|
||||
{
|
||||
// Add mCurrentPrototype's style sheets to the document.
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> sheets;
|
||||
rv = mCurrentPrototype->GetStyleSheetReferences(getter_AddRefs(sheets));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRUint32 count;
|
||||
sheets->Count(&count);
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsISupports> isupports = dont_AddRef(sheets->ElementAt(i));
|
||||
|
||||
nsCOMPtr<nsIURI> uri = do_QueryInterface(isupports);
|
||||
NS_ASSERTION(uri != nsnull, "not a URI!!!");
|
||||
if (! uri)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
nsCOMPtr<nsICSSStyleSheet> sheet;
|
||||
rv = gXULCache->GetStyleSheet(uri, getter_AddRefs(sheet));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
NS_ASSERTION(sheet != nsnull, "uh oh, sheet wasn't in the cache. go reload it");
|
||||
if (! sheet)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
nsCOMPtr<nsICSSStyleSheet> newsheet;
|
||||
rv = sheet->Clone(*getter_AddRefs(newsheet));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
AddStyleSheet(newsheet);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
// nsXULDocument::OverlayForwardReference
|
||||
|
@ -5324,3 +5462,19 @@ nsXULDocument::ProcessCommonAttributes(nsIContent* aElement)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
nsXULDocument::IsChromeURI(nsIURI* aURI)
|
||||
{
|
||||
nsresult rv;
|
||||
nsXPIDLCString protocol;
|
||||
rv = aURI->GetScheme(getter_Copies(protocol));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (PL_strcmp(protocol, "chrome") == 0) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "nsIXULDocument.h"
|
||||
#include "nsIXULPrototypeDocument.h"
|
||||
#include "nsRDFDOMNodeList.h"
|
||||
#include "nsTime.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsWeakPtr.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
@ -459,7 +460,7 @@ protected:
|
|||
static PRInt32 kNameSpaceID_XUL;
|
||||
|
||||
static nsIXULContentUtils* gXULUtils;
|
||||
static nsIXULPrototypeCache* gXULPrototypeCache;
|
||||
static nsIXULPrototypeCache* gXULCache;
|
||||
|
||||
static PRLogModuleInfo* gXULLog;
|
||||
|
||||
|
@ -632,6 +633,11 @@ protected:
|
|||
*/
|
||||
nsresult CheckBroadcasterHookup(nsIContent* aElement);
|
||||
|
||||
/**
|
||||
* Add the current prototype's style sheets to the document.
|
||||
*/
|
||||
nsresult AddPrototypeSheets();
|
||||
|
||||
/**
|
||||
* Used to resolve broadcaster references
|
||||
*/
|
||||
|
@ -686,6 +692,10 @@ protected:
|
|||
nsresult
|
||||
ProcessCommonAttributes(nsIContent* aElement);
|
||||
|
||||
static
|
||||
PRBool
|
||||
IsChromeURI(nsIURI* aURI);
|
||||
|
||||
/**
|
||||
* The current prototype that we are walking to construct the
|
||||
* content model.
|
||||
|
@ -714,6 +724,11 @@ protected:
|
|||
* prototype walk.
|
||||
*/
|
||||
nsresult ResumeWalk();
|
||||
|
||||
#if defined(DEBUG_waterson) || defined(DEBUG_hyatt)
|
||||
// timing
|
||||
nsTime mLoadStart;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -25,10 +25,14 @@
|
|||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsICSSStyleSheet.h"
|
||||
#include "nsIXULPrototypeCache.h"
|
||||
#include "nsIXULPrototypeDocument.h"
|
||||
#include "nsIURI.h"
|
||||
#include "plhash.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "plstr.h"
|
||||
|
||||
|
||||
class nsXULPrototypeCache : public nsIXULPrototypeCache
|
||||
{
|
||||
|
@ -36,8 +40,16 @@ public:
|
|||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Get(nsIURI* aURI, nsIXULPrototypeDocument** _result);
|
||||
NS_IMETHOD Put(nsIURI* aURI, nsIXULPrototypeDocument* aDocument);
|
||||
NS_IMETHOD GetPrototype(nsIURI* aURI, nsIXULPrototypeDocument** _result);
|
||||
NS_IMETHOD PutPrototype(nsIXULPrototypeDocument* aDocument);
|
||||
|
||||
NS_IMETHOD GetStyleSheet(nsIURI* aURI, nsICSSStyleSheet** _result);
|
||||
NS_IMETHOD PutStyleSheet(nsICSSStyleSheet* aStyleSheet);
|
||||
|
||||
NS_IMETHOD GetScript(nsIURI* aURI, nsString& aScript, const char** aVersion);
|
||||
NS_IMETHOD PutScript(nsIURI* aURI, const nsString& aScript, const char* aVersion);
|
||||
|
||||
NS_IMETHOD Flush();
|
||||
|
||||
protected:
|
||||
friend NS_IMETHODIMP
|
||||
|
@ -45,13 +57,45 @@ protected:
|
|||
|
||||
nsXULPrototypeCache();
|
||||
virtual ~nsXULPrototypeCache();
|
||||
static PRIntn ReleaseTableEntry(PLHashEntry* aHashEntry, PRIntn aIndex, void* aClosure);
|
||||
nsresult Init();
|
||||
|
||||
static PLHashNumber Hash(const void* aKey);
|
||||
static PRIntn CompareKeys(const void* aKey1, const void* aKey2);
|
||||
static PRBool
|
||||
ReleaseScriptEntryEnumFunc(nsHashKey* aKey, void* aData, void* aClosure);
|
||||
|
||||
PLHashTable* mTable;
|
||||
nsSupportsHashtable mPrototypeTable;
|
||||
nsSupportsHashtable mStyleSheetTable;
|
||||
nsHashtable mScriptTable;
|
||||
|
||||
|
||||
class nsIURIKey : public nsHashKey {
|
||||
protected:
|
||||
nsCOMPtr<nsIURI> mKey;
|
||||
|
||||
public:
|
||||
nsIURIKey(nsIURI* key) : mKey(key) {}
|
||||
~nsIURIKey(void) {}
|
||||
|
||||
PRUint32 HashValue(void) const {
|
||||
nsXPIDLCString spec;
|
||||
mKey->GetSpec(getter_Copies(spec));
|
||||
return (PRUint32) PL_HashString(spec);
|
||||
}
|
||||
|
||||
PRBool Equals(const nsHashKey *aKey) const {
|
||||
PRBool eq;
|
||||
mKey->Equals( ((nsIURIKey*) aKey)->mKey, &eq );
|
||||
return eq;
|
||||
}
|
||||
|
||||
nsHashKey *Clone(void) const {
|
||||
return new nsIURIKey(mKey);
|
||||
}
|
||||
};
|
||||
|
||||
class ScriptEntry {
|
||||
public:
|
||||
nsString mScript;
|
||||
const char* mVersion;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
@ -64,36 +108,18 @@ nsXULPrototypeCache::nsXULPrototypeCache()
|
|||
|
||||
nsXULPrototypeCache::~nsXULPrototypeCache()
|
||||
{
|
||||
if (mTable) {
|
||||
PL_HashTableEnumerateEntries(mTable, ReleaseTableEntry, nsnull);
|
||||
PL_HashTableDestroy(mTable);
|
||||
}
|
||||
mScriptTable.Enumerate(ReleaseScriptEntryEnumFunc, nsnull);
|
||||
}
|
||||
|
||||
PRIntn
|
||||
nsXULPrototypeCache::ReleaseTableEntry(PLHashEntry* aHashEntry, PRIntn aIndex, void* aClosure)
|
||||
|
||||
PRBool
|
||||
nsXULPrototypeCache::ReleaseScriptEntryEnumFunc(nsHashKey* aKey, void* aData, void* aClosure)
|
||||
{
|
||||
nsIURI* key = NS_REINTERPRET_CAST(nsIURI*, NS_CONST_CAST(void*, aHashEntry->key));
|
||||
NS_RELEASE(key);
|
||||
|
||||
nsIXULPrototypeDocument* value = NS_REINTERPRET_CAST(nsIXULPrototypeDocument*, aHashEntry->value);
|
||||
NS_RELEASE(value);
|
||||
|
||||
return HT_ENUMERATE_REMOVE;
|
||||
ScriptEntry* entry = NS_REINTERPRET_CAST(ScriptEntry*, aData);
|
||||
delete entry;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsXULPrototypeCache::Init()
|
||||
{
|
||||
mTable = PL_NewHashTable(16, Hash, CompareKeys, PL_CompareValues, nsnull, nsnull);
|
||||
if (! mTable)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsXULPrototypeCache, nsIXULPrototypeCache);
|
||||
|
||||
|
||||
|
@ -109,11 +135,6 @@ NS_NewXULPrototypeCache(nsISupports* aOuter, REFNSIID aIID, void** aResult)
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv;
|
||||
rv = result->Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
delete result;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_ADDREF(result);
|
||||
rv = result->QueryInterface(aIID, aResult);
|
||||
|
@ -122,36 +143,98 @@ NS_NewXULPrototypeCache(nsISupports* aOuter, REFNSIID aIID, void** aResult)
|
|||
return rv;
|
||||
}
|
||||
|
||||
PLHashNumber
|
||||
nsXULPrototypeCache::Hash(const void* aKey)
|
||||
{
|
||||
nsIURI* uri = NS_REINTERPRET_CAST(nsIURI*, NS_CONST_CAST(void*, aKey));
|
||||
nsXPIDLCString spec;
|
||||
uri->GetSpec(getter_Copies(spec));
|
||||
return PL_HashString(spec);
|
||||
}
|
||||
|
||||
|
||||
PRIntn
|
||||
nsXULPrototypeCache::CompareKeys(const void* aKey1, const void* aKey2)
|
||||
{
|
||||
nsIURI* uri1 = NS_REINTERPRET_CAST(nsIURI*, NS_CONST_CAST(void*, aKey1));
|
||||
nsIURI* uri2 = NS_REINTERPRET_CAST(nsIURI*, NS_CONST_CAST(void*, aKey2));
|
||||
PRBool eq;
|
||||
uri1->Equals(uri2, &eq);
|
||||
return eq;
|
||||
}
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeCache::Get(nsIURI* aURI, nsIXULPrototypeDocument** _result)
|
||||
nsXULPrototypeCache::GetPrototype(nsIURI* aURI, nsIXULPrototypeDocument** _result)
|
||||
{
|
||||
nsIURIKey key(aURI);
|
||||
*_result = NS_STATIC_CAST(nsIXULPrototypeDocument*, mPrototypeTable.Get(&key));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeCache::Put(nsIURI* aURI, nsIXULPrototypeDocument* aDocument)
|
||||
nsXULPrototypeCache::PutPrototype(nsIXULPrototypeDocument* aDocument)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = aDocument->GetURI(getter_AddRefs(uri));
|
||||
|
||||
nsIURIKey key(uri);
|
||||
mPrototypeTable.Put(&key, aDocument);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeCache::GetStyleSheet(nsIURI* aURI, nsICSSStyleSheet** _result)
|
||||
{
|
||||
nsIURIKey key(aURI);
|
||||
*_result = NS_STATIC_CAST(nsICSSStyleSheet*, mStyleSheetTable.Get(&key));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeCache::PutStyleSheet(nsICSSStyleSheet* aStyleSheet)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = aStyleSheet->GetURL(*getter_AddRefs(uri));
|
||||
|
||||
nsIURIKey key(uri);
|
||||
mStyleSheetTable.Put(&key, aStyleSheet);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeCache::GetScript(nsIURI* aURI, nsString& aScript, const char** aVersion)
|
||||
{
|
||||
nsIURIKey key(aURI);
|
||||
const ScriptEntry* entry = NS_REINTERPRET_CAST(const ScriptEntry*, mScriptTable.Get(&key));
|
||||
if (entry) {
|
||||
aScript = entry->mScript;
|
||||
*aVersion = entry->mVersion;
|
||||
}
|
||||
else {
|
||||
aScript.Truncate();
|
||||
*aVersion = nsnull;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeCache::PutScript(nsIURI* aURI, const nsString& aScript, const char* aVersion)
|
||||
{
|
||||
ScriptEntry* newentry = new ScriptEntry();
|
||||
if (! newentry)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
newentry->mScript = aScript;
|
||||
newentry->mVersion = aVersion;
|
||||
|
||||
nsIURIKey key(aURI);
|
||||
ScriptEntry* oldentry = NS_REINTERPRET_CAST(ScriptEntry*, mScriptTable.Put(&key, newentry));
|
||||
|
||||
delete oldentry;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeCache::Flush()
|
||||
{
|
||||
mPrototypeTable.Reset();
|
||||
mStyleSheetTable.Reset();
|
||||
mScriptTable.Reset(ReleaseScriptEntryEnumFunc, nsnull);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsIStyleSheet.h"
|
||||
#include "nsIXULPrototypeDocument.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsString2.h"
|
||||
|
@ -48,11 +47,11 @@ public:
|
|||
NS_IMETHOD GetRootElement(nsXULPrototypeElement** aResult);
|
||||
NS_IMETHOD SetRootElement(nsXULPrototypeElement* aElement);
|
||||
|
||||
NS_IMETHOD AddStyleSheet(nsIStyleSheet* aStyleSheet);
|
||||
NS_IMETHOD GetStyleSheets(nsVoidArray& aResult);
|
||||
NS_IMETHOD AddStyleSheetReference(nsIURI* aStyleSheet);
|
||||
NS_IMETHOD GetStyleSheetReferences(nsISupportsArray** aResult);
|
||||
|
||||
NS_IMETHOD AddOverlayReference(nsIURI* aURI);
|
||||
NS_IMETHOD GetOverlayReferences(nsVoidArray& aResult);
|
||||
NS_IMETHOD GetOverlayReferences(nsISupportsArray** aResult);
|
||||
|
||||
NS_IMETHOD GetHeaderData(nsIAtom* aField, nsString& aData) const;
|
||||
NS_IMETHOD SetHeaderData(nsIAtom* aField, const nsString& aData);
|
||||
|
@ -60,7 +59,7 @@ public:
|
|||
protected:
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsXULPrototypeElement* mRoot;
|
||||
nsCOMPtr<nsISupportsArray> mStyleSheets;
|
||||
nsCOMPtr<nsISupportsArray> mStyleSheetReferences;
|
||||
nsCOMPtr<nsISupportsArray> mOverlayReferences;
|
||||
|
||||
nsXULPrototypeDocument();
|
||||
|
@ -86,7 +85,7 @@ nsXULPrototypeDocument::Init()
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(mStyleSheets));
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(mStyleSheetReferences));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(mOverlayReferences));
|
||||
|
@ -166,33 +165,22 @@ nsXULPrototypeDocument::SetRootElement(nsXULPrototypeElement* aElement)
|
|||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeDocument::AddStyleSheet(nsIStyleSheet* aStyleSheet)
|
||||
nsXULPrototypeDocument::AddStyleSheetReference(nsIURI* aURI)
|
||||
{
|
||||
NS_PRECONDITION(aStyleSheet != nsnull, "null ptr");
|
||||
if (! aStyleSheet)
|
||||
NS_PRECONDITION(aURI != nsnull, "null ptr");
|
||||
if (! aURI)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
mStyleSheets->AppendElement(aStyleSheet);
|
||||
mStyleSheetReferences->AppendElement(aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeDocument::GetStyleSheets(nsVoidArray& aResult)
|
||||
nsXULPrototypeDocument::GetStyleSheetReferences(nsISupportsArray** aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
aResult.Clear();
|
||||
|
||||
PRUint32 cnt;
|
||||
rv = mStyleSheets->Count(&cnt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
for (PRInt32 i = 0; i < PRInt32(cnt); ++i) {
|
||||
nsIStyleSheet* sheet = NS_REINTERPRET_CAST(nsIStyleSheet*, mStyleSheets->ElementAt(i));
|
||||
aResult.AppendElement(sheet);
|
||||
NS_RELEASE(sheet);
|
||||
}
|
||||
|
||||
*aResult = mStyleSheetReferences;
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -211,21 +199,10 @@ nsXULPrototypeDocument::AddOverlayReference(nsIURI* aURI)
|
|||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeDocument::GetOverlayReferences(nsVoidArray& aResult)
|
||||
nsXULPrototypeDocument::GetOverlayReferences(nsISupportsArray** aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
aResult.Clear();
|
||||
|
||||
PRUint32 cnt;
|
||||
rv = mOverlayReferences->Count(&cnt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
for (PRInt32 i = 0; i < PRInt32(cnt); ++i) {
|
||||
nsIURI* ref = NS_REINTERPRET_CAST(nsIURI*, mOverlayReferences->ElementAt(i));
|
||||
aResult.AppendElement(ref);
|
||||
NS_RELEASE(ref);
|
||||
}
|
||||
|
||||
*aResult = mOverlayReferences;
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,12 +43,14 @@
|
|||
#include "nsIRDFNode.h"
|
||||
#include "nsINameSpace.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsIRDFService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsITextContent.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIXMLContent.h"
|
||||
#include "nsIXULContentUtils.h"
|
||||
#include "nsIXULPrototypeCache.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsNeckoUtil.h"
|
||||
#include "nsRDFCID.h"
|
||||
|
@ -67,23 +69,15 @@
|
|||
#include "nsDateTimeFormatCID.h"
|
||||
#include "nsIScriptableDateFormat.h"
|
||||
|
||||
static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID);
|
||||
static NS_DEFINE_IID(kIRDFResourceIID, NS_IRDFRESOURCE_IID);
|
||||
static NS_DEFINE_IID(kIRDFLiteralIID, NS_IRDFLITERAL_IID);
|
||||
static NS_DEFINE_IID(kIRDFIntIID, NS_IRDFINT_IID);
|
||||
static NS_DEFINE_IID(kIRDFDateIID, NS_IRDFDATE_IID);
|
||||
static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID); // XXX grr...
|
||||
static NS_DEFINE_CID(kTextNodeCID, NS_TEXTNODE_CID);
|
||||
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
||||
|
||||
static NS_DEFINE_CID(kLocaleFactoryCID, NS_LOCALEFACTORY_CID);
|
||||
static NS_DEFINE_IID(kILocaleFactoryIID, NS_ILOCALEFACTORY_IID);
|
||||
static NS_DEFINE_CID(kLocaleCID, NS_LOCALE_CID);
|
||||
static NS_DEFINE_IID(kILocaleIID, NS_ILOCALE_IID);
|
||||
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
|
||||
|
||||
static NS_DEFINE_CID(kDateTimeFormatCID, NS_DATETIMEFORMAT_CID);
|
||||
static NS_DEFINE_CID(kDateTimeFormatIID, NS_IDATETIMEFORMAT_IID);
|
||||
static NS_DEFINE_CID(kDateTimeFormatCID, NS_DATETIMEFORMAT_CID);
|
||||
static NS_DEFINE_CID(kDateTimeFormatIID, NS_IDATETIMEFORMAT_IID);
|
||||
static NS_DEFINE_CID(kLocaleCID, NS_LOCALE_CID);
|
||||
static NS_DEFINE_CID(kLocaleFactoryCID, NS_LOCALEFACTORY_CID);
|
||||
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
|
||||
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
||||
static NS_DEFINE_CID(kTextNodeCID, NS_TEXTNODE_CID);
|
||||
static NS_DEFINE_CID(kXULPrototypeCacheCID, NS_XULPROTOTYPECACHE_CID);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
@ -113,6 +107,11 @@ protected:
|
|||
|
||||
static EventHandlerMapEntry kEventHandlerMap[];
|
||||
|
||||
static PRBool gDisableXULCache;
|
||||
|
||||
static int
|
||||
DisableXULCacheChangedCallback(const char* aPrefName, void* aClosure);
|
||||
|
||||
public:
|
||||
// nsISupports methods
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -170,6 +169,9 @@ public:
|
|||
|
||||
NS_IMETHOD
|
||||
GetEventHandlerIID(nsIAtom* aName, nsIID* aIID, PRBool* aFound);
|
||||
|
||||
NS_IMETHOD_(PRBool)
|
||||
UseXULCache();
|
||||
};
|
||||
|
||||
nsrefcnt nsXULContentUtils::gRefCnt;
|
||||
|
@ -227,9 +229,15 @@ nsXULContentUtils::kEventHandlerMap[] = {
|
|||
};
|
||||
|
||||
|
||||
// Enabled by default. Must be over-ridden to disable
|
||||
PRBool nsXULContentUtils::gDisableXULCache = PR_FALSE;
|
||||
|
||||
|
||||
static const char kDisableXULCachePref[] = "nglayout.debug.disable_xul_cache";
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Constructors n' stuff
|
||||
|
||||
//
|
||||
|
||||
nsXULContentUtils::nsXULContentUtils()
|
||||
{
|
||||
|
@ -242,19 +250,19 @@ nsXULContentUtils::Init()
|
|||
if (gRefCnt++ == 0) {
|
||||
nsresult rv;
|
||||
rv = nsServiceManager::GetService(kRDFServiceCID,
|
||||
nsCOMTypeInfo<nsIRDFService>::GetIID(),
|
||||
NS_GET_IID(nsIRDFService),
|
||||
(nsISupports**) &gRDF);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = nsComponentManager::CreateInstance(kNameSpaceManagerCID,
|
||||
nsnull,
|
||||
nsCOMTypeInfo<nsINameSpaceManager>::GetIID(),
|
||||
NS_GET_IID(nsINameSpaceManager),
|
||||
(void**) &gNameSpaceManager);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = nsComponentManager::CreateInstance(kDateTimeFormatCID,
|
||||
nsnull,
|
||||
nsCOMTypeInfo<nsIDateTimeFormat>::GetIID(),
|
||||
NS_GET_IID(nsIDateTimeFormat),
|
||||
(void**) &gFormat);
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -267,6 +275,13 @@ nsXULContentUtils::Init()
|
|||
entry->mAttributeAtom = NS_NewAtom(entry->mAttributeName);
|
||||
++entry;
|
||||
}
|
||||
|
||||
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_PROGID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// XXX Ignore return values.
|
||||
prefs->GetBoolPref(kDisableXULCachePref, &gDisableXULCache);
|
||||
prefs->RegisterCallback(kDisableXULCachePref, DisableXULCacheChangedCallback, nsnull);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -332,7 +347,7 @@ NS_NewXULContentUtils(nsISupports* aOuter, const nsIID& aIID, void** aResult)
|
|||
//------------------------------------------------------------------------
|
||||
// nsISupports methods
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsXULContentUtils, nsCOMTypeInfo<nsIXULContentUtils>::GetIID());
|
||||
NS_IMPL_ISUPPORTS(nsXULContentUtils, NS_GET_IID(nsIXULContentUtils));
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// nsIXULContentUtils methods
|
||||
|
@ -349,7 +364,7 @@ nsXULContentUtils::AttachTextNode(nsIContent* parent, nsIRDFNode* value)
|
|||
nsCOMPtr<nsITextContent> text;
|
||||
rv = nsComponentManager::CreateInstance(kTextNodeCID,
|
||||
nsnull,
|
||||
nsITextContent::GetIID(),
|
||||
NS_GET_IID(nsITextContent),
|
||||
getter_AddRefs(text));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
@ -948,3 +963,32 @@ nsXULContentUtils::GetEventHandlerIID(nsIAtom* aName, nsIID* aIID, PRBool* aFoun
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP_(PRBool)
|
||||
nsXULContentUtils::UseXULCache()
|
||||
{
|
||||
return !gDisableXULCache;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
int
|
||||
nsXULContentUtils::DisableXULCacheChangedCallback(const char* aPref, void* aClosure)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_PROGID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
prefs->GetBoolPref(kDisableXULCachePref, &gDisableXULCache);
|
||||
}
|
||||
|
||||
// Flush the cache, regardless
|
||||
NS_WITH_SERVICE(nsIXULPrototypeCache, cache, kXULPrototypeCacheCID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
cache->Flush();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -98,6 +98,12 @@ public:
|
|||
|
||||
NS_IMETHOD
|
||||
GetEventHandlerIID(nsIAtom* aName, nsIID* aIID, PRBool* aFound) = 0;
|
||||
|
||||
/**
|
||||
* Returns <code>PR_TRUE</code> if the XUL cache should be used
|
||||
*/
|
||||
NS_IMETHOD_(PRBool)
|
||||
UseXULCache() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#define nsIXULPrototypeCache_h__
|
||||
|
||||
#include "nsISupports.h"
|
||||
class nsICSSStyleSheet;
|
||||
class nsIURI;
|
||||
class nsIXULPrototypeDocument;
|
||||
|
||||
|
@ -40,8 +41,20 @@ class nsIXULPrototypeCache : public nsISupports
|
|||
public:
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IXULPROTOTYPECACHE_IID);
|
||||
|
||||
NS_IMETHOD Get(nsIURI* aURI, nsIXULPrototypeDocument** _result) = 0;
|
||||
NS_IMETHOD Put(nsIURI* aURI, nsIXULPrototypeDocument* aDocument) = 0;
|
||||
NS_IMETHOD GetPrototype(nsIURI* aURI, nsIXULPrototypeDocument** _result) = 0;
|
||||
NS_IMETHOD PutPrototype(nsIXULPrototypeDocument* aDocument) = 0;
|
||||
|
||||
NS_IMETHOD GetStyleSheet(nsIURI* aURI, nsICSSStyleSheet** _result) = 0;
|
||||
NS_IMETHOD PutStyleSheet(nsICSSStyleSheet* aStyleSheet) = 0;
|
||||
|
||||
NS_IMETHOD GetScript(nsIURI* aURI, nsString& aScript, const char** aVersion) = 0;
|
||||
NS_IMETHOD PutScript(nsIURI* aURI, const nsString& aScript, const char* aVersion) = 0;
|
||||
|
||||
/**
|
||||
* Flush the cache; remove all XUL prototype documents, style
|
||||
* sheets, and scripts.
|
||||
*/
|
||||
NS_IMETHOD Flush() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -57,11 +57,11 @@ public:
|
|||
NS_IMETHOD GetRootElement(nsXULPrototypeElement** aResult) = 0;
|
||||
NS_IMETHOD SetRootElement(nsXULPrototypeElement* aElement) = 0;
|
||||
|
||||
NS_IMETHOD AddStyleSheet(nsIStyleSheet* aStyleSheet) = 0;
|
||||
NS_IMETHOD GetStyleSheets(nsVoidArray& aResult) = 0;
|
||||
NS_IMETHOD AddStyleSheetReference(nsIURI* aStyleSheet) = 0;
|
||||
NS_IMETHOD GetStyleSheetReferences(nsISupportsArray** aResult) = 0;
|
||||
|
||||
NS_IMETHOD AddOverlayReference(nsIURI* aURI) = 0;
|
||||
NS_IMETHOD GetOverlayReferences(nsVoidArray& aResult) = 0;
|
||||
NS_IMETHOD GetOverlayReferences(nsISupportsArray** aResult) = 0;
|
||||
|
||||
NS_IMETHOD GetHeaderData(nsIAtom* aField, nsString& aData) const = 0;
|
||||
NS_IMETHOD SetHeaderData(nsIAtom* aField, const nsString& aData) = 0;
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
#include "nsIXULDocument.h"
|
||||
#include "nsIXULKeyListener.h"
|
||||
#include "nsIXULPrototypeDocument.h"
|
||||
#include "nsIXULPrototypeCache.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsNeckoUtil.h"
|
||||
#include "nsRDFCID.h"
|
||||
|
@ -102,6 +103,8 @@ static const char kXULNameSpaceURI[] = XUL_NAMESPACE_URI;
|
|||
static NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID);
|
||||
static NS_DEFINE_CID(kCSSParserCID, NS_CSSPARSER_CID);
|
||||
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
|
||||
static NS_DEFINE_CID(kXULContentUtilsCID, NS_XULCONTENTUTILS_CID);
|
||||
static NS_DEFINE_CID(kXULPrototypeCacheCID, NS_XULPROTOTYPECACHE_CID);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
|
@ -142,6 +145,8 @@ protected:
|
|||
// pseudo-constants
|
||||
static nsrefcnt gRefCnt;
|
||||
static nsINameSpaceManager* gNameSpaceManager;
|
||||
static nsIXULContentUtils* gXULUtils;
|
||||
static nsIXULPrototypeCache* gXULCache;
|
||||
|
||||
static nsIAtom* kClassAtom;
|
||||
static nsIAtom* kIdAtom;
|
||||
|
@ -240,6 +245,8 @@ protected:
|
|||
|
||||
nsrefcnt XULContentSinkImpl::gRefCnt;
|
||||
nsINameSpaceManager* XULContentSinkImpl::gNameSpaceManager;
|
||||
nsIXULContentUtils* XULContentSinkImpl::gXULUtils;
|
||||
nsIXULPrototypeCache* XULContentSinkImpl::gXULCache;
|
||||
|
||||
nsIAtom* XULContentSinkImpl::kClassAtom;
|
||||
nsIAtom* XULContentSinkImpl::kIdAtom;
|
||||
|
@ -377,6 +384,15 @@ XULContentSinkImpl::XULContentSinkImpl(nsresult& rv)
|
|||
kScriptAtom = NS_NewAtom("script");
|
||||
kStyleAtom = NS_NewAtom("style");
|
||||
kTemplateAtom = NS_NewAtom("template");
|
||||
|
||||
rv = nsServiceManager::GetService(kXULContentUtilsCID,
|
||||
NS_GET_IID(nsIXULContentUtils),
|
||||
(nsISupports**) &gXULUtils);
|
||||
if (NS_FAILED(rv)) return;
|
||||
|
||||
rv = nsServiceManager::GetService(kXULPrototypeCacheCID,
|
||||
NS_GET_IID(nsIXULPrototypeCache),
|
||||
(nsISupports**) &gXULCache);
|
||||
}
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
|
@ -390,11 +406,6 @@ XULContentSinkImpl::XULContentSinkImpl(nsresult& rv)
|
|||
|
||||
XULContentSinkImpl::~XULContentSinkImpl()
|
||||
{
|
||||
#ifdef DEBUG_REFS
|
||||
--gInstanceCount;
|
||||
fprintf(stdout, "%d - RDF: XULContentSinkImpl\n", gInstanceCount);
|
||||
#endif
|
||||
|
||||
NS_IF_RELEASE(mParser); // XXX should've been released by now, unless error.
|
||||
|
||||
{
|
||||
|
@ -475,6 +486,16 @@ XULContentSinkImpl::~XULContentSinkImpl()
|
|||
NS_IF_RELEASE(kScriptAtom);
|
||||
NS_IF_RELEASE(kStyleAtom);
|
||||
NS_IF_RELEASE(kTemplateAtom);
|
||||
|
||||
if (gXULUtils) {
|
||||
nsServiceManager::ReleaseService(kXULContentUtilsCID, gXULUtils);
|
||||
gXULUtils = nsnull;
|
||||
}
|
||||
|
||||
if (gXULCache) {
|
||||
nsServiceManager::ReleaseService(kXULPrototypeCacheCID, gXULCache);
|
||||
gXULCache = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -821,7 +842,7 @@ XULContentSinkImpl::ProcessStyleLink(nsIContent* aElement,
|
|||
{
|
||||
static const char kCSSType[] = "text/css";
|
||||
|
||||
nsresult result = NS_OK;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (aAlternate) { // if alternate, does it have title?
|
||||
if (0 == aTitle.Length()) { // alternates must have title
|
||||
|
@ -835,11 +856,35 @@ XULContentSinkImpl::ProcessStyleLink(nsIContent* aElement,
|
|||
|
||||
if ((0 == mimeType.Length()) || mimeType.EqualsIgnoreCase(kCSSType)) {
|
||||
nsCOMPtr<nsIURI> url;
|
||||
result = NS_NewURI(getter_AddRefs(url), aHref, mDocumentURL);
|
||||
if (NS_OK != result) {
|
||||
rv = NS_NewURI(getter_AddRefs(url), aHref, mDocumentURL);
|
||||
if (NS_OK != rv) {
|
||||
return NS_OK; // The URL is bad, move along, don't propagate the error (for now)
|
||||
}
|
||||
|
||||
// Add the style sheet reference to the prototype
|
||||
mPrototype->AddStyleSheetReference(url);
|
||||
|
||||
// See if the style sheet is in the style sheet cache. If so,
|
||||
// just use it.
|
||||
if (gXULUtils->UseXULCache()) {
|
||||
nsCOMPtr<nsICSSStyleSheet> sheet;
|
||||
rv = gXULCache->GetStyleSheet(url, getter_AddRefs(sheet));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && sheet) {
|
||||
nsCOMPtr<nsICSSStyleSheet> newsheet;
|
||||
rv = sheet->Clone(*getter_AddRefs(newsheet));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && newsheet) {
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
|
||||
if (doc) {
|
||||
doc->AddStyleSheet(newsheet);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Nope, we need to load it asynchronously
|
||||
PRBool blockParser = PR_FALSE;
|
||||
if (! aAlternate) {
|
||||
if (0 < aTitle.Length()) { // possibly preferred sheet
|
||||
|
@ -862,16 +907,16 @@ XULContentSinkImpl::ProcessStyleLink(nsIContent* aElement,
|
|||
// sheet in a fairly random location if we're loading an
|
||||
// overlay. Should we just use a Very Large Number?
|
||||
PRBool doneLoading;
|
||||
result = mCSSLoader->LoadStyleLink(aElement, url, aTitle, aMedia, kNameSpaceID_Unknown,
|
||||
mStyleSheetCount++,
|
||||
((blockParser) ? mParser : nsnull),
|
||||
doneLoading);
|
||||
if (NS_SUCCEEDED(result) && blockParser && (! doneLoading)) {
|
||||
result = NS_ERROR_HTMLPARSER_BLOCK;
|
||||
rv = mCSSLoader->LoadStyleLink(aElement, url, aTitle, aMedia, kNameSpaceID_Unknown,
|
||||
mStyleSheetCount++,
|
||||
((blockParser) ? mParser : nsnull),
|
||||
doneLoading);
|
||||
if (NS_SUCCEEDED(rv) && blockParser && (! doneLoading)) {
|
||||
rv = NS_ERROR_HTMLPARSER_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -43,12 +43,14 @@
|
|||
#include "nsIRDFNode.h"
|
||||
#include "nsINameSpace.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsIRDFService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsITextContent.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIXMLContent.h"
|
||||
#include "nsIXULContentUtils.h"
|
||||
#include "nsIXULPrototypeCache.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsNeckoUtil.h"
|
||||
#include "nsRDFCID.h"
|
||||
|
@ -67,23 +69,15 @@
|
|||
#include "nsDateTimeFormatCID.h"
|
||||
#include "nsIScriptableDateFormat.h"
|
||||
|
||||
static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID);
|
||||
static NS_DEFINE_IID(kIRDFResourceIID, NS_IRDFRESOURCE_IID);
|
||||
static NS_DEFINE_IID(kIRDFLiteralIID, NS_IRDFLITERAL_IID);
|
||||
static NS_DEFINE_IID(kIRDFIntIID, NS_IRDFINT_IID);
|
||||
static NS_DEFINE_IID(kIRDFDateIID, NS_IRDFDATE_IID);
|
||||
static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID); // XXX grr...
|
||||
static NS_DEFINE_CID(kTextNodeCID, NS_TEXTNODE_CID);
|
||||
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
||||
|
||||
static NS_DEFINE_CID(kLocaleFactoryCID, NS_LOCALEFACTORY_CID);
|
||||
static NS_DEFINE_IID(kILocaleFactoryIID, NS_ILOCALEFACTORY_IID);
|
||||
static NS_DEFINE_CID(kLocaleCID, NS_LOCALE_CID);
|
||||
static NS_DEFINE_IID(kILocaleIID, NS_ILOCALE_IID);
|
||||
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
|
||||
|
||||
static NS_DEFINE_CID(kDateTimeFormatCID, NS_DATETIMEFORMAT_CID);
|
||||
static NS_DEFINE_CID(kDateTimeFormatIID, NS_IDATETIMEFORMAT_IID);
|
||||
static NS_DEFINE_CID(kDateTimeFormatCID, NS_DATETIMEFORMAT_CID);
|
||||
static NS_DEFINE_CID(kDateTimeFormatIID, NS_IDATETIMEFORMAT_IID);
|
||||
static NS_DEFINE_CID(kLocaleCID, NS_LOCALE_CID);
|
||||
static NS_DEFINE_CID(kLocaleFactoryCID, NS_LOCALEFACTORY_CID);
|
||||
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
|
||||
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
||||
static NS_DEFINE_CID(kTextNodeCID, NS_TEXTNODE_CID);
|
||||
static NS_DEFINE_CID(kXULPrototypeCacheCID, NS_XULPROTOTYPECACHE_CID);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
@ -113,6 +107,11 @@ protected:
|
|||
|
||||
static EventHandlerMapEntry kEventHandlerMap[];
|
||||
|
||||
static PRBool gDisableXULCache;
|
||||
|
||||
static int
|
||||
DisableXULCacheChangedCallback(const char* aPrefName, void* aClosure);
|
||||
|
||||
public:
|
||||
// nsISupports methods
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -170,6 +169,9 @@ public:
|
|||
|
||||
NS_IMETHOD
|
||||
GetEventHandlerIID(nsIAtom* aName, nsIID* aIID, PRBool* aFound);
|
||||
|
||||
NS_IMETHOD_(PRBool)
|
||||
UseXULCache();
|
||||
};
|
||||
|
||||
nsrefcnt nsXULContentUtils::gRefCnt;
|
||||
|
@ -227,9 +229,15 @@ nsXULContentUtils::kEventHandlerMap[] = {
|
|||
};
|
||||
|
||||
|
||||
// Enabled by default. Must be over-ridden to disable
|
||||
PRBool nsXULContentUtils::gDisableXULCache = PR_FALSE;
|
||||
|
||||
|
||||
static const char kDisableXULCachePref[] = "nglayout.debug.disable_xul_cache";
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Constructors n' stuff
|
||||
|
||||
//
|
||||
|
||||
nsXULContentUtils::nsXULContentUtils()
|
||||
{
|
||||
|
@ -242,19 +250,19 @@ nsXULContentUtils::Init()
|
|||
if (gRefCnt++ == 0) {
|
||||
nsresult rv;
|
||||
rv = nsServiceManager::GetService(kRDFServiceCID,
|
||||
nsCOMTypeInfo<nsIRDFService>::GetIID(),
|
||||
NS_GET_IID(nsIRDFService),
|
||||
(nsISupports**) &gRDF);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = nsComponentManager::CreateInstance(kNameSpaceManagerCID,
|
||||
nsnull,
|
||||
nsCOMTypeInfo<nsINameSpaceManager>::GetIID(),
|
||||
NS_GET_IID(nsINameSpaceManager),
|
||||
(void**) &gNameSpaceManager);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = nsComponentManager::CreateInstance(kDateTimeFormatCID,
|
||||
nsnull,
|
||||
nsCOMTypeInfo<nsIDateTimeFormat>::GetIID(),
|
||||
NS_GET_IID(nsIDateTimeFormat),
|
||||
(void**) &gFormat);
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -267,6 +275,13 @@ nsXULContentUtils::Init()
|
|||
entry->mAttributeAtom = NS_NewAtom(entry->mAttributeName);
|
||||
++entry;
|
||||
}
|
||||
|
||||
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_PROGID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// XXX Ignore return values.
|
||||
prefs->GetBoolPref(kDisableXULCachePref, &gDisableXULCache);
|
||||
prefs->RegisterCallback(kDisableXULCachePref, DisableXULCacheChangedCallback, nsnull);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -332,7 +347,7 @@ NS_NewXULContentUtils(nsISupports* aOuter, const nsIID& aIID, void** aResult)
|
|||
//------------------------------------------------------------------------
|
||||
// nsISupports methods
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsXULContentUtils, nsCOMTypeInfo<nsIXULContentUtils>::GetIID());
|
||||
NS_IMPL_ISUPPORTS(nsXULContentUtils, NS_GET_IID(nsIXULContentUtils));
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// nsIXULContentUtils methods
|
||||
|
@ -349,7 +364,7 @@ nsXULContentUtils::AttachTextNode(nsIContent* parent, nsIRDFNode* value)
|
|||
nsCOMPtr<nsITextContent> text;
|
||||
rv = nsComponentManager::CreateInstance(kTextNodeCID,
|
||||
nsnull,
|
||||
nsITextContent::GetIID(),
|
||||
NS_GET_IID(nsITextContent),
|
||||
getter_AddRefs(text));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
@ -948,3 +963,32 @@ nsXULContentUtils::GetEventHandlerIID(nsIAtom* aName, nsIID* aIID, PRBool* aFoun
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP_(PRBool)
|
||||
nsXULContentUtils::UseXULCache()
|
||||
{
|
||||
return !gDisableXULCache;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
int
|
||||
nsXULContentUtils::DisableXULCacheChangedCallback(const char* aPref, void* aClosure)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_PROGID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
prefs->GetBoolPref(kDisableXULCachePref, &gDisableXULCache);
|
||||
}
|
||||
|
||||
// Flush the cache, regardless
|
||||
NS_WITH_SERVICE(nsIXULPrototypeCache, cache, kXULPrototypeCacheCID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
cache->Flush();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "nsIChromeRegistry.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsICSSStyleSheet.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
|
@ -196,7 +197,7 @@ nsINameSpaceManager* nsXULDocument::gNameSpaceManager;
|
|||
PRInt32 nsXULDocument::kNameSpaceID_XUL;
|
||||
|
||||
nsIXULContentUtils* nsXULDocument::gXULUtils;
|
||||
nsIXULPrototypeCache* nsXULDocument::gXULPrototypeCache;
|
||||
nsIXULPrototypeCache* nsXULDocument::gXULCache;
|
||||
|
||||
PRLogModuleInfo* nsXULDocument::gXULLog;
|
||||
|
||||
|
@ -330,9 +331,9 @@ nsXULDocument::~nsXULDocument()
|
|||
gXULUtils = nsnull;
|
||||
}
|
||||
|
||||
if (gXULPrototypeCache) {
|
||||
nsServiceManager::ReleaseService(kXULPrototypeCacheCID, gXULPrototypeCache);
|
||||
gXULPrototypeCache = nsnull;
|
||||
if (gXULCache) {
|
||||
nsServiceManager::ReleaseService(kXULPrototypeCacheCID, gXULCache);
|
||||
gXULCache = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -518,6 +519,10 @@ nsXULDocument::StartDocumentLoad(const char* aCommand,
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
#if defined(DEBUG_waterson) || defined(DEBUG_hyatt)
|
||||
mLoadStart = PR_Now();
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIURI> url;
|
||||
rv = aChannel->GetURI(getter_AddRefs(url));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -866,6 +871,15 @@ nsXULDocument::AddStyleSheet(nsIStyleSheet* aSheet)
|
|||
else {
|
||||
mStyleSheets.AppendElement(aSheet);
|
||||
}
|
||||
|
||||
// Put the style sheet into the XUL cache if the XUL cache is
|
||||
// actually enabled and the document is chrome.
|
||||
if (gXULUtils->UseXULCache() && IsChromeURI(mDocumentURL)) {
|
||||
nsCOMPtr<nsICSSStyleSheet> css = do_QueryInterface(aSheet);
|
||||
if (css) {
|
||||
gXULCache->PutStyleSheet(css);
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_ADDREF(aSheet);
|
||||
|
||||
|
@ -902,6 +916,16 @@ NS_IMETHODIMP
|
|||
nsXULDocument::InsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex, PRBool aNotify)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aSheet, "null ptr");
|
||||
|
||||
// Put the style sheet into the XUL cache if the XUL cache is
|
||||
// actually enabled and the document is chrome.
|
||||
if (gXULUtils->UseXULCache() && IsChromeURI(mDocumentURL)) {
|
||||
nsCOMPtr<nsICSSStyleSheet> css = do_QueryInterface(aSheet);
|
||||
if (css) {
|
||||
gXULCache->PutStyleSheet(css);
|
||||
}
|
||||
}
|
||||
|
||||
mStyleSheets.InsertElementAt(aSheet, aIndex + 1); // offset by one for attribute sheet
|
||||
|
||||
NS_ADDREF(aSheet);
|
||||
|
@ -932,6 +956,7 @@ nsXULDocument::InsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex, PRBool
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1055,6 +1080,22 @@ NS_IMETHODIMP
|
|||
nsXULDocument::EndLoad()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// Whack the prototype document into the cache so that the next
|
||||
// time somebody asks for it, they don't need to load it by hand.
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = mCurrentPrototype->GetURI(getter_AddRefs(uri));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (gXULUtils->UseXULCache() && IsChromeURI(mDocumentURL)) {
|
||||
// If it's a 'chrome:' prototype document, then put it into
|
||||
// the prototype cache; other XUL documents will be reloaded
|
||||
// each time.
|
||||
rv = gXULCache->PutPrototype(mCurrentPrototype);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
// Now walk the prototype to build content.
|
||||
rv = PrepareToWalk();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
@ -1856,10 +1897,12 @@ nsXULDocument::CreateFromPrototype(const char* aCommand,
|
|||
|
||||
rv = PrepareStyleSheets(mDocumentURL);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return NS_OK;
|
||||
|
||||
mCommand = aCommand;
|
||||
|
||||
rv = AddPrototypeSheets();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Now create the delegates from the prototype
|
||||
rv = PrepareToWalk();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -3097,7 +3140,7 @@ static const char kXULNameSpaceURI[] = XUL_NAMESPACE_URI;
|
|||
|
||||
rv = nsServiceManager::GetService(kXULPrototypeCacheCID,
|
||||
NS_GET_IID(nsIXULPrototypeCache),
|
||||
(nsISupports**) &gXULPrototypeCache);
|
||||
(nsISupports**) &gXULCache);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
|
@ -4102,14 +4145,17 @@ nsXULDocument::PrepareToWalk()
|
|||
// Push the overlay references onto our overlay processing
|
||||
// stack. GetOverlayReferences() will return an ordered array of
|
||||
// overlay references...
|
||||
nsVoidArray overlays;
|
||||
rv = mCurrentPrototype->GetOverlayReferences(overlays);
|
||||
nsCOMPtr<nsISupportsArray> overlays;
|
||||
rv = mCurrentPrototype->GetOverlayReferences(getter_AddRefs(overlays));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// ...and we preserve this ordering by appending to our
|
||||
// mUnloadedOverlays array in reverse order
|
||||
for (PRInt32 i = overlays.Count() - 1; i >= 0; --i) {
|
||||
mUnloadedOverlays->AppendElement(NS_REINTERPRET_CAST(nsIURI*, overlays[i]));
|
||||
PRUint32 count;
|
||||
overlays->Count(&count);
|
||||
for (PRInt32 i = count - 1; i >= 0; --i) {
|
||||
nsCOMPtr<nsISupports> isupports = dont_AddRef(overlays->ElementAt(i));
|
||||
mUnloadedOverlays->AppendElement(isupports);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4422,11 +4468,15 @@ nsXULDocument::ResumeWalk()
|
|||
|
||||
// Look in the prototype cache for the prototype document with
|
||||
// the specified URI.
|
||||
rv = gXULPrototypeCache->Get(uri, getter_AddRefs(mCurrentPrototype));
|
||||
rv = gXULCache->GetPrototype(uri, getter_AddRefs(mCurrentPrototype));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (mCurrentPrototype) {
|
||||
// Found the overlay's prototype in the cache: walk it!
|
||||
if (gXULUtils->UseXULCache() && mCurrentPrototype) {
|
||||
// Found the overlay's prototype in the cache.
|
||||
rv = AddPrototypeSheets();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Now prepare to walk the prototype to create its content
|
||||
rv = PrepareToWalk();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
@ -4460,6 +4510,15 @@ nsXULDocument::ResumeWalk()
|
|||
|
||||
// If we get here, there is nothing left for us to walk. The content
|
||||
// model is built and ready for layout.
|
||||
#if defined(DEBUG_waterson) || defined(DEBUG_hyatt)
|
||||
{
|
||||
nsTime finish = PR_Now();
|
||||
nsInt64 diff64 = finish - mLoadStart;
|
||||
PRInt32 diff = PRInt32(diff64 / nsInt64(1000));
|
||||
printf("***** XUL document loaded in %ldmsec\n", diff);
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = ResolveForwardReferences();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
@ -4476,6 +4535,21 @@ nsXULDocument::ResumeWalk()
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(DEBUG_waterson) || defined(DEBUG_hyatt)
|
||||
{
|
||||
nsTime finish = PR_Now();
|
||||
nsInt64 diff64 = finish - mLoadStart;
|
||||
PRInt32 diff = PRInt32(diff64 / nsInt64(1000));
|
||||
printf("***** XUL document flowed in %ldmsec\n", diff);
|
||||
}
|
||||
|
||||
{
|
||||
nsInt64 now(PR_Now());
|
||||
now /= nsInt64(1000);
|
||||
printf("### ResumeWalk complete %ld\n", PRInt32(now));
|
||||
}
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -4487,11 +4561,17 @@ nsXULDocument::LoadScript(nsIURI* aURI, const char* aVersion, PRBool* aBlock)
|
|||
nsresult rv;
|
||||
|
||||
// XXX Look in a script cache to see if we already have it
|
||||
nsAutoString script;
|
||||
const char* version;
|
||||
rv = gXULCache->GetScript(aURI, script, &version);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (gXULUtils->UseXULCache() && script.Length()) {
|
||||
// We've found it in the cache. Just re-evaluate it.
|
||||
rv = EvaluateScript(aURI, script, 1, version);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (/* cached */ PR_FALSE) {
|
||||
*aBlock = PR_FALSE;
|
||||
|
||||
// XXX brendan, shaver: do some magic here
|
||||
}
|
||||
else {
|
||||
// Set the current script URL so that the DoneLoadingScript()
|
||||
|
@ -4538,6 +4618,12 @@ nsXULDocument::DoneLoadingScript(nsIUnicharStreamLoader* aLoader,
|
|||
if (NS_SUCCEEDED(aStatus)) {
|
||||
rv = doc->EvaluateScript(doc->mCurrentScriptURL, aData, 1,
|
||||
doc->mCurrentScriptLanguageVersion);
|
||||
|
||||
if (IsChromeURI(doc->mDocumentURL)) {
|
||||
gXULCache->PutScript(doc->mCurrentScriptURL,
|
||||
aData,
|
||||
doc->mCurrentScriptLanguageVersion);
|
||||
}
|
||||
}
|
||||
|
||||
// balance the addref we added in LoadScript()
|
||||
|
@ -4842,10 +4928,23 @@ nsXULDocument::CheckTemplateBuilder(nsIContent* aElement)
|
|||
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to set builder's database");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Force construction of immediate template sub-content _now_.
|
||||
rv = builder->CreateContents(aElement);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create template contents");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsCOMPtr<nsIXULContent> xulcontent = do_QueryInterface(aElement);
|
||||
if (xulcontent) {
|
||||
// Mark the XUL element as being lazy, so the template builder
|
||||
// will run when layout first asks for these nodes.
|
||||
//
|
||||
//rv = xulcontent->ClearLazyState(eTemplateContentsBuilt | eContainerContentsBuilt);
|
||||
//if (NS_FAILED(rv)) return rv;
|
||||
|
||||
xulcontent->SetLazyState(nsIXULContent::eChildrenMustBeRebuilt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
else {
|
||||
// Force construction of immediate template sub-content _now_.
|
||||
rv = builder->CreateContents(aElement);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create template contents");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -4895,6 +4994,45 @@ nsXULDocument::CheckBroadcasterHookup(nsIContent* aElement)
|
|||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsXULDocument::AddPrototypeSheets()
|
||||
{
|
||||
// Add mCurrentPrototype's style sheets to the document.
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> sheets;
|
||||
rv = mCurrentPrototype->GetStyleSheetReferences(getter_AddRefs(sheets));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRUint32 count;
|
||||
sheets->Count(&count);
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsISupports> isupports = dont_AddRef(sheets->ElementAt(i));
|
||||
|
||||
nsCOMPtr<nsIURI> uri = do_QueryInterface(isupports);
|
||||
NS_ASSERTION(uri != nsnull, "not a URI!!!");
|
||||
if (! uri)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
nsCOMPtr<nsICSSStyleSheet> sheet;
|
||||
rv = gXULCache->GetStyleSheet(uri, getter_AddRefs(sheet));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
NS_ASSERTION(sheet != nsnull, "uh oh, sheet wasn't in the cache. go reload it");
|
||||
if (! sheet)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
nsCOMPtr<nsICSSStyleSheet> newsheet;
|
||||
rv = sheet->Clone(*getter_AddRefs(newsheet));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
AddStyleSheet(newsheet);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
// nsXULDocument::OverlayForwardReference
|
||||
|
@ -5324,3 +5462,19 @@ nsXULDocument::ProcessCommonAttributes(nsIContent* aElement)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
nsXULDocument::IsChromeURI(nsIURI* aURI)
|
||||
{
|
||||
nsresult rv;
|
||||
nsXPIDLCString protocol;
|
||||
rv = aURI->GetScheme(getter_Copies(protocol));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (PL_strcmp(protocol, "chrome") == 0) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "nsIXULDocument.h"
|
||||
#include "nsIXULPrototypeDocument.h"
|
||||
#include "nsRDFDOMNodeList.h"
|
||||
#include "nsTime.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsWeakPtr.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
@ -459,7 +460,7 @@ protected:
|
|||
static PRInt32 kNameSpaceID_XUL;
|
||||
|
||||
static nsIXULContentUtils* gXULUtils;
|
||||
static nsIXULPrototypeCache* gXULPrototypeCache;
|
||||
static nsIXULPrototypeCache* gXULCache;
|
||||
|
||||
static PRLogModuleInfo* gXULLog;
|
||||
|
||||
|
@ -632,6 +633,11 @@ protected:
|
|||
*/
|
||||
nsresult CheckBroadcasterHookup(nsIContent* aElement);
|
||||
|
||||
/**
|
||||
* Add the current prototype's style sheets to the document.
|
||||
*/
|
||||
nsresult AddPrototypeSheets();
|
||||
|
||||
/**
|
||||
* Used to resolve broadcaster references
|
||||
*/
|
||||
|
@ -686,6 +692,10 @@ protected:
|
|||
nsresult
|
||||
ProcessCommonAttributes(nsIContent* aElement);
|
||||
|
||||
static
|
||||
PRBool
|
||||
IsChromeURI(nsIURI* aURI);
|
||||
|
||||
/**
|
||||
* The current prototype that we are walking to construct the
|
||||
* content model.
|
||||
|
@ -714,6 +724,11 @@ protected:
|
|||
* prototype walk.
|
||||
*/
|
||||
nsresult ResumeWalk();
|
||||
|
||||
#if defined(DEBUG_waterson) || defined(DEBUG_hyatt)
|
||||
// timing
|
||||
nsTime mLoadStart;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -25,10 +25,14 @@
|
|||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsICSSStyleSheet.h"
|
||||
#include "nsIXULPrototypeCache.h"
|
||||
#include "nsIXULPrototypeDocument.h"
|
||||
#include "nsIURI.h"
|
||||
#include "plhash.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "plstr.h"
|
||||
|
||||
|
||||
class nsXULPrototypeCache : public nsIXULPrototypeCache
|
||||
{
|
||||
|
@ -36,8 +40,16 @@ public:
|
|||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Get(nsIURI* aURI, nsIXULPrototypeDocument** _result);
|
||||
NS_IMETHOD Put(nsIURI* aURI, nsIXULPrototypeDocument* aDocument);
|
||||
NS_IMETHOD GetPrototype(nsIURI* aURI, nsIXULPrototypeDocument** _result);
|
||||
NS_IMETHOD PutPrototype(nsIXULPrototypeDocument* aDocument);
|
||||
|
||||
NS_IMETHOD GetStyleSheet(nsIURI* aURI, nsICSSStyleSheet** _result);
|
||||
NS_IMETHOD PutStyleSheet(nsICSSStyleSheet* aStyleSheet);
|
||||
|
||||
NS_IMETHOD GetScript(nsIURI* aURI, nsString& aScript, const char** aVersion);
|
||||
NS_IMETHOD PutScript(nsIURI* aURI, const nsString& aScript, const char* aVersion);
|
||||
|
||||
NS_IMETHOD Flush();
|
||||
|
||||
protected:
|
||||
friend NS_IMETHODIMP
|
||||
|
@ -45,13 +57,45 @@ protected:
|
|||
|
||||
nsXULPrototypeCache();
|
||||
virtual ~nsXULPrototypeCache();
|
||||
static PRIntn ReleaseTableEntry(PLHashEntry* aHashEntry, PRIntn aIndex, void* aClosure);
|
||||
nsresult Init();
|
||||
|
||||
static PLHashNumber Hash(const void* aKey);
|
||||
static PRIntn CompareKeys(const void* aKey1, const void* aKey2);
|
||||
static PRBool
|
||||
ReleaseScriptEntryEnumFunc(nsHashKey* aKey, void* aData, void* aClosure);
|
||||
|
||||
PLHashTable* mTable;
|
||||
nsSupportsHashtable mPrototypeTable;
|
||||
nsSupportsHashtable mStyleSheetTable;
|
||||
nsHashtable mScriptTable;
|
||||
|
||||
|
||||
class nsIURIKey : public nsHashKey {
|
||||
protected:
|
||||
nsCOMPtr<nsIURI> mKey;
|
||||
|
||||
public:
|
||||
nsIURIKey(nsIURI* key) : mKey(key) {}
|
||||
~nsIURIKey(void) {}
|
||||
|
||||
PRUint32 HashValue(void) const {
|
||||
nsXPIDLCString spec;
|
||||
mKey->GetSpec(getter_Copies(spec));
|
||||
return (PRUint32) PL_HashString(spec);
|
||||
}
|
||||
|
||||
PRBool Equals(const nsHashKey *aKey) const {
|
||||
PRBool eq;
|
||||
mKey->Equals( ((nsIURIKey*) aKey)->mKey, &eq );
|
||||
return eq;
|
||||
}
|
||||
|
||||
nsHashKey *Clone(void) const {
|
||||
return new nsIURIKey(mKey);
|
||||
}
|
||||
};
|
||||
|
||||
class ScriptEntry {
|
||||
public:
|
||||
nsString mScript;
|
||||
const char* mVersion;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
@ -64,36 +108,18 @@ nsXULPrototypeCache::nsXULPrototypeCache()
|
|||
|
||||
nsXULPrototypeCache::~nsXULPrototypeCache()
|
||||
{
|
||||
if (mTable) {
|
||||
PL_HashTableEnumerateEntries(mTable, ReleaseTableEntry, nsnull);
|
||||
PL_HashTableDestroy(mTable);
|
||||
}
|
||||
mScriptTable.Enumerate(ReleaseScriptEntryEnumFunc, nsnull);
|
||||
}
|
||||
|
||||
PRIntn
|
||||
nsXULPrototypeCache::ReleaseTableEntry(PLHashEntry* aHashEntry, PRIntn aIndex, void* aClosure)
|
||||
|
||||
PRBool
|
||||
nsXULPrototypeCache::ReleaseScriptEntryEnumFunc(nsHashKey* aKey, void* aData, void* aClosure)
|
||||
{
|
||||
nsIURI* key = NS_REINTERPRET_CAST(nsIURI*, NS_CONST_CAST(void*, aHashEntry->key));
|
||||
NS_RELEASE(key);
|
||||
|
||||
nsIXULPrototypeDocument* value = NS_REINTERPRET_CAST(nsIXULPrototypeDocument*, aHashEntry->value);
|
||||
NS_RELEASE(value);
|
||||
|
||||
return HT_ENUMERATE_REMOVE;
|
||||
ScriptEntry* entry = NS_REINTERPRET_CAST(ScriptEntry*, aData);
|
||||
delete entry;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsXULPrototypeCache::Init()
|
||||
{
|
||||
mTable = PL_NewHashTable(16, Hash, CompareKeys, PL_CompareValues, nsnull, nsnull);
|
||||
if (! mTable)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsXULPrototypeCache, nsIXULPrototypeCache);
|
||||
|
||||
|
||||
|
@ -109,11 +135,6 @@ NS_NewXULPrototypeCache(nsISupports* aOuter, REFNSIID aIID, void** aResult)
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv;
|
||||
rv = result->Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
delete result;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_ADDREF(result);
|
||||
rv = result->QueryInterface(aIID, aResult);
|
||||
|
@ -122,36 +143,98 @@ NS_NewXULPrototypeCache(nsISupports* aOuter, REFNSIID aIID, void** aResult)
|
|||
return rv;
|
||||
}
|
||||
|
||||
PLHashNumber
|
||||
nsXULPrototypeCache::Hash(const void* aKey)
|
||||
{
|
||||
nsIURI* uri = NS_REINTERPRET_CAST(nsIURI*, NS_CONST_CAST(void*, aKey));
|
||||
nsXPIDLCString spec;
|
||||
uri->GetSpec(getter_Copies(spec));
|
||||
return PL_HashString(spec);
|
||||
}
|
||||
|
||||
|
||||
PRIntn
|
||||
nsXULPrototypeCache::CompareKeys(const void* aKey1, const void* aKey2)
|
||||
{
|
||||
nsIURI* uri1 = NS_REINTERPRET_CAST(nsIURI*, NS_CONST_CAST(void*, aKey1));
|
||||
nsIURI* uri2 = NS_REINTERPRET_CAST(nsIURI*, NS_CONST_CAST(void*, aKey2));
|
||||
PRBool eq;
|
||||
uri1->Equals(uri2, &eq);
|
||||
return eq;
|
||||
}
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeCache::Get(nsIURI* aURI, nsIXULPrototypeDocument** _result)
|
||||
nsXULPrototypeCache::GetPrototype(nsIURI* aURI, nsIXULPrototypeDocument** _result)
|
||||
{
|
||||
nsIURIKey key(aURI);
|
||||
*_result = NS_STATIC_CAST(nsIXULPrototypeDocument*, mPrototypeTable.Get(&key));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeCache::Put(nsIURI* aURI, nsIXULPrototypeDocument* aDocument)
|
||||
nsXULPrototypeCache::PutPrototype(nsIXULPrototypeDocument* aDocument)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = aDocument->GetURI(getter_AddRefs(uri));
|
||||
|
||||
nsIURIKey key(uri);
|
||||
mPrototypeTable.Put(&key, aDocument);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeCache::GetStyleSheet(nsIURI* aURI, nsICSSStyleSheet** _result)
|
||||
{
|
||||
nsIURIKey key(aURI);
|
||||
*_result = NS_STATIC_CAST(nsICSSStyleSheet*, mStyleSheetTable.Get(&key));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeCache::PutStyleSheet(nsICSSStyleSheet* aStyleSheet)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = aStyleSheet->GetURL(*getter_AddRefs(uri));
|
||||
|
||||
nsIURIKey key(uri);
|
||||
mStyleSheetTable.Put(&key, aStyleSheet);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeCache::GetScript(nsIURI* aURI, nsString& aScript, const char** aVersion)
|
||||
{
|
||||
nsIURIKey key(aURI);
|
||||
const ScriptEntry* entry = NS_REINTERPRET_CAST(const ScriptEntry*, mScriptTable.Get(&key));
|
||||
if (entry) {
|
||||
aScript = entry->mScript;
|
||||
*aVersion = entry->mVersion;
|
||||
}
|
||||
else {
|
||||
aScript.Truncate();
|
||||
*aVersion = nsnull;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeCache::PutScript(nsIURI* aURI, const nsString& aScript, const char* aVersion)
|
||||
{
|
||||
ScriptEntry* newentry = new ScriptEntry();
|
||||
if (! newentry)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
newentry->mScript = aScript;
|
||||
newentry->mVersion = aVersion;
|
||||
|
||||
nsIURIKey key(aURI);
|
||||
ScriptEntry* oldentry = NS_REINTERPRET_CAST(ScriptEntry*, mScriptTable.Put(&key, newentry));
|
||||
|
||||
delete oldentry;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeCache::Flush()
|
||||
{
|
||||
mPrototypeTable.Reset();
|
||||
mStyleSheetTable.Reset();
|
||||
mScriptTable.Reset(ReleaseScriptEntryEnumFunc, nsnull);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsIStyleSheet.h"
|
||||
#include "nsIXULPrototypeDocument.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsString2.h"
|
||||
|
@ -48,11 +47,11 @@ public:
|
|||
NS_IMETHOD GetRootElement(nsXULPrototypeElement** aResult);
|
||||
NS_IMETHOD SetRootElement(nsXULPrototypeElement* aElement);
|
||||
|
||||
NS_IMETHOD AddStyleSheet(nsIStyleSheet* aStyleSheet);
|
||||
NS_IMETHOD GetStyleSheets(nsVoidArray& aResult);
|
||||
NS_IMETHOD AddStyleSheetReference(nsIURI* aStyleSheet);
|
||||
NS_IMETHOD GetStyleSheetReferences(nsISupportsArray** aResult);
|
||||
|
||||
NS_IMETHOD AddOverlayReference(nsIURI* aURI);
|
||||
NS_IMETHOD GetOverlayReferences(nsVoidArray& aResult);
|
||||
NS_IMETHOD GetOverlayReferences(nsISupportsArray** aResult);
|
||||
|
||||
NS_IMETHOD GetHeaderData(nsIAtom* aField, nsString& aData) const;
|
||||
NS_IMETHOD SetHeaderData(nsIAtom* aField, const nsString& aData);
|
||||
|
@ -60,7 +59,7 @@ public:
|
|||
protected:
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsXULPrototypeElement* mRoot;
|
||||
nsCOMPtr<nsISupportsArray> mStyleSheets;
|
||||
nsCOMPtr<nsISupportsArray> mStyleSheetReferences;
|
||||
nsCOMPtr<nsISupportsArray> mOverlayReferences;
|
||||
|
||||
nsXULPrototypeDocument();
|
||||
|
@ -86,7 +85,7 @@ nsXULPrototypeDocument::Init()
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(mStyleSheets));
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(mStyleSheetReferences));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(mOverlayReferences));
|
||||
|
@ -166,33 +165,22 @@ nsXULPrototypeDocument::SetRootElement(nsXULPrototypeElement* aElement)
|
|||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeDocument::AddStyleSheet(nsIStyleSheet* aStyleSheet)
|
||||
nsXULPrototypeDocument::AddStyleSheetReference(nsIURI* aURI)
|
||||
{
|
||||
NS_PRECONDITION(aStyleSheet != nsnull, "null ptr");
|
||||
if (! aStyleSheet)
|
||||
NS_PRECONDITION(aURI != nsnull, "null ptr");
|
||||
if (! aURI)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
mStyleSheets->AppendElement(aStyleSheet);
|
||||
mStyleSheetReferences->AppendElement(aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeDocument::GetStyleSheets(nsVoidArray& aResult)
|
||||
nsXULPrototypeDocument::GetStyleSheetReferences(nsISupportsArray** aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
aResult.Clear();
|
||||
|
||||
PRUint32 cnt;
|
||||
rv = mStyleSheets->Count(&cnt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
for (PRInt32 i = 0; i < PRInt32(cnt); ++i) {
|
||||
nsIStyleSheet* sheet = NS_REINTERPRET_CAST(nsIStyleSheet*, mStyleSheets->ElementAt(i));
|
||||
aResult.AppendElement(sheet);
|
||||
NS_RELEASE(sheet);
|
||||
}
|
||||
|
||||
*aResult = mStyleSheetReferences;
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -211,21 +199,10 @@ nsXULPrototypeDocument::AddOverlayReference(nsIURI* aURI)
|
|||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeDocument::GetOverlayReferences(nsVoidArray& aResult)
|
||||
nsXULPrototypeDocument::GetOverlayReferences(nsISupportsArray** aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
aResult.Clear();
|
||||
|
||||
PRUint32 cnt;
|
||||
rv = mOverlayReferences->Count(&cnt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
for (PRInt32 i = 0; i < PRInt32(cnt); ++i) {
|
||||
nsIURI* ref = NS_REINTERPRET_CAST(nsIURI*, mOverlayReferences->ElementAt(i));
|
||||
aResult.AppendElement(ref);
|
||||
NS_RELEASE(ref);
|
||||
}
|
||||
|
||||
*aResult = mOverlayReferences;
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче