Convert URL stuff in XBL to use nsIURI instead of strings. Bug 224765, r+sr=bryner

This commit is contained in:
bzbarsky%mit.edu 2003-11-17 21:03:32 +00:00
Родитель ef94d6d3a7
Коммит bfd6b88a89
23 изменённых файлов: 316 добавлений и 322 удалений

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

@ -40,7 +40,7 @@
#include "nsISupports.h"
#include "nsEvent.h"
#include "nsAString.h"
#include "nsString.h"
#include "nsChangeHint.h"
#include "nsCOMArray.h"
#include "nsIDocumentObserver.h"

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

@ -2361,13 +2361,19 @@ nsDocument::LoadBindingDocument(const nsAString& aURL,
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL,
mCharacterSet.get(), GetBaseURL());
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocument> doc;
mBindingManager->LoadBindingDocument(this, aURL, getter_AddRefs(doc));
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(doc));
*aResult = domDoc;
NS_IF_ADDREF(*aResult);
mBindingManager->LoadBindingDocument(this, uri, getter_AddRefs(doc));
if (doc) {
CallQueryInterface(doc, aResult);
}
return NS_OK;
}

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

@ -46,7 +46,6 @@
#ifndef nsIBinding_Manager_h__
#define nsIBinding_Manager_h__
#include "nsString.h"
#include "nsISupports.h"
class nsIContent;
@ -153,7 +152,7 @@ public:
NS_IMETHOD AddLayeredBinding(nsIContent* aContent, nsIURI* aURL) = 0;
NS_IMETHOD RemoveLayeredBinding(nsIContent* aContent, nsIURI* aURL) = 0;
NS_IMETHOD LoadBindingDocument(nsIDocument* aDocument, const nsAString& aURL,
NS_IMETHOD LoadBindingDocument(nsIDocument* aDocument, nsIURI* aURL,
nsIDocument** aResult) = 0;
NS_IMETHOD AddToAttachedQueue(nsIXBLBinding* aBinding)=0;
@ -164,11 +163,11 @@ public:
NS_IMETHOD PutXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo)=0;
NS_IMETHOD RemoveXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo)=0;
NS_IMETHOD GetXBLDocumentInfo(const nsCString& aURL, nsIXBLDocumentInfo** aResult)=0;
NS_IMETHOD GetXBLDocumentInfo(nsIURI* aURI, nsIXBLDocumentInfo** aResult)=0;
NS_IMETHOD PutLoadingDocListener(const nsCString& aURL, nsIStreamListener* aListener) = 0;
NS_IMETHOD GetLoadingDocListener(const nsCString& aURL, nsIStreamListener** aResult) = 0;
NS_IMETHOD RemoveLoadingDocListener(const nsCString& aURL)=0;
NS_IMETHOD PutLoadingDocListener(nsIURI* aURL, nsIStreamListener* aListener) = 0;
NS_IMETHOD GetLoadingDocListener(nsIURI* aURL, nsIStreamListener** aResult) = 0;
NS_IMETHOD RemoveLoadingDocListener(nsIURI* aURL) = 0;
NS_IMETHOD InheritsStyle(nsIContent* aContent, PRBool* aResult) = 0;
NS_IMETHOD FlushSkinBindings() = 0;

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

@ -46,7 +46,6 @@
#ifndef nsIXBLBinding_h__
#define nsIXBLBinding_h__
#include "nsString.h"
#include "nsISupports.h"
#include "nsISupportsArray.h"
@ -56,6 +55,8 @@ class nsIDOMNodeList;
class nsIScriptContext;
class nsXBLPrototypeBinding;
class nsVoidArray;
class nsIURI;
class nsACString;
// {DDDBAD20-C8DF-11d3-97FB-00400553EEF0}
#define NS_IXBLBINDING_IID \
@ -100,9 +101,9 @@ public:
NS_IMETHOD UnhookEventHandlers() = 0;
NS_IMETHOD ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocument) = 0;
NS_IMETHOD GetBindingURI(nsCString& aResult) = 0;
NS_IMETHOD GetDocURI(nsCString& aResult) = 0;
NS_IMETHOD GetID(nsCString& aResult) = 0;
NS_IMETHOD_(nsIURI*) BindingURI() const = 0;
NS_IMETHOD_(nsIURI*) DocURI() const = 0;
NS_IMETHOD GetID(nsACString& aResult) const = 0;
// Get the list of insertion points for aParent. The nsVoidArray is owned
// by the binding, you should not delete it.

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

@ -46,14 +46,14 @@
#ifndef nsIXBLDocumentInfo_h__
#define nsIXBLDocumentInfo_h__
#include "nsString.h"
#include "nsISupports.h"
#include "nsISupportsArray.h"
class nsIContent;
class nsIDocument;
class nsIScriptContext;
class nsXBLPrototypeBinding;
class nsIURI;
class nsACString;
// {5C4D9674-A2CF-4ddf-9F65-E1806C34D28D}
#define NS_IXBLDOCUMENTINFO_IID \
@ -69,7 +69,8 @@ public:
NS_IMETHOD GetScriptAccess(PRBool* aResult)=0;
NS_IMETHOD SetScriptAccess(PRBool aAccess)=0;
NS_IMETHOD GetDocumentURI(nsCString& aDocURI)=0;
/* Never returns null */
NS_IMETHOD_(nsIURI*) DocumentURI()=0;
NS_IMETHOD GetPrototypeBinding(const nsACString& aRef, nsXBLPrototypeBinding** aResult)=0;
NS_IMETHOD SetPrototypeBinding(const nsACString& aRef, nsXBLPrototypeBinding* aBinding)=0;

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

@ -46,7 +46,6 @@
#ifndef nsIXBLService_h__
#define nsIXBLService_h__
#include "nsString.h"
#include "nsISupports.h"
class nsIContent;
@ -73,14 +72,14 @@ public:
nsIXBLBinding** aBinding, PRBool* aResolveStyle) = 0;
// Indicates whether or not a binding is fully loaded.
NS_IMETHOD BindingReady(nsIContent* aBoundElement, const nsCString& aURLStr, PRBool* aIsReady) = 0;
NS_IMETHOD BindingReady(nsIContent* aBoundElement, nsIURI* aURI, PRBool* aIsReady) = 0;
// Retrieves our base class (e.g., tells us what type of frame and content node to build)
NS_IMETHOD ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom** aResult) = 0;
// This method checks the hashtable and then calls FetchBindingDocument on a miss.
NS_IMETHOD LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aBoundDocument,
const nsCString& aURI, const nsCString& aRef,
nsIURI* aBindingURI,
PRBool aForceSyncLoad, nsIXBLDocumentInfo** aResult) = 0;
// Hooks up the global key and DragDrop event handlers to the document root.

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

