diff --git a/mozilla/content/base/src/nsContentList.cpp b/mozilla/content/base/src/nsContentList.cpp index 74541585267..b9dc3d604b0 100644 --- a/mozilla/content/base/src/nsContentList.cpp +++ b/mozilla/content/base/src/nsContentList.cpp @@ -25,28 +25,48 @@ #include "nsHTMLAtoms.h" // XXX until atoms get factored into nsLayoutAtoms +nsIAtom* nsContentList::gWildCardAtom = nsnull; + nsContentList::nsContentList(nsIDocument *aDocument) { NS_INIT_REFCNT(); mScriptObject = nsnull; mFunc = nsnull; - mMatchTag = nsnull; + mMatchAtom = nsnull; mDocument = aDocument; + mMatchAll = PR_FALSE; } nsContentList::nsContentList(nsIDocument *aDocument, - const nsString& aMatchTag) + nsIAtom* aMatchAtom, + PRInt32 aMatchNameSpaceId, + nsIContent* aRootContent) { - mMatchTag = new nsString(aMatchTag); + mMatchAtom = aMatchAtom; + NS_IF_ADDREF(mMatchAtom); + if (nsnull == gWildCardAtom) { + gWildCardAtom = NS_NewAtom("*"); + } + if (gWildCardAtom == mMatchAtom) { + mMatchAll = PR_TRUE; + } + else { + mMatchAll = PR_FALSE; + } + mMatchNameSpaceId = aMatchNameSpaceId; mFunc = nsnull; + mRootContent = aRootContent; Init(aDocument); } nsContentList::nsContentList(nsIDocument *aDocument, - nsContentListMatchFunc aFunc) + nsContentListMatchFunc aFunc, + nsIContent* aRootContent) { mFunc = aFunc; - mMatchTag = nsnull; + mMatchAtom = nsnull; + mRootContent = aRootContent; + mMatchAll = PR_FALSE; Init(aDocument); } @@ -61,9 +81,17 @@ void nsContentList::Init(nsIDocument *aDocument) // document's observer list. mDocument = aDocument; mDocument->AddObserver(this); - nsIContent *root = mDocument->GetRootContent(); + nsIContent *root; + if (nsnull != mRootContent) { + root = mRootContent; + } + else { + root = mDocument->GetRootContent(); + } PopulateSelf(root); - NS_RELEASE(root); + if (nsnull == mRootContent) { + NS_RELEASE(root); + } } nsContentList::~nsContentList() @@ -72,9 +100,7 @@ nsContentList::~nsContentList() mDocument->RemoveObserver(this); } - if (nsnull != mMatchTag) { - delete mMatchTag; - } + NS_IF_RELEASE(mMatchAtom); } static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID); @@ -117,11 +143,15 @@ NS_IMPL_RELEASE(nsContentList) NS_IMETHODIMP nsContentList::Match(nsIContent *aContent, PRBool *aMatch) { - if (nsnull != mMatchTag) { + if (nsnull != mMatchAtom) { nsIAtom *name = nsnull; aContent->GetTag(name); - - if ((nsnull !=name) && mMatchTag->EqualsIgnoreCase(name)) { + + if (mMatchAll && (nsnull != name)) { + *aMatch = PR_TRUE; + } + // XXX We don't yet match on namespace. Maybe we should?? + else if (name == mMatchAtom) { *aMatch = PR_TRUE; } else { @@ -143,7 +173,9 @@ nsContentList::Match(nsIContent *aContent, PRBool *aMatch) NS_IMETHODIMP nsContentList::Add(nsIContent *aContent) { - // XXX Should hold a reference ?? + // Shouldn't hold a reference since we'll be + // told when the content leaves the document or + // the document will be destroyed. mContent.AppendElement(aContent); return NS_OK; @@ -152,7 +184,6 @@ nsContentList::Add(nsIContent *aContent) NS_IMETHODIMP nsContentList::Remove(nsIContent *aContent) { - // XXX Should drop a reference ?? mContent.RemoveElement(aContent); return NS_OK; @@ -161,7 +192,6 @@ nsContentList::Remove(nsIContent *aContent) NS_IMETHODIMP nsContentList::Reset() { - // XXX Should drop references ?? mContent.Clear(); return NS_OK; diff --git a/mozilla/content/base/src/nsContentList.h b/mozilla/content/base/src/nsContentList.h index be96ee119a9..14bffbc258d 100644 --- a/mozilla/content/base/src/nsContentList.h +++ b/mozilla/content/base/src/nsContentList.h @@ -34,8 +34,13 @@ class nsContentList : public nsIDOMNodeList, public nsIDOMHTMLCollection, public protected: nsContentList(nsIDocument *aDocument); public: - nsContentList(nsIDocument *aDocument, const nsString& aMatchTag); - nsContentList(nsIDocument *aDocument, nsContentListMatchFunc aFunc); + nsContentList(nsIDocument *aDocument, + nsIAtom* aMatchAtom, + PRInt32 aMatchNameSpaceId, + nsIContent* aRootContent=nsnull); + nsContentList(nsIDocument *aDocument, + nsContentListMatchFunc aFunc, + nsIContent* aRootContent=nsnull); virtual ~nsContentList(); NS_DECL_ISUPPORTS @@ -110,11 +115,16 @@ protected: void PopulateSelf(nsIContent *aContent); PRBool MatchSelf(nsIContent *aContent); - nsString *mMatchTag; + static nsIAtom* gWildCardAtom; + + nsIAtom* mMatchAtom; + PRInt32 mMatchNameSpaceId; nsContentListMatchFunc mFunc; nsVoidArray mContent; void *mScriptObject; nsIDocument *mDocument; + nsIContent* mRootContent; + PRBool mMatchAll; }; #endif // nsContentList_h___ diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index 255cdaa31f4..e21ec6d0b5b 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -70,6 +70,7 @@ static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID); static NS_DEFINE_IID(kIDOMDocumentIID, NS_IDOMDOCUMENT_IID); static NS_DEFINE_IID(kIDOMNSDocumentIID, NS_IDOMNSDOCUMENT_IID); +static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID); static NS_DEFINE_IID(kIDOMAttrIID, NS_IDOMATTR_IID); static NS_DEFINE_IID(kIScriptEventListenerIID, NS_ISCRIPTEVENTLISTENER_IID); static NS_DEFINE_IID(kIDOMEventCapturerIID, NS_IDOMEVENTCAPTURER_IID); @@ -1153,14 +1154,29 @@ NS_IMETHODIMP nsDocument::GetElementsByTagName(const nsString& aTagname, nsIDOMNodeList** aReturn) { - nsContentList* list = new nsContentList(this, aTagname); + nsIAtom* nameAtom; + PRInt32 nameSpaceId; + nsresult result = NS_OK; + + if (nsnull != mRootContent) { + result = mRootContent->ParseAttributeString(aTagname, nameAtom, + nameSpaceId); + if (NS_OK != result) { + return result; + } + } + else { + nameAtom = NS_NewAtom(aTagname); + nameSpaceId = kNameSpaceID_None; + } + + nsContentList* list = new nsContentList(this, nameAtom, nameSpaceId); + NS_IF_RELEASE(nameAtom); if (nsnull == list) { return NS_ERROR_OUT_OF_MEMORY; } - *aReturn = (nsIDOMNodeList *)list; - NS_ADDREF(list); - return NS_OK; + return list->QueryInterface(kIDOMNodeListIID, (void **)aReturn); } NS_IMETHODIMP diff --git a/mozilla/content/base/src/nsGenericElement.cpp b/mozilla/content/base/src/nsGenericElement.cpp index 56842d04473..f4d5236623b 100644 --- a/mozilla/content/base/src/nsGenericElement.cpp +++ b/mozilla/content/base/src/nsGenericElement.cpp @@ -517,7 +517,7 @@ nsGenericElement::RemoveAttributeNode(nsIDOMAttr* aAttribute, nsresult nsGenericElement::GetElementsByTagName(const nsString& aTagname, - nsIDOMNodeList** aReturn) + nsIDOMNodeList** aReturn) { return NS_ERROR_NOT_IMPLEMENTED;/* XXX */ } diff --git a/mozilla/content/html/document/src/nsHTMLDocument.cpp b/mozilla/content/html/document/src/nsHTMLDocument.cpp index 86d7c5df14c..5c088eb8877 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/content/html/document/src/nsHTMLDocument.cpp @@ -730,7 +730,7 @@ NS_IMETHODIMP nsHTMLDocument::GetImages(nsIDOMHTMLCollection** aImages) { if (nsnull == mImages) { - mImages = new nsContentList(this, "IMG"); + mImages = new nsContentList(this, nsHTMLAtoms::img, kNameSpaceID_HTML); if (nsnull == mImages) { return NS_ERROR_OUT_OF_MEMORY; } @@ -747,7 +747,7 @@ NS_IMETHODIMP nsHTMLDocument::GetApplets(nsIDOMHTMLCollection** aApplets) { if (nsnull == mApplets) { - mApplets = new nsContentList(this, "APPLET"); + mApplets = new nsContentList(this, nsHTMLAtoms::applet, kNameSpaceID_HTML); if (nsnull == mApplets) { return NS_ERROR_OUT_OF_MEMORY; } @@ -765,12 +765,11 @@ nsHTMLDocument::MatchLinks(nsIContent *aContent) { nsIAtom *name; aContent->GetTag(name); - static nsAutoString area("AREA"), anchor("A"); nsAutoString attr; PRBool result = PR_FALSE; if ((nsnull != name) && - (area.EqualsIgnoreCase(name) || anchor.EqualsIgnoreCase(name)) && + ((nsHTMLAtoms::area == name) || (nsHTMLAtoms::a == name)) && (NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, attr))) { result = PR_TRUE; } @@ -801,12 +800,11 @@ nsHTMLDocument::MatchAnchors(nsIContent *aContent) { nsIAtom *name; aContent->GetTag(name); - static nsAutoString anchor("A"); nsAutoString attr; PRBool result = PR_FALSE; if ((nsnull != name) && - anchor.EqualsIgnoreCase(name) && + (nsHTMLAtoms::a == name) && (NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::name, attr))) { result = PR_TRUE; } @@ -1116,7 +1114,7 @@ NS_IMETHODIMP nsHTMLDocument::GetEmbeds(nsIDOMHTMLCollection** aEmbeds) { if (nsnull == mEmbeds) { - mEmbeds = new nsContentList(this, "EMBED"); + mEmbeds = new nsContentList(this, nsHTMLAtoms::embed, kNameSpaceID_HTML); if (nsnull == mEmbeds) { return NS_ERROR_OUT_OF_MEMORY; } @@ -2298,8 +2296,7 @@ nsHTMLDocument::AddForm(nsIDOMHTMLFormElement *aForm) // Initialize mForms if necessary... if (nsnull == mForms) { - nsAutoString tag("form"); - mForms = new nsContentList(this, tag); + mForms = new nsContentList(this, nsHTMLAtoms::form, kNameSpaceID_HTML); NS_ADDREF(mForms); } @@ -2313,8 +2310,7 @@ NS_IMETHODIMP nsHTMLDocument::GetForms(nsIDOMHTMLCollection** aForms) { if (nsnull == mForms) { - nsAutoString tag("form"); - mForms = new nsContentList(this, tag); + mForms = new nsContentList(this, nsHTMLAtoms::form, kNameSpaceID_HTML); if (nsnull == mForms) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/mozilla/layout/base/src/nsContentList.cpp b/mozilla/layout/base/src/nsContentList.cpp index 74541585267..b9dc3d604b0 100644 --- a/mozilla/layout/base/src/nsContentList.cpp +++ b/mozilla/layout/base/src/nsContentList.cpp @@ -25,28 +25,48 @@ #include "nsHTMLAtoms.h" // XXX until atoms get factored into nsLayoutAtoms +nsIAtom* nsContentList::gWildCardAtom = nsnull; + nsContentList::nsContentList(nsIDocument *aDocument) { NS_INIT_REFCNT(); mScriptObject = nsnull; mFunc = nsnull; - mMatchTag = nsnull; + mMatchAtom = nsnull; mDocument = aDocument; + mMatchAll = PR_FALSE; } nsContentList::nsContentList(nsIDocument *aDocument, - const nsString& aMatchTag) + nsIAtom* aMatchAtom, + PRInt32 aMatchNameSpaceId, + nsIContent* aRootContent) { - mMatchTag = new nsString(aMatchTag); + mMatchAtom = aMatchAtom; + NS_IF_ADDREF(mMatchAtom); + if (nsnull == gWildCardAtom) { + gWildCardAtom = NS_NewAtom("*"); + } + if (gWildCardAtom == mMatchAtom) { + mMatchAll = PR_TRUE; + } + else { + mMatchAll = PR_FALSE; + } + mMatchNameSpaceId = aMatchNameSpaceId; mFunc = nsnull; + mRootContent = aRootContent; Init(aDocument); } nsContentList::nsContentList(nsIDocument *aDocument, - nsContentListMatchFunc aFunc) + nsContentListMatchFunc aFunc, + nsIContent* aRootContent) { mFunc = aFunc; - mMatchTag = nsnull; + mMatchAtom = nsnull; + mRootContent = aRootContent; + mMatchAll = PR_FALSE; Init(aDocument); } @@ -61,9 +81,17 @@ void nsContentList::Init(nsIDocument *aDocument) // document's observer list. mDocument = aDocument; mDocument->AddObserver(this); - nsIContent *root = mDocument->GetRootContent(); + nsIContent *root; + if (nsnull != mRootContent) { + root = mRootContent; + } + else { + root = mDocument->GetRootContent(); + } PopulateSelf(root); - NS_RELEASE(root); + if (nsnull == mRootContent) { + NS_RELEASE(root); + } } nsContentList::~nsContentList() @@ -72,9 +100,7 @@ nsContentList::~nsContentList() mDocument->RemoveObserver(this); } - if (nsnull != mMatchTag) { - delete mMatchTag; - } + NS_IF_RELEASE(mMatchAtom); } static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID); @@ -117,11 +143,15 @@ NS_IMPL_RELEASE(nsContentList) NS_IMETHODIMP nsContentList::Match(nsIContent *aContent, PRBool *aMatch) { - if (nsnull != mMatchTag) { + if (nsnull != mMatchAtom) { nsIAtom *name = nsnull; aContent->GetTag(name); - - if ((nsnull !=name) && mMatchTag->EqualsIgnoreCase(name)) { + + if (mMatchAll && (nsnull != name)) { + *aMatch = PR_TRUE; + } + // XXX We don't yet match on namespace. Maybe we should?? + else if (name == mMatchAtom) { *aMatch = PR_TRUE; } else { @@ -143,7 +173,9 @@ nsContentList::Match(nsIContent *aContent, PRBool *aMatch) NS_IMETHODIMP nsContentList::Add(nsIContent *aContent) { - // XXX Should hold a reference ?? + // Shouldn't hold a reference since we'll be + // told when the content leaves the document or + // the document will be destroyed. mContent.AppendElement(aContent); return NS_OK; @@ -152,7 +184,6 @@ nsContentList::Add(nsIContent *aContent) NS_IMETHODIMP nsContentList::Remove(nsIContent *aContent) { - // XXX Should drop a reference ?? mContent.RemoveElement(aContent); return NS_OK; @@ -161,7 +192,6 @@ nsContentList::Remove(nsIContent *aContent) NS_IMETHODIMP nsContentList::Reset() { - // XXX Should drop references ?? mContent.Clear(); return NS_OK; diff --git a/mozilla/layout/base/src/nsContentList.h b/mozilla/layout/base/src/nsContentList.h index be96ee119a9..14bffbc258d 100644 --- a/mozilla/layout/base/src/nsContentList.h +++ b/mozilla/layout/base/src/nsContentList.h @@ -34,8 +34,13 @@ class nsContentList : public nsIDOMNodeList, public nsIDOMHTMLCollection, public protected: nsContentList(nsIDocument *aDocument); public: - nsContentList(nsIDocument *aDocument, const nsString& aMatchTag); - nsContentList(nsIDocument *aDocument, nsContentListMatchFunc aFunc); + nsContentList(nsIDocument *aDocument, + nsIAtom* aMatchAtom, + PRInt32 aMatchNameSpaceId, + nsIContent* aRootContent=nsnull); + nsContentList(nsIDocument *aDocument, + nsContentListMatchFunc aFunc, + nsIContent* aRootContent=nsnull); virtual ~nsContentList(); NS_DECL_ISUPPORTS @@ -110,11 +115,16 @@ protected: void PopulateSelf(nsIContent *aContent); PRBool MatchSelf(nsIContent *aContent); - nsString *mMatchTag; + static nsIAtom* gWildCardAtom; + + nsIAtom* mMatchAtom; + PRInt32 mMatchNameSpaceId; nsContentListMatchFunc mFunc; nsVoidArray mContent; void *mScriptObject; nsIDocument *mDocument; + nsIContent* mRootContent; + PRBool mMatchAll; }; #endif // nsContentList_h___ diff --git a/mozilla/layout/base/src/nsDocument.cpp b/mozilla/layout/base/src/nsDocument.cpp index 255cdaa31f4..e21ec6d0b5b 100644 --- a/mozilla/layout/base/src/nsDocument.cpp +++ b/mozilla/layout/base/src/nsDocument.cpp @@ -70,6 +70,7 @@ static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID); static NS_DEFINE_IID(kIDOMDocumentIID, NS_IDOMDOCUMENT_IID); static NS_DEFINE_IID(kIDOMNSDocumentIID, NS_IDOMNSDOCUMENT_IID); +static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID); static NS_DEFINE_IID(kIDOMAttrIID, NS_IDOMATTR_IID); static NS_DEFINE_IID(kIScriptEventListenerIID, NS_ISCRIPTEVENTLISTENER_IID); static NS_DEFINE_IID(kIDOMEventCapturerIID, NS_IDOMEVENTCAPTURER_IID); @@ -1153,14 +1154,29 @@ NS_IMETHODIMP nsDocument::GetElementsByTagName(const nsString& aTagname, nsIDOMNodeList** aReturn) { - nsContentList* list = new nsContentList(this, aTagname); + nsIAtom* nameAtom; + PRInt32 nameSpaceId; + nsresult result = NS_OK; + + if (nsnull != mRootContent) { + result = mRootContent->ParseAttributeString(aTagname, nameAtom, + nameSpaceId); + if (NS_OK != result) { + return result; + } + } + else { + nameAtom = NS_NewAtom(aTagname); + nameSpaceId = kNameSpaceID_None; + } + + nsContentList* list = new nsContentList(this, nameAtom, nameSpaceId); + NS_IF_RELEASE(nameAtom); if (nsnull == list) { return NS_ERROR_OUT_OF_MEMORY; } - *aReturn = (nsIDOMNodeList *)list; - NS_ADDREF(list); - return NS_OK; + return list->QueryInterface(kIDOMNodeListIID, (void **)aReturn); } NS_IMETHODIMP diff --git a/mozilla/layout/base/src/nsGenericElement.cpp b/mozilla/layout/base/src/nsGenericElement.cpp index 56842d04473..f4d5236623b 100644 --- a/mozilla/layout/base/src/nsGenericElement.cpp +++ b/mozilla/layout/base/src/nsGenericElement.cpp @@ -517,7 +517,7 @@ nsGenericElement::RemoveAttributeNode(nsIDOMAttr* aAttribute, nsresult nsGenericElement::GetElementsByTagName(const nsString& aTagname, - nsIDOMNodeList** aReturn) + nsIDOMNodeList** aReturn) { return NS_ERROR_NOT_IMPLEMENTED;/* XXX */ } diff --git a/mozilla/layout/html/document/src/nsHTMLDocument.cpp b/mozilla/layout/html/document/src/nsHTMLDocument.cpp index 86d7c5df14c..5c088eb8877 100644 --- a/mozilla/layout/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/layout/html/document/src/nsHTMLDocument.cpp @@ -730,7 +730,7 @@ NS_IMETHODIMP nsHTMLDocument::GetImages(nsIDOMHTMLCollection** aImages) { if (nsnull == mImages) { - mImages = new nsContentList(this, "IMG"); + mImages = new nsContentList(this, nsHTMLAtoms::img, kNameSpaceID_HTML); if (nsnull == mImages) { return NS_ERROR_OUT_OF_MEMORY; } @@ -747,7 +747,7 @@ NS_IMETHODIMP nsHTMLDocument::GetApplets(nsIDOMHTMLCollection** aApplets) { if (nsnull == mApplets) { - mApplets = new nsContentList(this, "APPLET"); + mApplets = new nsContentList(this, nsHTMLAtoms::applet, kNameSpaceID_HTML); if (nsnull == mApplets) { return NS_ERROR_OUT_OF_MEMORY; } @@ -765,12 +765,11 @@ nsHTMLDocument::MatchLinks(nsIContent *aContent) { nsIAtom *name; aContent->GetTag(name); - static nsAutoString area("AREA"), anchor("A"); nsAutoString attr; PRBool result = PR_FALSE; if ((nsnull != name) && - (area.EqualsIgnoreCase(name) || anchor.EqualsIgnoreCase(name)) && + ((nsHTMLAtoms::area == name) || (nsHTMLAtoms::a == name)) && (NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, attr))) { result = PR_TRUE; } @@ -801,12 +800,11 @@ nsHTMLDocument::MatchAnchors(nsIContent *aContent) { nsIAtom *name; aContent->GetTag(name); - static nsAutoString anchor("A"); nsAutoString attr; PRBool result = PR_FALSE; if ((nsnull != name) && - anchor.EqualsIgnoreCase(name) && + (nsHTMLAtoms::a == name) && (NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::name, attr))) { result = PR_TRUE; } @@ -1116,7 +1114,7 @@ NS_IMETHODIMP nsHTMLDocument::GetEmbeds(nsIDOMHTMLCollection** aEmbeds) { if (nsnull == mEmbeds) { - mEmbeds = new nsContentList(this, "EMBED"); + mEmbeds = new nsContentList(this, nsHTMLAtoms::embed, kNameSpaceID_HTML); if (nsnull == mEmbeds) { return NS_ERROR_OUT_OF_MEMORY; } @@ -2298,8 +2296,7 @@ nsHTMLDocument::AddForm(nsIDOMHTMLFormElement *aForm) // Initialize mForms if necessary... if (nsnull == mForms) { - nsAutoString tag("form"); - mForms = new nsContentList(this, tag); + mForms = new nsContentList(this, nsHTMLAtoms::form, kNameSpaceID_HTML); NS_ADDREF(mForms); } @@ -2313,8 +2310,7 @@ NS_IMETHODIMP nsHTMLDocument::GetForms(nsIDOMHTMLCollection** aForms) { if (nsnull == mForms) { - nsAutoString tag("form"); - mForms = new nsContentList(this, tag); + mForms = new nsContentList(this, nsHTMLAtoms::form, kNameSpaceID_HTML); if (nsnull == mForms) { return NS_ERROR_OUT_OF_MEMORY; }