Fix some getElementsByTagNameNS issues, both regressions and long-standing

bugs.  Bug 343307, r+sr=sicking
This commit is contained in:
bzbarsky%mit.edu 2006-07-20 03:25:39 +00:00
Родитель 199da5edf0
Коммит a47feb1031
6 изменённых файлов: 62 добавлений и 46 удалений

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

@ -686,6 +686,10 @@ nsContentList::Match(nsIContent *aContent)
return (mMatchAll || ni->QualifiedNameEquals(mMatchAtom));
}
if (mMatchNameSpaceId == kNameSpaceID_Wildcard) {
return (mMatchAll || ni->Equals(mMatchAtom));
}
return ((mMatchAll && ni->NamespaceEquals(mMatchNameSpaceId)) ||
ni->Equals(mMatchAtom, mMatchNameSpaceId));
}

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

@ -53,6 +53,10 @@
#include "nsIAtom.h"
#include "nsINameSpaceManager.h"
// Magic namespace id that means "match all namespaces". This is
// negative so it won't collide with actual namespace constants.
#define kNameSpaceID_Wildcard PR_INT32_MIN
// This is a callback function type that can be used to implement an
// arbitrary matching algorithm. aContent is the content that may
// match the list, while aNamespaceID, aAtom, and aData are whatever
@ -163,11 +167,16 @@ public:
/**
* @param aRootNode The node under which to limit our search.
* @param aMatchAtom an atom whose meaning depends on aMatchNameSpaceId
* @param aMatchNameSpaceId if kNameSpaceID_Unknown then aMatchAtom is the
* tagName to match. Otherwise we match nodes with
* aMatchNameSpaceId and a localName equal to
* aMatchAtom
* @param aMatchAtom An atom whose meaning depends on aMatchNameSpaceId.
* The special value "*" always matches whatever aMatchAtom
* is matched against.
* @param aMatchNameSpaceId If kNameSpaceID_Unknown, then aMatchAtom is the
* tagName to match.
* If kNameSpaceID_Wildcard, then aMatchAtom is the
* localName to match.
* Otherwise we match nodes whose namespace is
* aMatchNameSpaceId and localName matches
* aMatchAtom.
* @param aDeep If false, then look only at children of the root, nothing
* deeper. If true, then look at the whole subtree rooted at
* our root.

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

@ -2739,19 +2739,15 @@ nsDocument::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName,
nsIDOMNodeList** aReturn)
{
PRInt32 nameSpaceId = kNameSpaceID_Unknown;
PRInt32 nameSpaceId = kNameSpaceID_Wildcard;
nsContentList *list = nsnull;
if (!aNamespaceURI.EqualsLiteral("*")) {
nameSpaceId =
nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
if (nameSpaceId == kNameSpaceID_Unknown) {
// Unknown namespace means no matches, we create an empty list...
list = NS_GetContentList(this, nsnull, kNameSpaceID_None).get();
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
}
nsresult rv =
nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURI,
nameSpaceId);
NS_ENSURE_SUCCESS(rv, rv);
}
if (!list) {

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

@ -1674,21 +1674,15 @@ nsGenericElement::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName,
nsIDOMNodeList** aReturn)
{
PRInt32 nameSpaceId = kNameSpaceID_Unknown;
PRInt32 nameSpaceId = kNameSpaceID_Wildcard;
nsContentList *list = nsnull;
nsIDocument* document = GetCurrentDoc();
if (!aNamespaceURI.EqualsLiteral("*")) {
nameSpaceId =
nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
if (nameSpaceId == kNameSpaceID_Unknown) {
// Unknown namespace means no matches, we create an empty list...
list = NS_GetContentList(document, nsnull,
kNameSpaceID_None).get();
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
}
nsresult rv =
nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURI,
nameSpaceId);
NS_ENSURE_SUCCESS(rv, rv);
}
if (!list) {

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

@ -196,12 +196,16 @@ NameSpaceManagerImpl::RegisterNameSpace(const nsAString& aURI,
}
}
NS_POSTCONDITION(aNameSpaceID >= -1, "Bogus namespace ID");
return rv;
}
nsresult
NameSpaceManagerImpl::GetNameSpaceURI(PRInt32 aNameSpaceID, nsAString& aURI)
{
NS_PRECONDITION(aNameSpaceID >= 0, "Bogus namespace ID");
PRInt32 index = aNameSpaceID - 1; // id is index + 1
if (index < 0 || index >= mURIArray.Count()) {
aURI.Truncate();
@ -223,8 +227,12 @@ NameSpaceManagerImpl::GetNameSpaceID(const nsAString& aURI)
PRInt32 nameSpaceID;
return mURIToIDTable.Get(&aURI, &nameSpaceID) ? nameSpaceID :
kNameSpaceID_Unknown;
if (mURIToIDTable.Get(&aURI, &nameSpaceID)) {
NS_POSTCONDITION(nameSpaceID >= 0, "Bogus namespace ID");
return nameSpaceID;
}
return kNameSpaceID_Unknown;
}
nsresult
@ -285,6 +293,11 @@ NameSpaceManagerImpl::HasElementCreator(PRInt32 aNameSpaceID)
nsresult NameSpaceManagerImpl::AddNameSpace(const nsAString& aURI,
const PRInt32 aNameSpaceID)
{
if (aNameSpaceID < 0) {
// We've wrapped... Can't do anything else here; just bail.
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ASSERTION(aNameSpaceID - 1 == mURIArray.Count(),
"BAD! AddNameSpace not called in right order!");

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

@ -12,6 +12,7 @@ function run_test()
test_getElementsByAttribute();
// What else should we test?
// XXXbz we need more tests here to test liveness!
}
@ -86,13 +87,9 @@ function test_getElementsByTagNameNS()
do_check_eq(doc.getElementById("test2")
.getElementsByTagNameNS("", "test").length,
1);
/* XXXbz this test is currently failing because getElementsByTagNameNS("*",
"tagname" is actually broken. See bug 343307.
do_check_eq(doc.getElementById("test2")
.getElementsByTagNameNS("*", "test").length,
7);
*/
// Check that the first element of getElementsByTagNameNS on the document is
// the right thing.
@ -102,20 +99,15 @@ function test_getElementsByTagNameNS()
// Check that we get the right things in the right order
/* XXXbz this test is currently failing because getElementsByTagNameNS("*",
"tagname" is actually broken. See bug 343307.
var numTests = doc.getElementsByTagNameNS("*", "test").length;
do_check_eq(numTests, 14);
for (var i = 1; i <= numTests; ++i) {
do_check_true(doc.getElementById("test" + i) instanceof nsIDOMElement);
do_check_eq(doc.getElementById("test" + i),
doc.getElementsByTagName("test").item(i-1));
doc.getElementsByTagNameNS("*", "test").item(i-1));
}
*/
// Check general proper functioning of having a non-wildcard namespace.
var test2 = doc.getElementById("test2");
do_check_eq(doc.getElementsByTagNameNS("", "test").length,
@ -141,29 +133,37 @@ function test_getElementsByTagNameNS()
do_check_eq(doc.getElementsByTagNameNS(null, "foo:test").length, 0);
do_check_eq(doc.getElementsByTagNameNS("foo", "foo:test").length, 0);
do_check_eq(doc.getElementsByTagNameNS("bar", "foo:test").length, 0);
/* XXXbz this test is currently failing because getElementsByTagNameNS("*",
"tagname" is actually broken. See bug 343307.
do_check_eq(doc.getElementsByTagNameNS("*", "foo:test").length, 0);
*/
do_check_true(doc.getElementsByTagNameNS(null, "foo2:test")
instanceof nsIDOMNodeList);
do_check_eq(doc.getElementsByTagNameNS(null, "foo2:test").length, 0);
do_check_eq(doc.getElementsByTagNameNS("foo2", "foo2:test").length, 0);
do_check_eq(doc.getElementsByTagNameNS("bar", "foo2:test").length, 0);
/* XXXbz this test is currently failing because getElementsByTagNameNS("*",
"tagname" is actually broken. See bug 343307.
do_check_eq(doc.getElementsByTagNameNS("*", "foo2:test").length, 0);
*/
do_check_true(doc.getElementsByTagNameNS(null, "bar:test")
instanceof nsIDOMNodeList);
do_check_eq(doc.getElementsByTagNameNS(null, "bar:test").length, 0);
do_check_eq(doc.getElementsByTagNameNS("bar", "bar:test").length, 0);
/* XXXbz this test is currently failing because getElementsByTagNameNS("*",
"tagname" is actually broken. See bug 343307.
do_check_eq(doc.getElementsByTagNameNS("*", "bar:test").length, 0);
*/
// Check that previously-unknown namespaces are handled right. Note that we
// can just hardcode the strings, since we're running only once in XPCshell.
// If someone wants to run these in a browser, some use of Math.random() may
// be in order.
list1 = doc.getElementsByTagNameNS("random-bogus-namespace", "foo");
list2 = doc.documentElement.getElementsByTagNameNS("random-bogus-namespace2",
"foo");
do_check_neq(list1, list2);
do_check_eq(list1.length, 0);
do_check_eq(list2.length, 0);
var newNode = doc.createElementNS("random-bogus-namespace", "foo");
doc.documentElement.appendChild(newNode);
var newNode = doc.createElementNS("random-bogus-namespace2", "foo");
doc.documentElement.appendChild(newNode);
do_check_eq(list1.length, 1);
do_check_eq(list2.length, 1);
}
function test_getElementsByAttribute()