@ -41,10 +41,11 @@
#include "nsCOMPtr.h"
#include "nsIXBLService.h"
#include "nsIInputStream.h"
#include "nsHashtable.h"
#include "nsDoubleHashtable.h"
#include "nsInterfaceHashtable.h"
#include "nsIURI.h"
#include "nsIURL.h"
#include "nsURIHashKey.h"
#include "nsIChannel.h"
#include "nsXPIDLString.h"
#include "nsIParser.h"
@ -175,28 +176,6 @@ nsAnonymousContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
return NS_ERROR_FAILURE;
}
// nsDoubleHashtable stuff to create a generic string -> nsISupports
// table
class StringToObjectEntry : public PLDHashCStringEntry {
public:
StringToObjectEntry(const void* aKey) : PLDHashCStringEntry(aKey) {
MOZ_COUNT_CTOR(StringToObjectEntry);
}
~StringToObjectEntry() {
MOZ_COUNT_DTOR(StringToObjectEntry);
}
nsISupports* GetValue() { return mValue; }
void SetValue(nsISupports* aValue) { mValue = aValue; }
private:
nsCOMPtr<nsISupports> mValue;
};
DECL_DHASH_WRAPPER(StringToObjectTable, StringToObjectEntry, nsACString&)
DHASH_WRAPPER(StringToObjectTable, StringToObjectEntry, nsACString&)
//
// Generic pldhash table stuff for mapping one nsISupports to another
//
@ -354,7 +333,7 @@ public:
NS_IMETHOD AddLayeredBinding(nsIContent* aContent, nsIURI* aURL);
NS_IMETHOD RemoveLayeredBinding(nsIContent* aContent, nsIURI* aURL);
NS_IMETHOD LoadBindingDocument(nsIDocument* aBoundDoc, const nsAString& aURL,
NS_IMETHOD LoadBindingDocument(nsIDocument* aBoundDoc, nsIURI* aURL,
nsIDocument** aResult);
NS_IMETHOD AddToAttachedQueue(nsIXBLBinding* aBinding);
@ -364,12 +343,12 @@ public:
NS_IMETHOD ExecuteDetachedHandlers();
NS_IMETHOD PutXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo);
NS_IMETHOD GetXBLDocumentInfo(const nsCString& aURL, nsIXBLDocumentInfo** aResult);
NS_IMETHOD GetXBLDocumentInfo(nsIURI* aURI, nsIXBLDocumentInfo** aResult);
NS_IMETHOD RemoveXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo);
NS_IMETHOD PutLoadingDocListener(const nsCString& aURL, nsIStreamListener* aListener);
NS_IMETHOD GetLoadingDocListener(const nsCString& aURL, nsIStreamListener** aResult);
NS_IMETHOD RemoveLoadingDocListener(const nsCString& aURL);
NS_IMETHOD PutLoadingDocListener(nsIURI* aURL, nsIStreamListener* aListener);
NS_IMETHOD GetLoadingDocListener(nsIURI* aURL, nsIStreamListener** aResult);
NS_IMETHOD RemoveLoadingDocListener(nsIURI* aURL);
NS_IMETHOD InheritsStyle(nsIContent* aContent, PRBool* aResult);
NS_IMETHOD FlushSkinBindings();
@ -443,12 +422,12 @@ protected:
// A mapping from a URL (a string) to nsIXBLDocumentInfo*. This table
// is the cache of all binding documents that have been loaded by a
// given bound document.
StringToObjectTable mDocumentTable;
nsInterfaceHashtable<nsURIHashKey,nsIXBLDocumentInfo> mDocumentTable;
// A mapping from a URL (a string) to a nsIStreamListener. This
// table is the currently loading binding docs. If they're in this
// table, they have not yet finished loading.
StringToObjectTable mLoadingDocTable;
nsInterfaceHashtable<nsURIHashKey,nsIStreamListener> mLoadingDocTable;
// A queue of binding attached event handlers that are awaiting
// execution.
@ -835,14 +814,10 @@ nsBindingManager::RemoveLayeredBinding(nsIContent* aContent, nsIURI* aURL)
NS_ENSURE_FALSE(nextBinding, NS_ERROR_FAILURE);
// Make sure that the binding has the URI that is requested to be removed
nsCAutoString bindingUriStr;
binding->GetBindingURI(bindingUriStr);
nsCOMPtr<nsIURI> bindingUri;
nsresult rv = NS_NewURI(getter_AddRefs(bindingUri), bindingUriStr);
NS_ENSURE_SUCCESS(rv, rv);
nsIURI* bindingUri = binding->BindingURI();
PRBool equalUri;
rv = aURL->Equals(bindingUri, &equalUri);
nsresult rv = aURL->Equals(bindingUri, &equalUri);
NS_ENSURE_SUCCESS(rv, rv);
if (!equalUri) {
return NS_OK;
@ -881,16 +856,14 @@ nsBindingManager::RemoveLayeredBinding(nsIContent* aContent, nsIURI* aURL)
NS_IMETHODIMP
nsBindingManager::LoadBindingDocument(nsIDocument* aBoundDoc,
const nsAString& aURL,
nsIURI* aURL,
nsIDocument** aResult)
{
NS_ConvertUCS2toUTF8 url(aURL);
NS_PRECONDITION(aURL, "Must have a URI to load!");
nsCAutoString otherScheme;
nsCOMPtr<nsIIOService> ioService = do_GetIOService();
if (!ioService) return NS_ERROR_FAILURE;
ioService->ExtractScheme(url, otherScheme);
aURL->GetScheme(otherScheme);
nsCAutoString scheme;
aBoundDoc->GetDocumentURL()->GetScheme(scheme);
@ -904,11 +877,14 @@ nsBindingManager::LoadBindingDocument(nsIDocument* aBoundDoc,
// Load the binding doc.
nsCOMPtr<nsIXBLDocumentInfo> info;
xblService->LoadBindingDocumentInfo(nsnull, aBoundDoc, url, nsCAutoString(), PR_TRUE, getter_AddRefs(info));
xblService->LoadBindingDocumentInfo(nsnull, aBoundDoc, aURL,
PR_TRUE, getter_AddRefs(info));
if (!info)
return NS_ERROR_FAILURE;
if (!strcmp(scheme.get(), otherScheme.get()))
// XXXbz Why is this based on a scheme comparison? Shouldn't this
// be a real security check???
if (!strcmp(scheme.get(), otherScheme.get()))
info->GetDocument(aResult); // Addref happens here.
return NS_OK;
@ -977,85 +953,68 @@ nsBindingManager::ExecuteDetachedHandlers()
NS_IMETHODIMP
nsBindingManager::PutXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo)
{
if (!mDocumentTable.mHashTable.ops)
mDocumentTable.Init(16);
NS_PRECONDITION(aDocumentInfo, "Must have a non-null documentinfo!");
NS_ENSURE_TRUE(mDocumentTable.IsInitialized() || mDocumentTable.Init(16),
NS_ERROR_OUT_OF_MEMORY);
nsCOMPtr<nsIDocument> doc;
aDocumentInfo->GetDocument(getter_AddRefs(doc));
NS_ENSURE_TRUE(mDocumentTable.Put(aDocumentInfo->DocumentURI(),
aDocumentInfo),
NS_ERROR_OUT_OF_MEMORY);
nsCAutoString str;
doc->GetDocumentURL()->GetSpec(str);
StringToObjectEntry* entry = mDocumentTable.AddEntry(str);
if (!entry) return NS_ERROR_OUT_OF_MEMORY;
entry->SetValue(aDocumentInfo);
return NS_OK;
}
NS_IMETHODIMP
nsBindingManager::RemoveXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo)
{
if (!mDocumentTable.mHashTable.ops)
if (!mDocumentTable.IsInitialized())
return NS_OK;
nsCOMPtr<nsIDocument> doc;
aDocumentInfo->GetDocument(getter_AddRefs(doc));
nsCAutoString str;
doc->GetDocumentURL()->GetSpec(str);
mDocumentTable.Remove(str);
mDocumentTable.Remove(aDocumentInfo->DocumentURI());
return NS_OK;
}
NS_IMETHODIMP
nsBindingManager::GetXBLDocumentInfo(const nsCString& aURL, nsIXBLDocumentInfo** aResult)
nsBindingManager::GetXBLDocumentInfo(nsIURI* aURL, nsIXBLDocumentInfo** aResult)
{
*aResult = nsnull;
if (!mDocumentTable.mHashTable.ops)
if (!mDocumentTable.IsInitialized())
return NS_OK;
StringToObjectEntry *entry = mDocumentTable.GetEntry(aURL);
if (entry) {
*aResult = NS_STATIC_CAST(nsIXBLDocumentInfo*, entry->GetValue());
NS_IF_ADDREF(*aResult);
}
mDocumentTable.Get(aURL, aResult);
return NS_OK;
}
NS_IMETHODIMP
nsBindingManager::PutLoadingDocListener(const nsCString& aURL, nsIStreamListener* aListener)
nsBindingManager::PutLoadingDocListener(nsIURI* aURL, nsIStreamListener* aListener)
{
if (!mLoadingDocTable.mHashTable.ops)
mLoadingDocTable.Init(16);
StringToObjectEntry* entry = mLoadingDocTable.AddEntry(aURL);
if (!entry) return NS_ERROR_OUT_OF_MEMORY;
entry->SetValue(aListener);
NS_PRECONDITION(aListener, "Must have a non-null listener!");
NS_ENSURE_TRUE(mLoadingDocTable.IsInitialized() || mLoadingDocTable.Init(16),
NS_ERROR_OUT_OF_MEMORY);
NS_ENSURE_TRUE(mLoadingDocTable.Put(aURL, aListener),
NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
NS_IMETHODIMP
nsBindingManager::GetLoadingDocListener(const nsCString& aURL, nsIStreamListener** aResult)
nsBindingManager::GetLoadingDocListener(nsIURI* aURL, nsIStreamListener** aResult)
{
*aResult = nsnull;
if (!mLoadingDocTable.mHashTable.ops)
if (!mLoadingDocTable.IsInitialized())
return NS_OK;
StringToObjectEntry* entry = mLoadingDocTable.GetEntry(aURL);
if (entry) {
*aResult = NS_STATIC_CAST(nsIStreamListener*, entry->GetValue());
NS_IF_ADDREF(*aResult);
}
mLoadingDocTable.Get(aURL, aResult);
return NS_OK;
}
NS_IMETHODIMP
nsBindingManager::RemoveLoadingDocListener(const nsCString& aURL)
nsBindingManager::RemoveLoadingDocListener(nsIURI* aURL)
{
if (!mLoadingDocTable.mHashTable.ops)
if (!mLoadingDocTable.IsInitialized())
return NS_OK;
mLoadingDocTable.Remove(aURL);
@ -1074,16 +1033,12 @@ MarkForDeath(PLDHashTable* aTable, PLDHashEntryHdr* aHdr, PRUint32 aNumber, void
if (marked)
return PL_DHASH_NEXT; // Already marked for death.
nsCAutoString uriStr;
binding->GetDocURI(uriStr);
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), uriStr);
if (uri) {
nsCAutoString path;
uri->GetPath(path);
if (!strncmp(path.get(), "/skin", 5))
binding->MarkForDeath();
}
nsCAutoString path;
nsIURI* uri = binding->DocURI()->GetPath(path);
if (!strncmp(path.get(), "/skin", 5))
binding->MarkForDeath();
return PL_DHASH_NEXT;
}

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

@ -522,7 +522,7 @@ nsXBLBinding::GenerateAnonymousContent()
message += id;
message += " and found in the file ";
nsCAutoString uri;
mPrototypeBinding->GetDocURI(uri);
mPrototypeBinding->DocURI()->GetSpec(uri);
message += uri;
message += " is still using the deprecated\n<content includes=\"\"> syntax! Use <children> instead!\n";
NS_WARNING(message.get());
@ -1019,20 +1019,20 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen
return NS_OK;
}
NS_IMETHODIMP
nsXBLBinding::GetBindingURI(nsCString& aResult)
NS_IMETHODIMP_(nsIURI*)
nsXBLBinding::BindingURI() const
{
return mPrototypeBinding->GetBindingURI(aResult);
return mPrototypeBinding->BindingURI();
}
NS_IMETHODIMP_(nsIURI*)
nsXBLBinding::DocURI() const
{
return mPrototypeBinding->DocURI();
}
NS_IMETHODIMP
nsXBLBinding::GetDocURI(nsCString& aResult)
{
return mPrototypeBinding->GetDocURI(aResult);
}
NS_IMETHODIMP
nsXBLBinding::GetID(nsCString& aResult)
nsXBLBinding::GetID(nsACString& aResult) const
{
return mPrototypeBinding->GetID(aResult);
}

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

@ -95,9 +95,9 @@ class nsXBLBinding: public nsIXBLBinding
NS_IMETHOD UnhookEventHandlers();
NS_IMETHOD ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocument);
NS_IMETHOD GetBindingURI(nsCString& aResult);
NS_IMETHOD GetDocURI(nsCString& aResult);
NS_IMETHOD GetID(nsCString& aResult);
NS_IMETHOD_(nsIURI*) BindingURI() const;
NS_IMETHOD_(nsIURI*) DocURI() const;
NS_IMETHOD GetID(nsACString& aResult) const;
NS_IMETHOD GetInsertionPointsFor(nsIContent* aParent, nsVoidArray** aResult);

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

