diff --git a/mozilla/content/base/public/nsINameSpaceManager.h b/mozilla/content/base/public/nsINameSpaceManager.h index f31a39e5fc3..6cf6a296918 100644 --- a/mozilla/content/base/public/nsINameSpaceManager.h +++ b/mozilla/content/base/public/nsINameSpaceManager.h @@ -30,6 +30,7 @@ class nsIAtom; class nsString; class nsINameSpace; +class nsIElementFactory; #define kNameSpaceID_Unknown -1 #define kNameSpaceID_None 0 @@ -67,17 +68,24 @@ class nsINameSpace; * The "html" and "xml" namespaces come "pre-canned" from the root. * */ -class nsINameSpaceManager : public nsISupports { + +class nsINameSpaceManager : public nsISupports +{ public: - static const nsIID& GetIID() { static nsIID iid = NS_INAMESPACEMANAGER_IID; return iid; } + NS_DEFINE_STATIC_IID_ACCESSOR(NS_INAMESPACEMANAGER_IID) NS_IMETHOD CreateRootNameSpace(nsINameSpace*& aRootNameSpace) = 0; NS_IMETHOD RegisterNameSpace(const nsAReadableString& aURI, PRInt32& aNameSpaceID) = 0; - NS_IMETHOD GetNameSpaceURI(PRInt32 aNameSpaceID, nsAWritableString& aURI) = 0; - NS_IMETHOD GetNameSpaceID(const nsAReadableString& aURI, PRInt32& aNameSpaceID) = 0; + NS_IMETHOD GetNameSpaceURI(PRInt32 aNameSpaceID, + nsAWritableString& aURI) = 0; + NS_IMETHOD GetNameSpaceID(const nsAReadableString& aURI, + PRInt32& aNameSpaceID) = 0; + + NS_IMETHOD GetElementFactory(PRInt32 aNameSpaceID, + nsIElementFactory **aElementFactory) = 0; }; extern NS_LAYOUT nsresult diff --git a/mozilla/content/base/src/nsNameSpaceManager.cpp b/mozilla/content/base/src/nsNameSpaceManager.cpp index e7af2f3b123..c5baec28ff0 100644 --- a/mozilla/content/base/src/nsNameSpaceManager.cpp +++ b/mozilla/content/base/src/nsNameSpaceManager.cpp @@ -22,13 +22,18 @@ #include "nscore.h" #include "nsINameSpaceManager.h" #include "nsINameSpace.h" +#include "nsISupportsArray.h" +#include "nsIElementFactory.h" +#include "nsIServiceManager.h" #include "nsHashtable.h" #include "nsVoidArray.h" #include "nsLayoutAtoms.h" #include "nsString.h" #include "nsCRT.h" +#include "nsContentCID.h" +extern nsresult NS_NewXMLElementFactory(nsIElementFactory** aResult); static const char kXMLNSNameSpaceURI[] = "http://www.w3.org/2000/xmlns/"; static const char kXMLNameSpaceURI[] = "http://www.w3.org/XML/1998/namespace"; @@ -41,9 +46,10 @@ static const char kXSLTNameSpaceURI[] = "http://www.w3.org/1999/XSL/Transform"; //----------------------------------------------------------- // Name Space ID table support -static PRInt32 gNameSpaceTableRefs; -static nsHashtable* gURIToIDTable; -static nsVoidArray* gURIArray; +static PRInt32 gNameSpaceTableRefs; +static nsHashtable* gURIToIDTable; +static nsVoidArray* gURIArray; +static nsISupportsArray* gElementFactoryArray; static void AddRefTable() { @@ -78,9 +84,12 @@ static void AddRefTable() gURIToIDTable->Put(&xlinkKey, (void*)kNameSpaceID_XLink); gURIToIDTable->Put(&htmlKey, (void*)kNameSpaceID_HTML); gURIToIDTable->Put(&xsltKey, (void*)kNameSpaceID_XSLT); + + NS_NewISupportsArray(&gElementFactoryArray); } NS_ASSERTION(nsnull != gURIToIDTable, "no URI table"); NS_ASSERTION(nsnull != gURIArray, "no URI array"); + NS_ASSERTION(nsnull != gElementFactoryArray, "no element factory array"); } static void ReleaseTable() @@ -95,6 +104,8 @@ static void ReleaseTable() delete gURIArray; gURIToIDTable = nsnull; gURIArray = nsnull; + + NS_IF_RELEASE(gElementFactoryArray); } } @@ -341,8 +352,10 @@ public: PRInt32& aNameSpaceID); NS_IMETHOD GetNameSpaceURI(PRInt32 aNameSpaceID, nsAWritableString& aURI); - NS_IMETHOD GetNameSpaceID(const nsAReadableString& aURI, PRInt32& aNameSpaceID); - + NS_IMETHOD GetNameSpaceID(const nsAReadableString& aURI, + PRInt32& aNameSpaceID); + NS_IMETHOD GetElementFactory(PRInt32 aNameSpaceID, + nsIElementFactory **aElementFactory); private: // These are not supported and are not implemented! NameSpaceManagerImpl(const NameSpaceManagerImpl& aCopy); @@ -427,6 +440,67 @@ NameSpaceManagerImpl::GetNameSpaceID(const nsAReadableString& aURI, PRInt32& aNa return NS_OK; } +NS_IMETHODIMP +NameSpaceManagerImpl::GetElementFactory(PRInt32 aNameSpaceID, + nsIElementFactory **aElementFactory) +{ + *aElementFactory = nsnull; + + NS_ENSURE_TRUE(gElementFactoryArray, NS_ERROR_NOT_INITIALIZED); + NS_ENSURE_TRUE(aNameSpaceID >= 0, NS_ERROR_ILLEGAL_VALUE); + + gElementFactoryArray->QueryElementAt(aNameSpaceID, + NS_GET_IID(nsIElementFactory), + (void **)aElementFactory); + + if (*aElementFactory) { + return NS_OK; + } + + nsAutoString uri; + + GetNameSpaceURI(aNameSpaceID, uri); + + nsCOMPtr ef; + + if (!uri.IsEmpty()) { + nsCAutoString contract_id(NS_ELEMENT_FACTORY_CONTRACTID_PREFIX); + contract_id.Append(NS_ConvertUCS2toUTF8(uri)); + + ef = do_GetService(contract_id.get()); + } + + if (!ef) { + nsresult rv = NS_NewXMLElementFactory(getter_AddRefs(ef)); + + if (NS_FAILED(rv)) { + return rv; + } + } + + PRUint32 count = 0; + gElementFactoryArray->Count(&count); + + if ((PRUint32)aNameSpaceID < count) { + gElementFactoryArray->ReplaceElementAt(ef, aNameSpaceID); + } else { + // This sucks, simply doing an InsertElementAt() should IMNSHO + // automatically grow the array and insert null's as needed to + // fill up the array!?!! + + for (PRInt32 i = count; i < aNameSpaceID; i++) { + gElementFactoryArray->AppendElement(nsnull); + } + + gElementFactoryArray->AppendElement(ef); + } + + *aElementFactory = ef; + NS_ADDREF(*aElementFactory); + + return NS_OK; +} + NS_LAYOUT nsresult NS_NewNameSpaceManager(nsINameSpaceManager** aInstancePtrResult) { diff --git a/mozilla/content/xml/document/src/nsXMLContentSink.cpp b/mozilla/content/xml/document/src/nsXMLContentSink.cpp index 43a854cedeb..99f19bdcd85 100644 --- a/mozilla/content/xml/document/src/nsXMLContentSink.cpp +++ b/mozilla/content/xml/document/src/nsXMLContentSink.cpp @@ -193,6 +193,8 @@ nsXMLContentSink::Init(nsIDocument* aDoc, nsIURI* aURL, nsIWebShell* aContainer) { + NS_ENSURE_TRUE(gNameSpaceManager, NS_ERROR_OUT_OF_MEMORY); + NS_PRECONDITION(nsnull != aDoc, "null ptr"); NS_PRECONDITION(nsnull != aURL, "null ptr"); if ((nsnull == aDoc) || (nsnull == aURL)) { @@ -691,8 +693,6 @@ nsXMLContentSink::OpenContainer(const nsIParserNode& aNode) // This is done based off a contractid/namespace scheme. nsCOMPtr elementFactory; - // This should *not* be done for every node, only when we find - // a new namespace!!! -- jst GetElementFactory(nameSpaceID, getter_AddRefs(elementFactory)); if (elementFactory) { // Create the content element using the element factory. @@ -1542,7 +1542,8 @@ PRInt32 nsXMLContentSink::GetNameSpaceId(nsIAtom* aPrefix) { PRInt32 id = (nsnull == aPrefix) ? kNameSpaceID_None : kNameSpaceID_Unknown; - if ((nsnull != mNameSpaceStack) && (0 < mNameSpaceStack->Count())) { + + if (mNameSpaceStack && mNameSpaceStack->Count() > 0) { PRInt32 index = mNameSpaceStack->Count() - 1; nsINameSpace* nameSpace = (nsINameSpace*)mNameSpaceStack->ElementAt(index); nameSpace->FindNameSpaceID(aPrefix, id); @@ -1890,18 +1891,8 @@ XMLElementFactoryImpl::CreateInstanceByTag(nsINodeInfo *aNodeInfo, } void -nsXMLContentSink::GetElementFactory(PRInt32 aNameSpaceID, nsIElementFactory** aResult) +nsXMLContentSink::GetElementFactory(PRInt32 aNameSpaceID, + nsIElementFactory** aResult) { - nsresult rv; - nsAutoString nameSpace; - gNameSpaceManager->GetNameSpaceURI(aNameSpaceID, nameSpace); - - nsCAutoString contractID( NS_ELEMENT_FACTORY_CONTRACTID_PREFIX ); - contractID.AppendWithConversion(nameSpace); - - // Retrieve the appropriate factory. - nsCOMPtr elementFactory(do_GetService(contractID, &rv)); - - *aResult = elementFactory; - NS_IF_ADDREF(*aResult); + gNameSpaceManager->GetElementFactory(aNameSpaceID, aResult); } diff --git a/mozilla/content/xul/document/src/nsXULDocument.cpp b/mozilla/content/xul/document/src/nsXULDocument.cpp index a289167bbc5..f75999a4e86 100644 --- a/mozilla/content/xul/document/src/nsXULDocument.cpp +++ b/mozilla/content/xul/document/src/nsXULDocument.cpp @@ -4347,14 +4347,6 @@ nsXULDocument::CreateElement(nsINodeInfo *aNodeInfo, nsIContent** aResult) rv = nsXULElement::Create(aNodeInfo, getter_AddRefs(result)); if (NS_FAILED(rv)) return rv; } - else if (aNodeInfo->NamespaceEquals(kNameSpaceID_HTML)) { - rv = gHTMLElementFactory->CreateInstanceByTag(aNodeInfo, - getter_AddRefs(result)); - if (NS_FAILED(rv)) return rv; - - if (! result) - return NS_ERROR_UNEXPECTED; - } else { PRInt32 namespaceID; aNodeInfo->GetNamespaceID(namespaceID); @@ -5844,8 +5836,8 @@ nsXULDocument::CreateElement(nsXULPrototypeElement* aPrototype, nsIContent** aRe nsCOMPtr elementFactory; GetElementFactory(namespaceID, getter_AddRefs(elementFactory)); - elementFactory->CreateInstanceByTag(aPrototype->mNodeInfo, - getter_AddRefs(result)); + rv = elementFactory->CreateInstanceByTag(aPrototype->mNodeInfo, + getter_AddRefs(result)); if (NS_FAILED(rv)) return rv; if (! result) @@ -6582,27 +6574,18 @@ nsXULDocument::RemoveElement(nsIContent* aParent, nsIContent* aChild) return NS_OK; } - - - -void -nsXULDocument::GetElementFactory(PRInt32 aNameSpaceID, nsIElementFactory** aResult) +void +nsXULDocument::GetElementFactory(PRInt32 aNameSpaceID, + nsIElementFactory** aResult) { - nsresult rv; - nsAutoString nameSpace; - gNameSpaceManager->GetNameSpaceURI(aNameSpaceID, nameSpace); + // Retrieve the appropriate factory. + gNameSpaceManager->GetElementFactory(aNameSpaceID, aResult); - nsCAutoString contractID(NS_ELEMENT_FACTORY_CONTRACTID_PREFIX); - contractID.AppendWithConversion(nameSpace); - - // Retrieve the appropriate factory. - nsCOMPtr elementFactory(do_GetService(contractID, &rv)); - - if (!elementFactory) - elementFactory = gXMLElementFactory; // Nothing found. Use generic XML element. - - *aResult = elementFactory; - NS_IF_ADDREF(*aResult); + if (!*aResult) { + // Nothing found. Use generic XML element. + *aResult = gXMLElementFactory; + NS_IF_ADDREF(*aResult); + } } NS_IMETHODIMP diff --git a/mozilla/content/xul/templates/src/nsXULContentBuilder.cpp b/mozilla/content/xul/templates/src/nsXULContentBuilder.cpp index baabbe22d2c..b589cf4f959 100644 --- a/mozilla/content/xul/templates/src/nsXULContentBuilder.cpp +++ b/mozilla/content/xul/templates/src/nsXULContentBuilder.cpp @@ -1634,21 +1634,12 @@ nsXULContentBuilder::SetContainerAttrs(nsIContent *aElement, const nsTemplateMat void nsXULContentBuilder::GetElementFactory(PRInt32 aNameSpaceID, nsIElementFactory** aResult) { - nsresult rv; - nsAutoString nameSpace; - gNameSpaceManager->GetNameSpaceURI(aNameSpaceID, nameSpace); + gNameSpaceManager->GetElementFactory(aNameSpaceID, aResult); - nsCAutoString contractID(NS_ELEMENT_FACTORY_CONTRACTID_PREFIX); - contractID.AppendWithConversion(nameSpace.get()); - - // Retrieve the appropriate factory. - nsCOMPtr elementFactory(do_GetService(contractID, &rv)); - - if (!elementFactory) - elementFactory = gXMLElementFactory; // Nothing found. Use generic XML element. - - *aResult = elementFactory; - NS_IF_ADDREF(*aResult); + if (!*aResult) { + *aResult = gXMLElementFactory; // Nothing found. Use generic XML element. + NS_IF_ADDREF(*aResult); + } } //---------------------------------------------------------------------- diff --git a/mozilla/content/xul/templates/src/nsXULTemplateBuilder.cpp b/mozilla/content/xul/templates/src/nsXULTemplateBuilder.cpp index 5220ded0af7..75cde05b4ad 100644 --- a/mozilla/content/xul/templates/src/nsXULTemplateBuilder.cpp +++ b/mozilla/content/xul/templates/src/nsXULTemplateBuilder.cpp @@ -59,7 +59,6 @@ #include "nsIBindingManager.h" #include "nsIDOMNodeList.h" #include "nsIHTMLContent.h" -#include "nsIElementFactory.h" #include "nsINameSpace.h" #include "nsINameSpaceManager.h" #include "nsIRDFCompositeDataSource.h"