Fixing bug 102583. Fixing bad old string useage in nsXMLContentSink. r=peterv@netscape.com, sr=waterson@netscape.com

git-svn-id: svn://10.0.0.236/trunk@105473 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
jst%netscape.com 2001-10-16 05:55:04 +00:00
parent 6939fc1b77
commit 03e0d6d868
2 changed files with 115 additions and 84 deletions

View File

@ -37,7 +37,6 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsCOMPtr.h"
#include "nsReadableUtils.h"
#include "nsXMLContentSink.h"
#include "nsIElementFactory.h"
#include "nsIParser.h"
@ -104,7 +103,6 @@
#include "nsHTMLTokens.h"
static char kNameSpaceSeparator = ':';
static char kNameSpaceDef[] = "xmlns";
static char kStyleSheetPI[] = "xml-stylesheet";
static char kXSLType[] = "text/xsl";
@ -505,15 +503,16 @@ nsXMLContentSink::AddAttributes(const nsIParserNode& aNode,
PRBool aIsHTML)
{
// Add tag attributes to the content attributes
nsAutoString name;
nsCOMPtr<nsIAtom> nameSpacePrefix, nameAtom;
PRInt32 ac = aNode.GetAttributeCount();
for (PRInt32 i = 0; i < ac; i++) {
// Get upper-cased key
const nsAReadableString& key = aNode.GetKeyAt(i);
name.Assign(key);
nsCOMPtr<nsIAtom> nameSpacePrefix(dont_AddRef(CutNameSpacePrefix(name)));
nsCOMPtr<nsIAtom> nameAtom(dont_AddRef(NS_NewAtom(name)));
SplitXMLName(key, getter_AddRefs(nameSpacePrefix),
getter_AddRefs(nameAtom));
PRInt32 nameSpaceID;
if (nameSpacePrefix) {
@ -530,6 +529,9 @@ nsXMLContentSink::AddAttributes(const nsIParserNode& aNode,
nameAtom = dont_AddRef(NS_NewAtom(key));
nameSpacePrefix = nsnull;
} else if ((kNameSpaceID_XMLNS == nameSpaceID) && aIsHTML) {
// Ooh, what a nice little hack we have here :-)
nsAutoString name;
nameAtom->ToString(name);
name.InsertWithConversion("xmlns:", 0);
nameAtom = dont_AddRef(NS_NewAtom(name));
nameSpaceID = kNameSpaceID_HTML; // XXX this is wrong, but necessary until HTML can store other namespaces for attrs
@ -561,89 +563,121 @@ nsXMLContentSink::AddAttributes(const nsIParserNode& aNode,
return NS_OK;
}
void
nsresult
nsXMLContentSink::PushNameSpacesFrom(const nsIParserNode& aNode)
{
nsAutoString k, prefix;
PRInt32 ac = aNode.GetAttributeCount();
PRInt32 offset;
nsINameSpace* nameSpace = nsnull;
nsCOMPtr<nsINameSpace> nameSpace;
nsresult rv = NS_OK;
if ((nsnull != mNameSpaceStack) && (0 < mNameSpaceStack->Count())) {
nameSpace = (nsINameSpace*)mNameSpaceStack->ElementAt(mNameSpaceStack->Count() - 1);
NS_ADDREF(nameSpace);
}
else {
nsINameSpaceManager* manager = nsnull;
mDocument->GetNameSpaceManager(manager);
NS_ASSERTION(nsnull != manager, "no name space manager in document");
if (nsnull != manager) {
manager->CreateRootNameSpace(nameSpace);
NS_RELEASE(manager);
if (mNameSpaceStack && (0 < mNameSpaceStack->Count())) {
nameSpace =
(nsINameSpace*)mNameSpaceStack->ElementAt(mNameSpaceStack->Count() - 1);
} else {
nsCOMPtr<nsINameSpaceManager> manager;
mDocument->GetNameSpaceManager(*getter_AddRefs(manager));
NS_ASSERTION(manager, "no name space manager in document");
if (manager) {
rv = manager->CreateRootNameSpace(*getter_AddRefs(nameSpace));
NS_ENSURE_SUCCESS(rv, rv);
}
}
if (nsnull != nameSpace) {
for (PRInt32 i = 0; i < ac; i++) {
const nsAReadableString& key = aNode.GetKeyAt(i);
k.Assign(key);
// Look for "xmlns" at the start of the attribute name
offset = k.Find(kNameSpaceDef);
if (0 == offset) {
if (k.Length() == (sizeof(kNameSpaceDef)-1)) {
// If there's nothing left, this is a default namespace
prefix.Truncate();
}
else {
PRUnichar next = k.CharAt(sizeof(kNameSpaceDef)-1);
// If the next character is a :, there is a namespace prefix
if (':' == next) {
prefix.Truncate();
k.Right(prefix, k.Length()-sizeof(kNameSpaceDef));
}
else {
continue;
}
}
NS_ENSURE_TRUE(nameSpace, NS_ERROR_UNEXPECTED);
// Open a local namespace
nsIAtom* prefixAtom = ((0 < prefix.Length()) ? NS_NewAtom(prefix) : nsnull);
nsINameSpace* child = nsnull;
nameSpace->CreateChildNameSpace(prefixAtom, aNode.GetValueAt(i), child);
if (nsnull != child) {
NS_RELEASE(nameSpace);
nameSpace = child;
static const NS_NAMED_LITERAL_STRING(kNameSpaceDef, "xmlns");
static const PRUint32 xmlns_len = kNameSpaceDef.Length();
for (PRInt32 i = 0; i < ac; i++) {
const nsAReadableString& key = aNode.GetKeyAt(i);
// Look for "xmlns" at the start of the attribute name
PRUint32 key_len = key.Length();
if (key_len >= xmlns_len &&
nsDependentSubstring(key, 0, xmlns_len).Equals(kNameSpaceDef)) {
nsCOMPtr<nsIAtom> prefixAtom;
// If key_len > xmlns_len we have a xmlns:foo type attribute,
// extract the prefix. If not, we have a xmlns attribute in
// which case there is no prefix.
if (key_len > xmlns_len) {
nsReadingIterator<PRUnichar> start, end;
key.BeginReading(start);
key.EndReading(end);
start.advance(xmlns_len);
if (*start == ':') {
++start;
prefixAtom =
dont_AddRef(NS_NewAtom(nsDependentSubstring(start, end)));
}
NS_IF_RELEASE(prefixAtom);
}
nsCOMPtr<nsINameSpace> child;
rv = nameSpace->CreateChildNameSpace(prefixAtom, aNode.GetValueAt(i),
*getter_AddRefs(child));
NS_ENSURE_SUCCESS(rv, rv);
nameSpace = child;
}
if (nsnull == mNameSpaceStack) {
mNameSpaceStack = new nsAutoVoidArray();
}
mNameSpaceStack->AppendElement(nameSpace);
}
if (!mNameSpaceStack) {
mNameSpaceStack = new nsAutoVoidArray();
if (!mNameSpaceStack) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
nsINameSpace *tmp = nameSpace;
mNameSpaceStack->AppendElement(tmp);
NS_ADDREF(tmp);
return NS_OK;
}
nsIAtom* nsXMLContentSink::CutNameSpacePrefix(nsString& aString)
// static
void
nsXMLContentSink::SplitXMLName(nsAReadableString& aString, nsIAtom **aPrefix,
nsIAtom **aLocalName)
{
nsAutoString prefix;
PRInt32 nsoffset = aString.FindChar(kNameSpaceSeparator);
if (-1 != nsoffset) {
aString.Left(prefix, nsoffset);
aString.Cut(0, nsoffset+1);
nsReadingIterator<PRUnichar> iter, end;
aString.BeginReading(iter);
aString.EndReading(end);
FindCharInReadable(kNameSpaceSeparator, iter, end);
if (iter != end) {
nsReadingIterator<PRUnichar> start;
aString.BeginReading(start);
*aPrefix = NS_NewAtom(nsDependentSubstring(start, iter));
++iter;
*aLocalName = NS_NewAtom(nsDependentSubstring(iter, end));
return;
}
if (0 < prefix.Length()) {
return NS_NewAtom(prefix);
}
return nsnull;
*aPrefix = nsnull;
*aLocalName = NS_NewAtom(aString);
}
NS_IMETHODIMP
nsXMLContentSink::OpenContainer(const nsIParserNode& aNode)
{
nsresult result = NS_OK;
nsAutoString tag;
nsCOMPtr<nsIAtom> nameSpacePrefix;
PRBool isHTML = PR_FALSE;
PRBool appendContent = PR_TRUE;
nsCOMPtr<nsIContent> content;
@ -657,9 +691,10 @@ nsXMLContentSink::OpenContainer(const nsIParserNode& aNode)
mState = eXMLContentSinkState_InDocumentElement;
tag.Assign(aNode.GetText());
nameSpacePrefix = getter_AddRefs(CutNameSpacePrefix(tag));
nsCOMPtr<nsIAtom> tagAtom(dont_AddRef(NS_NewAtom(tag)));
nsCOMPtr<nsIAtom> nameSpacePrefix, tagAtom;
SplitXMLName(aNode.GetText(), getter_AddRefs(nameSpacePrefix),
getter_AddRefs(tagAtom));
// We must register namespace declarations found in the attribute list
// of an element before creating the element. This is because the
@ -789,9 +824,6 @@ NS_IMETHODIMP
nsXMLContentSink::CloseContainer(const nsIParserNode& aNode)
{
nsresult result = NS_OK;
nsAutoString tag;
nsCOMPtr<nsIAtom> nameSpacePrefix;
PRBool isHTML = PR_FALSE;
PRBool popContent = PR_TRUE;
PRBool appendContent = PR_FALSE;
@ -800,16 +832,14 @@ nsXMLContentSink::CloseContainer(const nsIParserNode& aNode)
// no close tags for elements.
PR_ASSERT(eXMLContentSinkState_InDocumentElement == mState);
tag.Assign(aNode.GetText());
nameSpacePrefix = getter_AddRefs(CutNameSpacePrefix(tag));
PRInt32 nameSpaceID = GetNameSpaceId(nameSpacePrefix);
isHTML = IsHTMLNameSpace(nameSpaceID);
FlushText();
if (isHTML) {
nsCOMPtr<nsIAtom> tagAtom(dont_AddRef(NS_NewAtom(tag)));
nsCOMPtr<nsIContent> currentContent(dont_AddRef(GetCurrentContent()));
if (currentContent && currentContent->IsContentOfType(nsIContent::eHTML)) {
nsCOMPtr<nsIAtom> tagAtom;
currentContent->GetTag(*getter_AddRefs(tagAtom));
if (tagAtom.get() == nsHTMLAtoms::script) {
result = ProcessEndSCRIPTTag(aNode);
@ -1561,7 +1591,7 @@ nsXMLContentSink::AddEntityReference(const nsIParserNode& aNode)
PRInt32
nsXMLContentSink::GetNameSpaceId(nsIAtom* aPrefix)
{
PRInt32 id = (nsnull == aPrefix) ? kNameSpaceID_None : kNameSpaceID_Unknown;
PRInt32 id = aPrefix ? kNameSpaceID_Unknown : kNameSpaceID_None;
if (mNameSpaceStack && mNameSpaceStack->Count() > 0) {
PRInt32 index = mNameSpaceStack->Count() - 1;

View File

@ -139,8 +139,9 @@ protected:
nsIContent* aContent,
PRBool aIsHTML);
nsresult AddContentAsLeaf(nsIContent *aContent);
void PushNameSpacesFrom(const nsIParserNode& aNode);
nsIAtom* CutNameSpacePrefix(nsString& aString);
void PushNameSpacesFrom(const nsIParserNode& aNode);
static void SplitXMLName(nsAReadableString& aString, nsIAtom **aPrefix,
nsIAtom **aTagName);
PRInt32 GetNameSpaceId(nsIAtom* aPrefix);
nsINameSpace* PopNameSpaces();
PRBool IsHTMLNameSpace(PRInt32 aId);