@ -237,9 +237,15 @@ nsXBLContentSink::HandleStartElement(const PRUnichar *aName,
if (NS_FAILED(rv))
return rv;
if (mState == eXBL_InBinding && !mBinding)
if (mState == eXBL_InBinding && !mBinding) {
// XXX need to return nsresult here. Need error-handling in this
// file in general.
ConstructBinding();
if (!mBinding) {
return NS_ERROR_UNEXPECTED;
}
}
return rv;
}
@ -449,9 +455,16 @@ nsXBLContentSink::ConstructBinding()
nsCAutoString cid; cid.AssignWithConversion(id);
if (!cid.IsEmpty()) {
mBinding = new nsXBLPrototypeBinding(cid, mDocInfo, binding);
mDocInfo->SetPrototypeBinding(cid, mBinding);
binding->UnsetAttr(kNameSpaceID_None, nsHTMLAtoms::id, PR_FALSE);
mBinding = new nsXBLPrototypeBinding();
if (mBinding) {
if (NS_SUCCEEDED(mBinding->Init(cid, mDocInfo, binding))) {
mDocInfo->SetPrototypeBinding(cid, mBinding);
binding->UnsetAttr(kNameSpaceID_None, nsHTMLAtoms::id, PR_FALSE);
} else {
delete mBinding;
mBinding = nsnull;
}
}
}
}

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

