diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index 743d14ec495..f20845ab9ee 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -2451,6 +2451,7 @@ nsDocument::GetElementsByTagNameNS(const nsAString& aNamespaceURI, const nsAString& aLocalName, nsIDOMNodeList** aReturn) { + PRInt32 nameSpaceId = kNameSpaceID_Unknown; nsCOMPtr list; @@ -2460,7 +2461,7 @@ nsDocument::GetElementsByTagNameNS(const nsAString& aNamespaceURI, nameSpaceId); if (nameSpaceId == kNameSpaceID_Unknown) { - // Unknown namespace means no matches, we create an empty list... + // Unkonwn namespace means no matches, we create an empty list... NS_GetContentList(this, nsnull, kNameSpaceID_None, nsnull, getter_AddRefs(list)); NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY); @@ -2469,8 +2470,6 @@ nsDocument::GetElementsByTagNameNS(const nsAString& aNamespaceURI, if (!list) { nsCOMPtr nameAtom = do_GetAtom(aLocalName); - NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY); - NS_GetContentList(this, nameAtom, nameSpaceId, nsnull, getter_AddRefs(list)); NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY); diff --git a/mozilla/content/base/src/nsGenericElement.cpp b/mozilla/content/base/src/nsGenericElement.cpp index f6273f4e21e..f5584405c2e 100644 --- a/mozilla/content/base/src/nsGenericElement.cpp +++ b/mozilla/content/base/src/nsGenericElement.cpp @@ -1323,13 +1323,18 @@ nsresult nsGenericElement::GetElementsByTagName(const nsAString& aTagname, nsIDOMNodeList** aReturn) { - nsCOMPtr nameAtom = do_GetAtom(aTagname); + nsCOMPtr nameAtom; + + nameAtom = do_GetAtom(aTagname); NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY); nsCOMPtr list; NS_GetContentList(mDocument, nameAtom, kNameSpaceID_Unknown, this, getter_AddRefs(list)); - NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY); + + if (!list) { + return NS_ERROR_OUT_OF_MEMORY; + } return CallQueryInterface(list, aReturn); } @@ -1447,6 +1452,9 @@ nsGenericElement::GetElementsByTagNameNS(const nsAString& aNamespaceURI, const nsAString& aLocalName, nsIDOMNodeList** aReturn) { + nsCOMPtr nameAtom = do_GetAtom(aLocalName); + NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY); + PRInt32 nameSpaceId = kNameSpaceID_Unknown; nsCOMPtr list; @@ -1464,9 +1472,6 @@ nsGenericElement::GetElementsByTagNameNS(const nsAString& aNamespaceURI, } if (!list) { - nsCOMPtr nameAtom = do_GetAtom(aLocalName); - NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY); - NS_GetContentList(mDocument, nameAtom, nameSpaceId, this, getter_AddRefs(list)); NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY); diff --git a/mozilla/content/xul/content/src/nsXULElement.cpp b/mozilla/content/xul/content/src/nsXULElement.cpp index ec0c4d3de45..cabbc744c60 100644 --- a/mozilla/content/xul/content/src/nsXULElement.cpp +++ b/mozilla/content/xul/content/src/nsXULElement.cpp @@ -129,7 +129,7 @@ #include "nsIListBoxObject.h" #include "nsContentUtils.h" #include "nsGenericElement.h" -#include "nsContentList.h" + #include "nsMutationEvent.h" #include "nsIDOMMutationEvent.h" #include "nsPIDOMWindow.h" @@ -1392,18 +1392,25 @@ nsXULElement::RemoveAttributeNode(nsIDOMAttr* aOldAttr, nsIDOMAttr** aReturn) NS_IMETHODIMP -nsXULElement::GetElementsByTagName(const nsAString& aTagname, +nsXULElement::GetElementsByTagName(const nsAString& aName, nsIDOMNodeList** aReturn) { - nsCOMPtr nameAtom = do_GetAtom(aTagname); - NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY); + nsresult rv; - nsCOMPtr list; - NS_GetContentList(mDocument, nameAtom, kNameSpaceID_Unknown, this, - getter_AddRefs(list)); - NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY); + nsRDFDOMNodeList* elements; + rv = nsRDFDOMNodeList::Create(&elements); + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create node list"); + if (NS_FAILED(rv)) return rv; - return CallQueryInterface(list, aReturn); + nsCOMPtr domElement; + rv = QueryInterface(NS_GET_IID(nsIDOMNode), getter_AddRefs(domElement)); + if (NS_SUCCEEDED(rv)) { + GetElementsByTagName(domElement, aName, elements); + } + + // transfer ownership to caller + *aReturn = elements; + return NS_OK; } NS_IMETHODIMP @@ -1497,32 +1504,40 @@ nsXULElement::GetElementsByTagNameNS(const nsAString& aNamespaceURI, const nsAString& aLocalName, nsIDOMNodeList** aReturn) { - nsCOMPtr nameAtom = do_GetAtom(aLocalName); - NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY); + NS_ENSURE_ARG_POINTER(aReturn); PRInt32 nameSpaceId = kNameSpaceID_Unknown; - nsCOMPtr list; + nsRDFDOMNodeList* elements; + nsresult rv = nsRDFDOMNodeList::Create(&elements); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr kungFuGrip; + kungFuGrip = dont_AddRef(NS_STATIC_CAST(nsIDOMNodeList *, elements)); if (!aNamespaceURI.Equals(NS_LITERAL_STRING("*"))) { nsContentUtils::GetNSManagerWeakRef()->GetNameSpaceID(aNamespaceURI, nameSpaceId); - + if (nameSpaceId == kNameSpaceID_Unknown) { - // Unknown namespace means no matches, we create an empty list... - NS_GetContentList(mDocument, nsnull, kNameSpaceID_None, nsnull, - getter_AddRefs(list)); - NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY); + // Unkonwn namespace means no matches, we return an empty list... + + *aReturn = elements; + NS_ADDREF(*aReturn); + + return NS_OK; } } - if (!list) { - NS_GetContentList(mDocument, nameAtom, nameSpaceId, this, - getter_AddRefs(list)); - NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY); - } + rv = nsXULDocument::GetElementsByTagName(NS_STATIC_CAST(nsIStyledContent *, + this), aLocalName, + nameSpaceId, elements); + NS_ENSURE_SUCCESS(rv, rv); - return CallQueryInterface(list, aReturn); + *aReturn = elements; + NS_ADDREF(*aReturn); + + return NS_OK; } NS_IMETHODIMP @@ -1571,9 +1586,6 @@ nsXULElement::GetElementsByAttribute(const nsAString& aAttribute, const nsAString& aValue, nsIDOMNodeList** aReturn) { - // XXX This should use nsContentList, but that does not support - // _two_ strings being passed to the match func. Ah, the ability - // to create real closures, where art thou? nsresult rv; nsRDFDOMNodeList* elements; rv = nsRDFDOMNodeList::Create(&elements); @@ -3556,6 +3568,72 @@ nsXULElement::EnsureContentsGenerated(void) const return NS_OK; } +nsresult +nsXULElement::GetElementsByTagName(nsIDOMNode* aNode, + const nsAString& aTagName, + nsRDFDOMNodeList* aElements) +{ + nsresult rv; + + nsCOMPtr children; + if (NS_FAILED(rv = aNode->GetChildNodes( getter_AddRefs(children) ))) { + NS_ERROR("unable to get node's children"); + return rv; + } + + // no kids: terminate the recursion + if (! children) + return NS_OK; + + PRUint32 length; + if (NS_FAILED(children->GetLength(&length))) { + NS_ERROR("unable to get node list's length"); + return rv; + } + + for (PRUint32 i = 0; i < length; ++i) { + nsCOMPtr child; + if (NS_FAILED(rv = children->Item(i, getter_AddRefs(child) ))) { + NS_ERROR("unable to get child from list"); + return rv; + } + + nsCOMPtr element; + element = do_QueryInterface(child); + if (!element) + continue; + + if (aTagName.Equals(NS_LITERAL_STRING("*"))) { + if (NS_FAILED(rv = aElements->AppendNode(child))) { + NS_ERROR("unable to append element to node list"); + return rv; + } + } + else { + nsAutoString name; + if (NS_FAILED(rv = child->GetNodeName(name))) { + NS_ERROR("unable to get node name"); + return rv; + } + + if (aTagName.Equals(name)) { + if (NS_FAILED(rv = aElements->AppendNode(child))) { + NS_ERROR("unable to append element to node list"); + return rv; + } + } + } + + // Now recursively look for children + if (NS_FAILED(rv = GetElementsByTagName(child, aTagName, aElements))) { + NS_ERROR("unable to recursively get elements by tag name"); + return rv; + } + } + + return NS_OK; +} + nsresult nsXULElement::GetElementsByAttribute(nsIDOMNode* aNode, const nsAString& aAttribute, diff --git a/mozilla/content/xul/content/src/nsXULElement.h b/mozilla/content/xul/content/src/nsXULElement.h index 2779c0b915a..da90bcdce77 100644 --- a/mozilla/content/xul/content/src/nsXULElement.h +++ b/mozilla/content/xul/content/src/nsXULElement.h @@ -524,6 +524,11 @@ protected: ExecuteJSCode(nsIDOMElement* anElement, nsEvent* aEvent); // Static helpers + static nsresult + GetElementsByTagName(nsIDOMNode* aNode, + const nsAString& aTagName, + nsRDFDOMNodeList* aElements); + static nsresult GetElementsByAttribute(nsIDOMNode* aNode, const nsAString& aAttributeName, diff --git a/mozilla/content/xul/document/src/nsXULDocument.cpp b/mozilla/content/xul/document/src/nsXULDocument.cpp index ee2675392ca..dc673b389f4 100644 --- a/mozilla/content/xul/document/src/nsXULDocument.cpp +++ b/mozilla/content/xul/document/src/nsXULDocument.cpp @@ -160,7 +160,7 @@ #include "nsIObjectOutputStream.h" #include "nsIPref.h" #include "nsIFocusController.h" -#include "nsContentList.h" + //---------------------------------------------------------------------- // @@ -2954,18 +2954,29 @@ nsXULDocument::CreateEntityReference(const nsAString& aName, NS_IMETHODIMP -nsXULDocument::GetElementsByTagName(const nsAString& aTagname, +nsXULDocument::GetElementsByTagName(const nsAString& aTagName, nsIDOMNodeList** aReturn) { - nsCOMPtr nameAtom = do_GetAtom(aTagname); - NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY); + nsresult rv; + nsRDFDOMNodeList* elements; + if (NS_FAILED(rv = nsRDFDOMNodeList::Create(&elements))) { + NS_ERROR("unable to create node list"); + return rv; + } - nsCOMPtr list; - NS_GetContentList(this, nameAtom, kNameSpaceID_Unknown, nsnull, - getter_AddRefs(list)); - NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY); + nsIContent* root = nsnull; + GetRootContent(&root); + NS_ASSERTION(root != nsnull, "no doc root"); - return CallQueryInterface(list, aReturn); + if (root != nsnull) { + rv = GetElementsByTagName(root, aTagName, kNameSpaceID_Unknown, + elements); + + NS_RELEASE(root); + } + + *aReturn = elements; + return NS_OK; } NS_IMETHODIMP @@ -2973,9 +2984,6 @@ nsXULDocument::GetElementsByAttribute(const nsAString& aAttribute, const nsAString& aValue, nsIDOMNodeList** aReturn) { - // XXX This should use nsContentList, but that does not support - // _two_ strings being passed to the match func. Ah, the ability - // to create real closures, where art thou? nsresult rv; nsRDFDOMNodeList* elements; if (NS_FAILED(rv = nsRDFDOMNodeList::Create(&elements))) { @@ -3704,32 +3712,38 @@ nsXULDocument::GetElementsByTagNameNS(const nsAString& aNamespaceURI, const nsAString& aLocalName, nsIDOMNodeList** aReturn) { - PRInt32 nameSpaceId = kNameSpaceID_Unknown; + nsresult rv; - nsCOMPtr list; + nsRDFDOMNodeList* elements; + if (NS_FAILED(rv = nsRDFDOMNodeList::Create(&elements))) { + NS_ERROR("unable to create node list"); + return rv; + } - if (!aNamespaceURI.Equals(NS_LITERAL_STRING("*"))) { - nsContentUtils::GetNSManagerWeakRef()->GetNameSpaceID(aNamespaceURI, - nameSpaceId); + *aReturn = elements; - if (nameSpaceId == kNameSpaceID_Unknown) { - // Unknown namespace means no matches, we create an empty list... - NS_GetContentList(this, nsnull, kNameSpaceID_None, nsnull, - getter_AddRefs(list)); - NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY); + nsCOMPtr root; + GetRootContent(getter_AddRefs(root)); + NS_ASSERTION(root, "no doc root"); + + if (root) { + PRInt32 nsid = kNameSpaceID_Unknown; + if (!aNamespaceURI.Equals(NS_LITERAL_STRING("*"))) { + rv = nsContentUtils::GetNSManagerWeakRef()->GetNameSpaceID(aNamespaceURI, nsid); + NS_ENSURE_SUCCESS(rv, rv); + + if (nsid == kNameSpaceID_Unknown) { + // Namespace not found, then there can't be any elements to + // be found. + return NS_OK; + } } + + rv = GetElementsByTagName(root, aLocalName, nsid, + elements); } - if (!list) { - nsCOMPtr nameAtom = do_GetAtom(aLocalName); - NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY); - - NS_GetContentList(this, nameAtom, nameSpaceId, nsnull, - getter_AddRefs(list)); - NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY); - } - - return CallQueryInterface(list, aReturn); + return NS_OK; } nsresult @@ -4505,6 +4519,68 @@ nsXULDocument::StartLayout(void) } +nsresult +nsXULDocument::GetElementsByTagName(nsIContent *aContent, + const nsAString& aName, + PRInt32 aNamespaceID, + nsRDFDOMNodeList* aElements) +{ + NS_ENSURE_ARG_POINTER(aContent); + NS_ENSURE_ARG_POINTER(aElements); + + nsresult rv = NS_OK; + + nsCOMPtr element(do_QueryInterface(aContent)); + if (!element) + return NS_OK; + + nsCOMPtr ni; + aContent->GetNodeInfo(*getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_OK); + + if (aName.Equals(NS_LITERAL_STRING("*"))) { + if (aNamespaceID == kNameSpaceID_Unknown || + ni->NamespaceEquals(aNamespaceID)) { + if (NS_FAILED(rv = aElements->AppendNode(element))) { + NS_ERROR("unable to append element to node list"); + return rv; + } + } + } + else { + if (ni->Equals(aName) && + (aNamespaceID == kNameSpaceID_Unknown || + ni->NamespaceEquals(aNamespaceID))) { + if (NS_FAILED(rv = aElements->AppendNode(element))) { + NS_ERROR("unable to append element to node list"); + return rv; + } + } + } + + PRInt32 length; + if (NS_FAILED(rv = aContent->ChildCount(length))) { + NS_ERROR("unable to get childcount"); + return rv; + } + + for (PRInt32 i = 0; i < length; ++i) { + nsCOMPtr child; + if (NS_FAILED(rv = aContent->ChildAt(i, *getter_AddRefs(child) ))) { + NS_ERROR("unable to get child from content"); + return rv; + } + + if (NS_FAILED(rv = GetElementsByTagName(child, aName, aNamespaceID, + aElements))) { + NS_ERROR("unable to recursively get elements by tag name"); + return rv; + } + } + + return NS_OK; +} + nsresult nsXULDocument::GetElementsByAttribute(nsIDOMNode* aNode, const nsAString& aAttribute, diff --git a/mozilla/content/xul/document/src/nsXULDocument.h b/mozilla/content/xul/document/src/nsXULDocument.h index d79638e94d2..84a4f8c6d37 100644 --- a/mozilla/content/xul/document/src/nsXULDocument.h +++ b/mozilla/content/xul/document/src/nsXULDocument.h @@ -433,6 +433,12 @@ public: NS_IMETHOD GetAttributeStyleSheet(nsIHTMLStyleSheet** aResult); NS_IMETHOD GetInlineStyleSheet(nsIHTMLCSSStyleSheet** aResult); + static nsresult + GetElementsByTagName(nsIContent* aContent, + const nsAString& aTagName, + PRInt32 aNamespaceID, + nsRDFDOMNodeList* aElements); + protected: // Implementation methods friend nsresult diff --git a/mozilla/editor/ui/composer/content/editorUtilities.js b/mozilla/editor/ui/composer/content/editorUtilities.js index a06abd6a7ff..2ca81d90afa 100644 --- a/mozilla/editor/ui/composer/content/editorUtilities.js +++ b/mozilla/editor/ui/composer/content/editorUtilities.js @@ -230,8 +230,8 @@ function GetCurrentEditorElement() var editorList = tmpWindow.document.getElementsByTagName("editor"); // This will change if we support > 1 editor element - if (editorList.item(0)) - return editorList.item(0); + if (editorList && editorList.length > 0) + return editorList[0]; tmpWindow = tmpWindow.opener; }