@ -360,15 +360,12 @@ static PRBool IsChromeOrResourceURI(nsIURI* aURI)
/* Implementation file */
NS_IMPL_ISUPPORTS3(nsXBLDocumentInfo, nsIXBLDocumentInfo, nsIScriptGlobalObjectOwner, nsISupportsWeakReference)
nsXBLDocumentInfo::nsXBLDocumentInfo(const char* aDocURI, nsIDocument* aDocument)
nsXBLDocumentInfo::nsXBLDocumentInfo(nsIDocument* aDocument)
: mDocument(aDocument),
mScriptAccess(PR_TRUE),
mBindingTable(nsnull)
{
/* member initializers and constructor code */
mDocURI = aDocURI;
mDocument = aDocument;
mScriptAccess = PR_TRUE;
mBindingTable = nsnull;
nsIURI *uri = mDocument->GetDocumentURL();
nsIURI* uri = aDocument->GetDocumentURL();
if (IsChromeOrResourceURI(uri)) {
// Cache whether or not this chrome XBL can execute scripts.
nsCOMPtr<nsIXULChromeRegistry> reg(do_GetService(NS_CHROMEREGISTRY_CONTRACTID));
@ -483,12 +480,14 @@ nsXBLDocumentInfo::ReportScriptError(nsIScriptError *errorObject)
nsresult NS_NewXBLDocumentInfo(nsIDocument* aDocument, nsIXBLDocumentInfo** aResult)
{
nsCAutoString str;
aDocument->GetDocumentURL()->GetSpec(str);
NS_PRECONDITION(aDocument, "Must have a document!");
*aResult = new nsXBLDocumentInfo(str.get(), aDocument);
NS_IF_ADDREF(*aResult);
*aResult = new nsXBLDocumentInfo(aDocument);
if (!*aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(*aResult);
return NS_OK;
}

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

@ -48,15 +48,15 @@ class nsXBLDocumentInfo : public nsIXBLDocumentInfo, public nsIScriptGlobalObjec
public:
NS_DECL_ISUPPORTS
nsXBLDocumentInfo(const char* aDocURI, nsIDocument* aDocument);
nsXBLDocumentInfo(nsIDocument* aDocument);
virtual ~nsXBLDocumentInfo();
NS_IMETHOD GetDocument(nsIDocument** aResult) { *aResult = mDocument; NS_IF_ADDREF(*aResult); return NS_OK; };
NS_IMETHOD GetDocument(nsIDocument** aResult) { NS_ADDREF(*aResult = mDocument); return NS_OK; };
NS_IMETHOD GetScriptAccess(PRBool* aResult) { *aResult = mScriptAccess; return NS_OK; };
NS_IMETHOD SetScriptAccess(PRBool aAccess) { mScriptAccess = aAccess; return NS_OK; };
NS_IMETHOD GetDocumentURI(nsCString& aDocURI) { aDocURI = mDocURI; return NS_OK; };
NS_IMETHOD_(nsIURI*) DocumentURI() { return mDocument->GetDocumentURL(); };
NS_IMETHOD GetPrototypeBinding(const nsACString& aRef, nsXBLPrototypeBinding** aResult);
NS_IMETHOD SetPrototypeBinding(const nsACString& aRef, nsXBLPrototypeBinding* aBinding);
@ -68,7 +68,6 @@ public:
private:
nsCOMPtr<nsIDocument> mDocument;
nsCString mDocURI;
PRBool mScriptAccess;
// the binding table owns each nsXBLPrototypeBinding
nsObjectHashtable* mBindingTable;

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

@ -190,7 +190,7 @@ NS_NewXBLProtoImpl(nsXBLPrototypeBinding* aBinding,
if (aClassName)
impl->mClassName.AssignWithConversion(aClassName);
else
aBinding->GetBindingURI(impl->mClassName);
aBinding->BindingURI()->GetSpec(impl->mClassName);
aBinding->SetImplementation(impl);
*aResult = impl;

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

@ -220,9 +220,7 @@ static const PRInt32 kInsInitialSize = (NS_SIZE_IN_HEAP(sizeof(nsXBLInsertionPoi
// Implementation /////////////////////////////////////////////////////////////////
// Constructors/Destructors
nsXBLPrototypeBinding::nsXBLPrototypeBinding(const nsACString& aID,
nsIXBLDocumentInfo* aInfo,
nsIContent* aElement)
nsXBLPrototypeBinding::nsXBLPrototypeBinding()
: mImplementation(nsnull),
mBaseBinding(nsnull),
mInheritStyle(PR_TRUE),
@ -233,22 +231,43 @@ nsXBLPrototypeBinding::nsXBLPrototypeBinding(const nsACString& aID,
mInsertionPointTable(nsnull),
mInterfaceTable(nsnull)
{
mID = ToNewCString(aID);
mXBLDocInfoWeak = do_GetWeakReference(aInfo);
gRefCnt++;
// printf("REF COUNT UP: %d %s\n", gRefCnt, (const char*)mID);
if (gRefCnt == 1) {
kAttrPool = new nsFixedSizeAllocator();
kAttrPool->Init("XBL Attribute Entries", kAttrBucketSizes, kAttrNumBuckets, kAttrInitialSize);
if (kAttrPool) {
kAttrPool->Init("XBL Attribute Entries", kAttrBucketSizes, kAttrNumBuckets, kAttrInitialSize);
}
kInsPool = new nsFixedSizeAllocator();
kInsPool->Init("XBL Insertion Point Entries", kInsBucketSizes, kInsNumBuckets, kInsInitialSize);
if (kInsPool) {
kInsPool->Init("XBL Insertion Point Entries", kInsBucketSizes, kInsNumBuckets, kInsInitialSize);
}
}
}
nsresult
nsXBLPrototypeBinding::Init(const nsACString& aID,
nsIXBLDocumentInfo* aInfo,
nsIContent* aElement)
{
if (!kAttrPool || !kInsPool) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_NewURI(getter_AddRefs(uri),
NS_LITERAL_CSTRING("#") + aID,
nsnull,
aInfo->DocumentURI());
NS_ENSURE_SUCCESS(rv, rv);
mBindingURI = do_QueryInterface(uri, &rv);
NS_ENSURE_SUCCESS(rv, rv);
mXBLDocInfoWeak = do_GetWeakReference(aInfo);
SetBindingElement(aElement);
return NS_OK;
}
void
@ -263,7 +282,6 @@ nsXBLPrototypeBinding::Initialize()
nsXBLPrototypeBinding::~nsXBLPrototypeBinding(void)
{
nsMemory::Free(mID);
delete mResources;
delete mAttributeTable;
delete mInsertionPointTable;
@ -308,32 +326,12 @@ nsXBLPrototypeBinding::SetBindingElement(nsIContent* aElement)
mInheritStyle = PR_FALSE;
}
nsresult
nsXBLPrototypeBinding::GetBindingURI(nsCString& aResult)
nsIURI*
nsXBLPrototypeBinding::DocURI() const
{
nsCOMPtr<nsIXBLDocumentInfo> info = GetXBLDocumentInfo(nsnull);
NS_ASSERTION(info, "The prototype binding has somehow lost its XBLDocInfo! Bad bad bad!!!\n");
if (!info)
return NS_ERROR_FAILURE;
info->GetDocumentURI(aResult);
aResult += "#";
aResult += mID;
return NS_OK;
}
nsresult
nsXBLPrototypeBinding::GetDocURI(nsCString& aResult)
{
nsCOMPtr<nsIXBLDocumentInfo> info = GetXBLDocumentInfo(nsnull);
NS_ASSERTION(info, "The prototype binding has somehow lost its XBLDocInfo! Bad bad bad!!!\n");
if (!info)
return NS_ERROR_FAILURE;
info->GetDocumentURI(aResult);
return NS_OK;
return info->DocumentURI();
}
nsresult
@ -393,7 +391,7 @@ nsXBLPrototypeBinding::BindingDetached(nsIDOMEventReceiver* aReceiver)
}
already_AddRefed<nsIXBLDocumentInfo>
nsXBLPrototypeBinding::GetXBLDocumentInfo(nsIContent* aBoundElement)
nsXBLPrototypeBinding::GetXBLDocumentInfo(nsIContent* aBoundElement) const
{
nsIXBLDocumentInfo* result = nsnull;
CallQueryReferent(mXBLDocInfoWeak.get(), &result); // addrefs

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

@ -50,6 +50,7 @@
#include "nsHashtable.h"
#include "nsIXBLDocumentInfo.h"
#include "nsCOMArray.h"
#include "nsIURL.h"
class nsIAtom;
class nsIDocument;
@ -74,9 +75,9 @@ public:
already_AddRefed<nsIContent> GetBindingElement();
void SetBindingElement(nsIContent* aElement);
nsresult GetBindingURI(nsCString& aResult);
nsresult GetDocURI(nsCString& aResult);
nsresult GetID(nsCString& aResult) { aResult = mID; return NS_OK; }
nsIURI* BindingURI() const { return mBindingURI; }
nsIURI* DocURI() const;
nsresult GetID(nsACString& aResult) const { return mBindingURI->GetRef(aResult); }
nsresult GetAllowScripts(PRBool* aResult);
@ -111,7 +112,7 @@ public:
nsXBLPrototypeBinding* GetBasePrototype() { return mBaseBinding; }
already_AddRefed<nsIXBLDocumentInfo>
GetXBLDocumentInfo(nsIContent* aBoundElement);
GetXBLDocumentInfo(nsIContent* aBoundElement) const;
PRBool HasBasePrototype() { return mHasBaseProto; }
void SetHasBasePrototype(PRBool aHasBase) { mHasBaseProto = aHasBase; }
@ -160,9 +161,17 @@ public:
}
public:
nsXBLPrototypeBinding(const nsACString& aRef, nsIXBLDocumentInfo* aInfo, nsIContent* aElement);
nsXBLPrototypeBinding();
~nsXBLPrototypeBinding();
// Init must be called after construction to initialize the prototype
// binding. It may well throw errors (eg on out-of-memory). Do not confuse
// this with the Initialize() method, which must be called after the
// binding's handlers, properties, etc are all set.
nsresult Init(const nsACString& aRef,
nsIXBLDocumentInfo* aInfo,
nsIContent* aElement);
nsrefcnt AddRef() {
++mRefCnt;
NS_LOG_ADDREF(this, mRefCnt, "nsXBLPrototypeBinding", sizeof(nsXBLPrototypeBinding));
@ -226,8 +235,7 @@ protected:
// MEMBER VARIABLES
protected:
char* mID;
nsCOMPtr<nsIURL> mBindingURI;
nsCOMPtr<nsIContent> mBinding; // Strong. We own a ref to our content element in the binding doc.
nsAutoPtr<nsXBLPrototypeHandler> mPrototypeHandler; // Strong. DocInfo owns us, and we own the handlers.

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

@ -433,7 +433,7 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver,
nsCAutoString bindingURI;
if (mPrototypeBinding)
mPrototypeBinding->GetDocURI(bindingURI);
mPrototypeBinding->DocURI()->GetSpec(bindingURI);
boundContext->CompileEventHandler(scriptObject, onEventAtom, handlerText,
bindingURI.get(),

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

@ -249,8 +249,7 @@ void
nsXBLResourceLoader::NotifyBoundElements()
{
nsCOMPtr<nsIXBLService> xblService(do_GetService("@mozilla.org/xbl;1"));
nsCAutoString bindingURI;
mBinding->GetBindingURI(bindingURI);
nsIURI* bindingURI = mBinding->BindingURI();
PRUint32 eltCount;
mBoundElements->Count(&eltCount);

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

@ -120,11 +120,11 @@ static PRBool IsResourceURI(nsIURI* aURI)
class nsXBLBindingRequest
{
public:
nsCString mBindingURL;
nsCOMPtr<nsIURL> mBindingURL;
nsCOMPtr<nsIContent> mBoundElement;
static nsXBLBindingRequest*
Create(nsFixedSizeAllocator& aPool, const nsCString& aURL, nsIContent* aBoundElement) {
Create(nsFixedSizeAllocator& aPool, nsIURL* aURL, nsIContent* aBoundElement) {
void* place = aPool.Alloc(sizeof(nsXBLBindingRequest));
return place ? ::new (place) nsXBLBindingRequest(aURL, aBoundElement) : nsnull;
}
@ -185,11 +185,10 @@ public:
static int gRefCnt;
protected:
nsXBLBindingRequest(const nsCString& aURL, nsIContent* aBoundElement)
nsXBLBindingRequest(nsIURL* aURL, nsIContent* aBoundElement)
: mBindingURL(aURL),
mBoundElement(aBoundElement)
{
mBindingURL = aURL;
mBoundElement = aBoundElement;
gRefCnt++;
if (gRefCnt == 1) {
CallGetService("@mozilla.org/xbl;1", &gXBLService);
@ -247,7 +246,7 @@ public:
virtual ~nsXBLStreamListener();
void AddRequest(nsXBLBindingRequest* aRequest) { mBindingRequests.AppendElement(aRequest); };
PRBool HasRequest(const nsCString& aURI, nsIContent* aBoundElement);
PRBool HasRequest(nsIURI* aURI, nsIContent* aBoundElement);
private:
nsXBLService* mXBLService; // [WEAK]
@ -350,13 +349,15 @@ nsXBLStreamListener::OnStopRequest(nsIRequest* request, nsISupports* aCtxt, nsre
}
PRBool
nsXBLStreamListener::HasRequest(const nsCString& aURI, nsIContent* aElt)
nsXBLStreamListener::HasRequest(nsIURI* aURI, nsIContent* aElt)
{
// XXX Could be more efficient.
PRUint32 count = mBindingRequests.Count();
for (PRUint32 i = 0; i < count; i++) {
nsXBLBindingRequest* req = (nsXBLBindingRequest*)mBindingRequests.ElementAt(i);
if (req->mBindingURL.Equals(aURI) && req->mBoundElement.get() == aElt)
PRBool eq;
if (req->mBoundElement == aElt &&
NS_SUCCEEDED(req->mBindingURL->Equals(aURI, &eq)) && eq)
return PR_TRUE;
}
@ -391,10 +392,8 @@ nsXBLStreamListener::Load(nsIDOMEvent* aEvent)
// Remove ourselves from the set of pending docs.
nsIBindingManager *bindingManager = doc->GetBindingManager();
nsIURI *uri = mBindingDocument->GetDocumentURL();
nsCAutoString str;
uri->GetSpec(str);
bindingManager->RemoveLoadingDocListener(str);
nsIURI* documentURI = mBindingDocument->GetDocumentURL();
bindingManager->RemoveLoadingDocListener(documentURI);
if (!mBindingDocument->GetRootContent()) {
NS_ERROR("*** XBL doc with no root element! Something went horribly wrong! ***");
@ -404,7 +403,7 @@ nsXBLStreamListener::Load(nsIDOMEvent* aEvent)
// Put our doc info in the doc table.
nsCOMPtr<nsIXBLDocumentInfo> info;
nsIBindingManager *xblDocBindingManager = mBindingDocument->GetBindingManager();
xblDocBindingManager->GetXBLDocumentInfo(str, getter_AddRefs(info));
xblDocBindingManager->GetXBLDocumentInfo(documentURI, getter_AddRefs(info));
xblDocBindingManager->RemoveXBLDocumentInfo(info); // Break the self-imposed cycle.
if (!info) {
NS_ERROR("An XBL file is malformed. Did you forget the XBL namespace on the bindings tag?");
@ -413,7 +412,7 @@ nsXBLStreamListener::Load(nsIDOMEvent* aEvent)
// If the doc is a chrome URI, then we put it into the XUL cache.
#ifdef MOZ_XUL
if (IsChromeOrResourceURI(uri)) {
if (IsChromeOrResourceURI(documentURI)) {
PRBool useXULCache;
gXULCache->GetEnabled(&useXULCache);
if (useXULCache)
@ -553,11 +552,7 @@ nsXBLService::LoadBindings(nsIContent* aContent, nsIURI* aURL, PRBool aAugmentFl
}
else {
// See if the URIs match.
nsCAutoString spec;
styleBinding->GetBindingURI(spec);
nsCOMPtr<nsIURI> uri;
// XXX This needs an origin charset.
NS_NewURI(getter_AddRefs(uri), spec.get());
nsIURI* uri = styleBinding->BindingURI();
PRBool equal;
if (NS_SUCCEEDED(uri->Equals(aURL, &equal)) && equal)
return NS_OK;
@ -581,9 +576,7 @@ nsXBLService::LoadBindings(nsIContent* aContent, nsIURI* aURL, PRBool aAugmentFl
return rv;
}
nsCOMPtr<nsIXBLBinding> newBinding;
nsCAutoString spec;
aURL->GetSpec(spec);
if (NS_FAILED(rv = GetBinding(aContent, spec, getter_AddRefs(newBinding)))) {
if (NS_FAILED(rv = GetBinding(aContent, aURL, getter_AddRefs(newBinding)))) {
return rv;
}
@ -696,7 +689,7 @@ nsXBLService::ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom**
}
nsresult
nsXBLService::GetXBLDocumentInfo(const nsCString& aURLStr, nsIContent* aBoundElement, nsIXBLDocumentInfo** aResult)
nsXBLService::GetXBLDocumentInfo(nsIURI* aURI, nsIContent* aBoundElement, nsIXBLDocumentInfo** aResult)
{
*aResult = nsnull;
@ -707,7 +700,7 @@ nsXBLService::GetXBLDocumentInfo(const nsCString& aURLStr, nsIContent* aBoundEle
// The first line of defense is the chrome cache.
// This cache crosses the entire product, so any XBL bindings that are
// part of chrome will be reused across all XUL documents.
gXULCache->GetXBLDocumentInfo(aURLStr, aResult);
gXULCache->GetXBLDocumentInfo(aURI, aResult);
}
#endif
@ -715,7 +708,7 @@ nsXBLService::GetXBLDocumentInfo(const nsCString& aURLStr, nsIContent* aBoundEle
// The second line of defense is the binding manager's document table.
nsIDocument* boundDocument = aBoundElement->GetDocument();
if (boundDocument)
boundDocument->GetBindingManager()->GetXBLDocumentInfo(aURLStr, aResult);
boundDocument->GetBindingManager()->GetXBLDocumentInfo(aURI, aResult);
}
return NS_OK;
}
@ -836,22 +829,22 @@ nsXBLService::FlushMemory()
// Internal helper methods ////////////////////////////////////////////////////////////////
nsresult nsXBLService::GetBinding(nsIContent* aBoundElement,
const nsCString& aURLStr,
nsIXBLBinding** aResult)
nsIURI* aURI,
nsIXBLBinding** aResult)
{
PRBool dummy;
return GetBindingInternal(aBoundElement, aURLStr, PR_FALSE, &dummy, aResult);
return GetBindingInternal(aBoundElement, aURI, PR_FALSE, &dummy, aResult);
}
NS_IMETHODIMP nsXBLService::BindingReady(nsIContent* aBoundElement,
const nsCString& aURLStr,
nsIURI* aURI,
PRBool* aIsReady)
{
return GetBindingInternal(aBoundElement, aURLStr, PR_TRUE, aIsReady, nsnull);
return GetBindingInternal(aBoundElement, aURI, PR_TRUE, aIsReady, nsnull);
}
NS_IMETHODIMP nsXBLService::GetBindingInternal(nsIContent* aBoundElement,
const nsCString& aURLStr,
nsIURI* aURI,
PRBool aPeekOnly,
PRBool* aIsReady,
nsIXBLBinding** aResult)
@ -859,24 +852,31 @@ NS_IMETHODIMP nsXBLService::GetBindingInternal(nsIContent* aBoundElement,
if (aResult)
*aResult = nsnull;
if (aURLStr.IsEmpty())
if (!aURI)
return NS_ERROR_FAILURE;
// XXX Obtain the # marker and remove it from the URL.
nsCAutoString uri(aURLStr);
PRInt32 indx = uri.RFindChar('#');
NS_ASSERTION(indx >= 0, "Incorrect syntax for an XBL binding.");
if (indx < 0)
nsCOMPtr<nsIURL> url(do_QueryInterface(aURI));
if (!url) {
#ifdef DEBUG
NS_ERROR("Binding load from a non-URL URI not allowed.");
nsCAutoString spec;
aURI->GetSpec(spec);
fprintf(stderr, "Spec of non-URL URI is: '%s'\n", spec.get());
#endif
return NS_ERROR_FAILURE;
}
nsCAutoString ref;
uri.Right(ref, uri.Length() - (indx + 1));
uri.Truncate(indx);
nsCAutoString ref;
url->GetRef(ref);
NS_ASSERTION(!ref.IsEmpty(), "Incorrect syntax for an XBL binding");
if (ref.IsEmpty())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIDocument> boundDocument = aBoundElement->GetDocument();
nsCOMPtr<nsIXBLDocumentInfo> docInfo;
LoadBindingDocumentInfo(aBoundElement, boundDocument, uri, ref, PR_FALSE, getter_AddRefs(docInfo));
LoadBindingDocumentInfo(aBoundElement, boundDocument, aURI, PR_FALSE,
getter_AddRefs(docInfo));
if (!docInfo)
return NS_ERROR_FAILURE;
@ -909,9 +909,8 @@ NS_IMETHODIMP nsXBLService::GetBindingInternal(nsIContent* aBoundElement,
PRBool hasBase = protoBinding->HasBasePrototype();
nsXBLPrototypeBinding* baseProto = protoBinding->GetBasePrototype();
if (baseProto) {
nsCAutoString url;
baseProto->GetBindingURI(url);
if (NS_FAILED(GetBindingInternal(aBoundElement, url, aPeekOnly, aIsReady, getter_AddRefs(baseBinding))))
if (NS_FAILED(GetBindingInternal(aBoundElement, baseProto->BindingURI(),
aPeekOnly, aIsReady, getter_AddRefs(baseBinding))))
return NS_ERROR_FAILURE; // We aren't ready yet.
}
else if (hasBase) {
@ -978,10 +977,15 @@ NS_IMETHODIMP nsXBLService::GetBindingInternal(nsIContent* aBoundElement,
if (hasExtends && (hasDisplay || nameSpace.IsEmpty())) {
// Look up the prefix.
// We have a base class binding. Load it right now.
NS_ConvertUCS2toUTF8 urlCString(value);
nsCAutoString urlStr;
doc->GetDocumentURL()->Resolve(urlCString, urlStr);
if (NS_FAILED(GetBindingInternal(aBoundElement, urlStr, aPeekOnly, aIsReady, getter_AddRefs(baseBinding))))
nsCOMPtr<nsIURI> bindingURI;
nsresult rv =
NS_NewURI(getter_AddRefs(bindingURI), value,
PromiseFlatCString(doc->GetDocumentCharacterSet()).get(),
doc->GetBaseURL());
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(GetBindingInternal(aBoundElement, bindingURI, aPeekOnly,
aIsReady, getter_AddRefs(baseBinding))))
return NS_ERROR_FAILURE; // Binding not yet ready or an error occurred.
if (!aPeekOnly) {
// Make sure to set the base prototype.
@ -1006,15 +1010,28 @@ NS_IMETHODIMP nsXBLService::GetBindingInternal(nsIContent* aBoundElement,
}
NS_IMETHODIMP
nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aBoundDocument,
const nsCString& aURLStr, const nsCString& aRef,
PRBool aForceSyncLoad, nsIXBLDocumentInfo** aResult)
nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement,
nsIDocument* aBoundDocument,
nsIURI* aBindingURI,
PRBool aForceSyncLoad,
nsIXBLDocumentInfo** aResult)
{
NS_PRECONDITION(aBindingURI, "Must have a binding URI");
nsresult rv = NS_OK;
*aResult = nsnull;
nsCOMPtr<nsIXBLDocumentInfo> info;
nsCOMPtr<nsIURI> uriClone;
rv = aBindingURI->Clone(getter_AddRefs(uriClone));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURL> documentURI(do_QueryInterface(uriClone, &rv));
NS_ENSURE_TRUE(documentURI, rv);
documentURI->SetRef(NS_LITERAL_CSTRING(""));
#ifdef MOZ_XUL
// We've got a file. Check our XBL document cache.
PRBool useXULCache;
@ -1024,7 +1041,7 @@ nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aB
// The first line of defense is the chrome cache.
// This cache crosses the entire product, so that any XBL bindings that are
// part of chrome will be reused across all XUL documents.
gXULCache->GetXBLDocumentInfo(aURLStr, getter_AddRefs(info));
gXULCache->GetXBLDocumentInfo(documentURI, getter_AddRefs(info));
}
#endif
@ -1032,9 +1049,12 @@ nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aB
// The second line of defense is the binding manager's document table.
nsIBindingManager *bindingManager = nsnull;
nsCOMPtr<nsIURL> bindingURL(do_QueryInterface(aBindingURI, &rv));
NS_ENSURE_SUCCESS(rv, rv);
if (aBoundDocument) {
bindingManager = aBoundDocument->GetBindingManager();
bindingManager->GetXBLDocumentInfo(aURLStr, getter_AddRefs(info));
bindingManager->GetXBLDocumentInfo(documentURI, getter_AddRefs(info));
}
nsCOMPtr<nsIAtom> tagName;
@ -1051,16 +1071,13 @@ nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aB
// processed whenever the doc does finish loading.
nsCOMPtr<nsIStreamListener> listener;
if (bindingManager)
bindingManager->GetLoadingDocListener(aURLStr, getter_AddRefs(listener));
bindingManager->GetLoadingDocListener(documentURI, getter_AddRefs(listener));
if (listener) {
nsIStreamListener* ilist = listener.get();
nsXBLStreamListener* xblListener = NS_STATIC_CAST(nsXBLStreamListener*, ilist);
// Create a new load observer.
nsCAutoString bindingURI(aURLStr);
bindingURI += "#";
bindingURI += aRef;
if (!xblListener->HasRequest(bindingURI, aBoundElement)) {
nsXBLBindingRequest* req = nsXBLBindingRequest::Create(mPool, bindingURI, aBoundElement);
if (!xblListener->HasRequest(aBindingURI, aBoundElement)) {
nsXBLBindingRequest* req = nsXBLBindingRequest::Create(mPool, bindingURL, aBoundElement);
xblListener->AddRequest(req);
}
return NS_OK;
@ -1070,21 +1087,19 @@ nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aB
if (!info) {
// Finally, if all lines of defense fail, we go and fetch the binding
// document.
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), aURLStr);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a url");
// Always load chrome synchronously
PRBool chrome;
if (NS_SUCCEEDED(uri->SchemeIs("chrome", &chrome)) && chrome)
if (NS_SUCCEEDED(documentURI->SchemeIs("chrome", &chrome)) && chrome)
aForceSyncLoad = PR_TRUE;
nsCOMPtr<nsIDocument> document;
FetchBindingDocument(aBoundElement, aBoundDocument, uri, aRef, aForceSyncLoad, getter_AddRefs(document));
FetchBindingDocument(aBoundElement, aBoundDocument, documentURI,
bindingURL, aForceSyncLoad, getter_AddRefs(document));
if (document) {
nsIBindingManager *xblDocBindingManager = document->GetBindingManager();
xblDocBindingManager->GetXBLDocumentInfo(aURLStr, getter_AddRefs(info));
xblDocBindingManager->GetXBLDocumentInfo(documentURI, getter_AddRefs(info));
if (!info) {
NS_ERROR("An XBL file is malformed. Did you forget the XBL namespace on the bindings tag?");
return NS_ERROR_FAILURE;
@ -1093,7 +1108,7 @@ nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aB
// If the doc is a chrome URI, then we put it into the XUL cache.
#ifdef MOZ_XUL
if (IsChromeOrResourceURI(uri)) {
if (IsChromeOrResourceURI(documentURI)) {
if (useXULCache)
gXULCache->PutXBLDocumentInfo(info);
}
@ -1118,7 +1133,7 @@ nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aB
nsresult
nsXBLService::FetchBindingDocument(nsIContent* aBoundElement, nsIDocument* aBoundDocument,
nsIURI* aURI, const nsCString& aRef,
nsIURI* aDocumentURI, nsIURL* aBindingURL,
PRBool aForceSyncLoad, nsIDocument** aResult)
{
nsresult rv = NS_OK;
@ -1137,7 +1152,7 @@ nsXBLService::FetchBindingDocument(nsIContent* aBoundElement, nsIDocument* aBoun
if (tagName == nsXULAtoms::scrollbar ||
tagName == nsXULAtoms::thumb ||
tagName == nsHTMLAtoms::select || IsResourceURI(aURI))
tagName == nsHTMLAtoms::select || IsResourceURI(aDocumentURI))
aForceSyncLoad = PR_TRUE;
if(!aForceSyncLoad) {
@ -1146,12 +1161,12 @@ nsXBLService::FetchBindingDocument(nsIContent* aBoundElement, nsIDocument* aBoun
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIChannel> channel;
rv = NS_NewChannel(getter_AddRefs(channel), aURI, nsnull, loadGroup);
rv = NS_NewChannel(getter_AddRefs(channel), aDocumentURI, nsnull, loadGroup);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIStreamListener> listener;
nsCOMPtr<nsIXMLContentSink> xblSink;
NS_NewXBLContentSink(getter_AddRefs(xblSink), doc, aURI, nsnull);
NS_NewXBLContentSink(getter_AddRefs(xblSink), doc, aDocumentURI, nsnull);
if (!xblSink)
return NS_ERROR_FAILURE;
@ -1180,16 +1195,13 @@ nsXBLService::FetchBindingDocument(nsIContent* aBoundElement, nsIDocument* aBoun
else
bindingManager = nsnull;
nsCAutoString uri;
aURI->GetSpec(uri);
if (bindingManager)
bindingManager->PutLoadingDocListener(uri, xblListener);
bindingManager->PutLoadingDocListener(aDocumentURI, xblListener);
// Add our request.
nsCAutoString bindingURI(uri);
bindingURI += "#";
bindingURI += aRef;
nsXBLBindingRequest* req = nsXBLBindingRequest::Create(mPool, bindingURI, aBoundElement);
nsXBLBindingRequest* req = nsXBLBindingRequest::Create(mPool,
aBindingURL,
aBoundElement);
xblListener->AddRequest(req);
// Now kick off the async read.
@ -1206,7 +1218,7 @@ nsXBLService::FetchBindingDocument(nsIContent* aBoundElement, nsIDocument* aBoun
// Open channel
nsCOMPtr<nsIChannel> channel;
rv = NS_NewChannel(getter_AddRefs(channel), aURI, nsnull, loadGroup);
rv = NS_NewChannel(getter_AddRefs(channel), aDocumentURI, nsnull, loadGroup);
NS_ENSURE_SUCCESS(rv, rv);
rv = loader->LoadLocalXBLDocument(channel, getter_AddRefs(domDoc));

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

@ -55,6 +55,7 @@ class nsIDocument;
class nsIAtom;
class nsString;
class nsIURI;
class nsIURL;
class nsSupportsHashtable;
class nsHashtable;
class nsIXULPrototypeCache;
@ -71,14 +72,14 @@ class nsXBLService : public nsIXBLService,
nsIXBLBinding** aBinding, PRBool* aResolveStyle);
// Indicates whether or not a binding is fully loaded.
NS_IMETHOD BindingReady(nsIContent* aBoundElement, const nsCString& aURLStr, PRBool* aIsReady);
NS_IMETHOD BindingReady(nsIContent* aBoundElement, nsIURI* aURI, PRBool* aIsReady);
// Gets the object's base class type.
NS_IMETHOD ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom** aResult);
// This method checks the hashtable and then calls FetchBindingDocument on a miss.
NS_IMETHOD LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aBoundDocument,
const nsCString& aURI, const nsCString& aRef,
nsIURI* aBindingURI,
PRBool aForceSyncLoad, nsIXBLDocumentInfo** aResult);
// Used by XUL key bindings and for window XBL.
@ -95,21 +96,21 @@ public:
nsresult FlushStyleBindings(nsIContent* aContent);
// This method loads a binding doc and then builds the specific binding required.
nsresult GetBinding(nsIContent* aBoundElement, const nsCString& aURLStr, nsIXBLBinding** aResult);
nsresult GetBinding(nsIContent* aBoundElement, nsIURI* aURI, nsIXBLBinding** aResult);
// Release any memory that we can
nsresult FlushMemory();
// This method synchronously loads and parses an XBL file.
nsresult FetchBindingDocument(nsIContent* aBoundElement, nsIDocument* aBoundDocument,
nsIURI* aURI, const nsCString& aRef,
nsIURI* aDocumentURI, nsIURL* aBindingURL,
PRBool aForceSyncLoad, nsIDocument** aResult);
nsresult GetXBLDocumentInfo(const nsCString& aURLStr, nsIContent* aBoundElement, nsIXBLDocumentInfo** aResult);
nsresult GetXBLDocumentInfo(nsIURI* aURI, nsIContent* aBoundElement, nsIXBLDocumentInfo** aResult);
// This method loads a binding doc and then builds the specific binding required. It
// can also peek without building.
NS_IMETHOD GetBindingInternal(nsIContent* aBoundElement, const nsCString& aURLStr,
NS_IMETHOD GetBindingInternal(nsIContent* aBoundElement, nsIURI* aURI,
PRBool aPeekFlag, PRBool* aIsReady, nsIXBLBinding** aResult);
// MEMBER VARIABLES

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

@ -66,6 +66,8 @@
#include "nsIDOMDocument.h"
#include "nsISelectionController.h"
#include "nsXULAtoms.h"
#include "nsIURI.h"
#include "nsNetUtil.h"
class nsXBLSpecialDocInfo
{
@ -74,10 +76,6 @@ public:
nsCOMPtr<nsIXBLDocumentInfo> mPlatformHTMLBindings;
nsCOMPtr<nsIXBLDocumentInfo> mUserHTMLBindings;
nsCString mHTMLBindingStr;
nsCString mPlatformHTMLBindingStr;
nsCString mUserHTMLBindingStr;
static const char sHTMLBindingStr[];
static const char sPlatformHTMLBindingStr[];
static const char sUserHTMLBindingStr[];
@ -109,13 +107,6 @@ void nsXBLSpecialDocInfo::LoadDocInfo()
return;
mInitialized = PR_TRUE;
mHTMLBindingStr = sHTMLBindingStr;
mPlatformHTMLBindingStr = sPlatformHTMLBindingStr;
mUserHTMLBindingStr = sUserHTMLBindingStr;
if (mHTMLBindings && mPlatformHTMLBindings && mUserHTMLBindings)
return;
nsresult rv;
nsCOMPtr<nsIXBLService> xblService =
do_GetService("@mozilla.org/xbl;1", &rv);
@ -123,17 +114,36 @@ void nsXBLSpecialDocInfo::LoadDocInfo()
return;
// Obtain the XP and platform doc infos
nsCOMPtr<nsIURI> bindingURI;
NS_NewURI(getter_AddRefs(bindingURI), sHTMLBindingStr);
if (!bindingURI) {
return;
}
xblService->LoadBindingDocumentInfo(nsnull, nsnull,
mHTMLBindingStr,
nsCAutoString(""), PR_TRUE,
bindingURI,
PR_TRUE,
getter_AddRefs(mHTMLBindings));
rv = bindingURI->SetSpec(NS_LITERAL_CSTRING(sPlatformHTMLBindingStr));
if (NS_FAILED(rv)) {
NS_ERROR("Shouldn't fail to set spec here");
return;
}
xblService->LoadBindingDocumentInfo(nsnull, nsnull,
mPlatformHTMLBindingStr,
nsCAutoString(""), PR_TRUE,
bindingURI,
PR_TRUE,
getter_AddRefs(mPlatformHTMLBindings));
rv = bindingURI->SetSpec(NS_LITERAL_CSTRING(sUserHTMLBindingStr));
if (NS_FAILED(rv)) {
NS_ERROR("Shouldn't fail to set spec here");
return;
}
xblService->LoadBindingDocumentInfo(nsnull, nsnull,
mUserHTMLBindingStr,
nsCAutoString(""), PR_TRUE,
bindingURI,
PR_TRUE,
getter_AddRefs(mUserHTMLBindings));
}

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

@ -82,7 +82,7 @@ public:
NS_IMETHOD PutScript(nsIURI* aURI, void* aScriptObject) = 0;
NS_IMETHOD FlushScripts() = 0;
NS_IMETHOD GetXBLDocumentInfo(const nsCString& aString, nsIXBLDocumentInfo** aResult) = 0;
NS_IMETHOD GetXBLDocumentInfo(nsIURI* aURL, nsIXBLDocumentInfo** aResult) = 0;
NS_IMETHOD PutXBLDocumentInfo(nsIXBLDocumentInfo* aDocument) = 0;
NS_IMETHOD FlushXBLInformation() = 0;

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

@ -89,7 +89,7 @@ public:
NS_IMETHOD PutScript(nsIURI* aURI, void* aScriptObject);
NS_IMETHOD FlushScripts();
NS_IMETHOD GetXBLDocumentInfo(const nsCString& aString, nsIXBLDocumentInfo** _result);
NS_IMETHOD GetXBLDocumentInfo(nsIURI* aURL, nsIXBLDocumentInfo** _result);
NS_IMETHOD PutXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo);
NS_IMETHOD FlushXBLInformation();
NS_IMETHOD FlushSkinFiles();
@ -115,7 +115,7 @@ protected:
nsInterfaceHashtable<nsURIHashKey,nsIXULPrototypeDocument> mPrototypeTable;
nsInterfaceHashtable<nsURIHashKey,nsICSSStyleSheet> mStyleSheetTable;
nsDataHashtable<nsURIHashKey,void*> mScriptTable;
nsInterfaceHashtable<nsCStringHashKey,nsIXBLDocumentInfo> mXBLDocTable;
nsInterfaceHashtable<nsURIHashKey,nsIXBLDocumentInfo> mXBLDocTable;
JSRuntime* mJSRuntime;
@ -364,7 +364,7 @@ nsXULPrototypeCache::FlushScripts()
NS_IMETHODIMP
nsXULPrototypeCache::GetXBLDocumentInfo(const nsCString& aURL, nsIXBLDocumentInfo** aResult)
nsXULPrototypeCache::GetXBLDocumentInfo(nsIURI* aURL, nsIXBLDocumentInfo** aResult)
{
mXBLDocTable.Get(aURL, aResult);
return NS_OK;
@ -374,16 +374,12 @@ nsXULPrototypeCache::GetXBLDocumentInfo(const nsCString& aURL, nsIXBLDocumentInf
NS_IMETHODIMP
nsXULPrototypeCache::PutXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo)
{
nsCOMPtr<nsIDocument> doc;
aDocumentInfo->GetDocument(getter_AddRefs(doc));
nsCAutoString str;
doc->GetDocumentURL()->GetSpec(str);
nsIURI* uri = aDocumentInfo->DocumentURI();
nsCOMPtr<nsIXBLDocumentInfo> info;
mXBLDocTable.Get(str, getter_AddRefs(info));
mXBLDocTable.Get(uri, getter_AddRefs(info));
if (!info)
mXBLDocTable.Put(str, aDocumentInfo);
mXBLDocTable.Put(uri, aDocumentInfo);
return NS_OK;
}
@ -397,12 +393,10 @@ nsXULPrototypeCache::FlushXBLInformation()
}
PR_STATIC_CALLBACK(PLDHashOperator)
FlushSkinXBL(const nsACString& key, nsCOMPtr<nsIXBLDocumentInfo>& aDocInfo, void* aClosure)
FlushSkinXBL(nsIURI* aKey, nsCOMPtr<nsIXBLDocumentInfo>& aDocInfo, void* aClosure)
{
nsCOMPtr<nsIDocument> doc;
aDocInfo->GetDocument(getter_AddRefs(doc));
nsCAutoString str;
doc->GetDocumentURL()->GetPath(str);
aKey->GetPath(str);
PLDHashOperator ret = PL_DHASH_NEXT;
@ -431,7 +425,7 @@ FlushSkinSheets(nsIURI* aKey, nsCOMPtr<nsICSSStyleSheet>& aSheet, void* aClosure
}
PR_STATIC_CALLBACK(PLDHashOperator)
FlushScopedSkinStylesheets(const nsACString& aKey, nsCOMPtr<nsIXBLDocumentInfo> &aDocInfo, void* aClosure)
FlushScopedSkinStylesheets(nsIURI* aKey, nsCOMPtr<nsIXBLDocumentInfo> &aDocInfo, void* aClosure)
{
aDocInfo->FlushSkinStylesheets();
return PL_DHASH_NEXT;

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

@ -229,7 +229,7 @@ inDOMUtils::GetBindingURLs(nsIDOMElement *aElement, nsISimpleEnumerator **_retva
nsCOMPtr<nsIXBLBinding> tempBinding;
while (binding) {
nsCAutoString uri;
binding->GetBindingURI(uri);
binding->BindingURI()->GetSpec(uri);
nsCOMPtr<nsIAtom> atom = do_GetAtom(uri.get());
urls->AppendElement(atom);