зеркало из https://github.com/mozilla/pjs.git
Implemented Element::GetElementsByTagName. Fixed bug 2327 - forms appearing multiple times in document.forms array.
This commit is contained in:
Родитель
398493209d
Коммит
572ca70ca6
|
@ -22,6 +22,8 @@
|
|||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIDOMScriptObjectFactory.h"
|
||||
#include "nsGenericElement.h"
|
||||
|
||||
#include "nsHTMLAtoms.h" // XXX until atoms get factored into nsLayoutAtoms
|
||||
|
||||
|
@ -74,24 +76,16 @@ void nsContentList::Init(nsIDocument *aDocument)
|
|||
{
|
||||
NS_INIT_REFCNT();
|
||||
mScriptObject = nsnull;
|
||||
// XXX We don't reference count this reference.
|
||||
// We don't reference count the reference to the document
|
||||
// If the document goes away first, we'll be informed and we
|
||||
// can drop our reference.
|
||||
// If we go away first, we'll get rid of ourselves from the
|
||||
// document's observer list.
|
||||
mDocument = aDocument;
|
||||
mDocument->AddObserver(this);
|
||||
nsIContent *root;
|
||||
if (nsnull != mRootContent) {
|
||||
root = mRootContent;
|
||||
}
|
||||
else {
|
||||
root = mDocument->GetRootContent();
|
||||
}
|
||||
PopulateSelf(root);
|
||||
if (nsnull == mRootContent) {
|
||||
NS_RELEASE(root);
|
||||
if (nsnull != mDocument) {
|
||||
mDocument->AddObserver(this);
|
||||
}
|
||||
PopulateSelf();
|
||||
}
|
||||
|
||||
nsContentList::~nsContentList()
|
||||
|
@ -103,11 +97,8 @@ nsContentList::~nsContentList()
|
|||
NS_IF_RELEASE(mMatchAtom);
|
||||
}
|
||||
|
||||
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
|
||||
static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID);
|
||||
static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID);
|
||||
static NS_DEFINE_IID(kIDOMHTMLCollectionIID, NS_IDOMHTMLCOLLECTION_IID);
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
|
||||
nsresult nsContentList::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
|
@ -141,12 +132,194 @@ NS_IMPL_ADDREF(nsContentList)
|
|||
NS_IMPL_RELEASE(nsContentList)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::GetLength(PRUint32* aLength)
|
||||
{
|
||||
nsresult result = CheckDocumentExistence();
|
||||
if (NS_OK == result) {
|
||||
*aLength = mContent.Count();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
|
||||
{
|
||||
nsresult result = CheckDocumentExistence();
|
||||
if (NS_OK == result) {
|
||||
nsISupports *element = (nsISupports *)mContent.ElementAt(aIndex);
|
||||
|
||||
if (nsnull != element) {
|
||||
result = element->QueryInterface(kIDOMNodeIID, (void **)aReturn);
|
||||
}
|
||||
else {
|
||||
*aReturn = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
|
||||
{
|
||||
nsresult result = CheckDocumentExistence();
|
||||
|
||||
if (NS_OK == result) {
|
||||
PRInt32 i, count = mContent.Count();
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
nsIContent *content = (nsIContent *)mContent.ElementAt(i);
|
||||
if (nsnull != content) {
|
||||
nsAutoString name;
|
||||
// XXX Should it be an EqualsIgnoreCase?
|
||||
if (((content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::name, name) == NS_CONTENT_ATTR_HAS_VALUE) &&
|
||||
(aName.Equals(name))) ||
|
||||
((content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::id, name) == NS_CONTENT_ATTR_HAS_VALUE) &&
|
||||
(aName.Equals(name)))) {
|
||||
return content->QueryInterface(kIDOMNodeIID, (void **)aReturn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*aReturn = nsnull;
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
|
||||
{
|
||||
nsresult res = NS_OK;
|
||||
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
|
||||
|
||||
if (nsnull == mScriptObject) {
|
||||
nsIDOMScriptObjectFactory *factory;
|
||||
|
||||
res = nsGenericElement::GetScriptObjectFactory(&factory);
|
||||
if (NS_OK != res) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = factory->NewScriptHTMLCollection(aContext,
|
||||
(nsISupports*)(nsIDOMHTMLCollection*)this,
|
||||
global,
|
||||
(void**)&mScriptObject);
|
||||
NS_RELEASE(factory);
|
||||
}
|
||||
*aScriptObject = mScriptObject;
|
||||
|
||||
NS_RELEASE(global);
|
||||
return res;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::SetScriptObject(void *aScriptObject)
|
||||
{
|
||||
mScriptObject = aScriptObject;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::ContentAppended(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
PRInt32 aNewIndexInContainer)
|
||||
{
|
||||
PRInt32 i, count;
|
||||
aContainer->ChildCount(count);
|
||||
if ((count > 0) && IsDescendantOfRoot(aContainer)) {
|
||||
PRBool repopulate = PR_FALSE;
|
||||
for (i = aNewIndexInContainer; i <= count-1; i++) {
|
||||
nsIContent *content;
|
||||
aContainer->ChildAt(i, content);
|
||||
if (mMatchAll || MatchSelf(content)) {
|
||||
repopulate = PR_TRUE;
|
||||
}
|
||||
NS_RELEASE(content);
|
||||
}
|
||||
if (repopulate) {
|
||||
PopulateSelf();
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::ContentInserted(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (IsDescendantOfRoot(aContainer)) {
|
||||
if (mMatchAll || MatchSelf(aChild)) {
|
||||
PopulateSelf();
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::ContentReplaced(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aOldChild,
|
||||
nsIContent* aNewChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (IsDescendantOfRoot(aContainer)) {
|
||||
if (mMatchAll || MatchSelf(aOldChild) || MatchSelf(aNewChild)) {
|
||||
PopulateSelf();
|
||||
}
|
||||
}
|
||||
else if (ContainsRoot(aOldChild)) {
|
||||
DisconnectFromDocument();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::ContentRemoved(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (IsDescendantOfRoot(aContainer) && MatchSelf(aChild)) {
|
||||
PopulateSelf();
|
||||
}
|
||||
else if (ContainsRoot(aChild)) {
|
||||
DisconnectFromDocument();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::DocumentWillBeDestroyed(nsIDocument *aDocument)
|
||||
{
|
||||
if (nsnull != mDocument) {
|
||||
aDocument->RemoveObserver(this);
|
||||
mDocument = nsnull;
|
||||
}
|
||||
Reset();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// Returns whether the content element matches the
|
||||
// criterion
|
||||
nsresult
|
||||
nsContentList::Match(nsIContent *aContent, PRBool *aMatch)
|
||||
{
|
||||
if (nsnull != mMatchAtom) {
|
||||
nsIAtom *name = nsnull;
|
||||
aContent->GetTag(name);
|
||||
|
||||
// If we have to match all, only do those that have
|
||||
// a tagName i.e. only the elements.
|
||||
if (mMatchAll && (nsnull != name)) {
|
||||
*aMatch = PR_TRUE;
|
||||
}
|
||||
|
@ -170,7 +343,7 @@ nsContentList::Match(nsIContent *aContent, PRBool *aMatch)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsContentList::Add(nsIContent *aContent)
|
||||
{
|
||||
// Shouldn't hold a reference since we'll be
|
||||
|
@ -181,7 +354,7 @@ nsContentList::Add(nsIContent *aContent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsContentList::Remove(nsIContent *aContent)
|
||||
{
|
||||
mContent.RemoveElement(aContent);
|
||||
|
@ -189,7 +362,7 @@ nsContentList::Remove(nsIContent *aContent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsContentList::Reset()
|
||||
{
|
||||
mContent.Clear();
|
||||
|
@ -197,75 +370,28 @@ nsContentList::Reset()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::GetLength(PRUint32* aLength)
|
||||
// If we were created outside the context of a document and we
|
||||
// have root content, then check if our content has been added
|
||||
// to a document yet. If so, we'll become an observer of the document.
|
||||
nsresult
|
||||
nsContentList::CheckDocumentExistence()
|
||||
{
|
||||
*aLength = mContent.Count();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
|
||||
{
|
||||
nsISupports *element = (nsISupports *)mContent.ElementAt(aIndex);
|
||||
|
||||
if (nsnull != element) {
|
||||
return element->QueryInterface(kIDOMNodeIID, (void **)aReturn);
|
||||
}
|
||||
else {
|
||||
*aReturn = nsnull;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
|
||||
{
|
||||
PRInt32 i, count = mContent.Count();
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
nsIContent *content = (nsIContent *)mContent.ElementAt(i);
|
||||
if (nsnull != content) {
|
||||
nsAutoString name;
|
||||
// XXX Should it be an EqualsIgnoreCase?
|
||||
if (((content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::name, name) == NS_CONTENT_ATTR_HAS_VALUE) &&
|
||||
(aName.Equals(name))) ||
|
||||
((content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::id, name) == NS_CONTENT_ATTR_HAS_VALUE) &&
|
||||
(aName.Equals(name)))) {
|
||||
return content->QueryInterface(kIDOMNodeIID, (void **)aReturn);
|
||||
}
|
||||
nsresult result = NS_OK;
|
||||
if ((nsnull == mDocument) && (nsnull != mRootContent)) {
|
||||
result = mRootContent->GetDocument(mDocument);
|
||||
if (nsnull != mDocument) {
|
||||
mDocument->AddObserver(this);
|
||||
PopulateSelf();
|
||||
}
|
||||
}
|
||||
|
||||
*aReturn = nsnull;
|
||||
return NS_OK;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
|
||||
{
|
||||
nsresult res = NS_OK;
|
||||
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
|
||||
|
||||
if (nsnull == mScriptObject) {
|
||||
res = NS_NewScriptHTMLCollection(aContext, (nsISupports*)(nsIDOMHTMLCollection*)this, global, (void**)&mScriptObject);
|
||||
}
|
||||
*aScriptObject = mScriptObject;
|
||||
|
||||
NS_RELEASE(global);
|
||||
return res;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::SetScriptObject(void *aScriptObject)
|
||||
{
|
||||
mScriptObject = aScriptObject;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool nsContentList::MatchSelf(nsIContent *aContent)
|
||||
// Match recursively. See if anything in the subtree
|
||||
// matches the criterion.
|
||||
PRBool
|
||||
nsContentList::MatchSelf(nsIContent *aContent)
|
||||
{
|
||||
PRBool match;
|
||||
PRInt32 i, count;
|
||||
|
@ -289,104 +415,110 @@ PRBool nsContentList::MatchSelf(nsIContent *aContent)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
void nsContentList::PopulateSelf(nsIContent *aContent)
|
||||
// Add all elements in this subtree that match to
|
||||
// our list.
|
||||
void
|
||||
nsContentList::PopulateWith(nsIContent *aContent, PRBool aIncludeRoot)
|
||||
{
|
||||
PRBool match;
|
||||
PRInt32 i, count;
|
||||
|
||||
Match(aContent, &match);
|
||||
if (match) {
|
||||
Add(aContent);
|
||||
if (aIncludeRoot) {
|
||||
Match(aContent, &match);
|
||||
if (match) {
|
||||
Add(aContent);
|
||||
}
|
||||
}
|
||||
|
||||
aContent->ChildCount(count);
|
||||
for (i = 0; i < count; i++) {
|
||||
nsIContent *child;
|
||||
aContent->ChildAt(i, child);
|
||||
PopulateSelf(child);
|
||||
PopulateWith(child, PR_TRUE);
|
||||
NS_RELEASE(child);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::ContentAppended(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
PRInt32 aNewIndexInContainer)
|
||||
// Clear out our old list and build up a new one
|
||||
void
|
||||
nsContentList::PopulateSelf()
|
||||
{
|
||||
PRInt32 count;
|
||||
aContainer->ChildCount(count);
|
||||
if (count > 0) {
|
||||
nsIContent *content;
|
||||
aContainer->ChildAt(count-1, content);
|
||||
if (MatchSelf(content)) {
|
||||
Reset();
|
||||
nsIContent *root = aDocument->GetRootContent();
|
||||
PopulateSelf(root);
|
||||
NS_RELEASE(root);
|
||||
Reset();
|
||||
if (nsnull != mRootContent) {
|
||||
PopulateWith(mRootContent, PR_FALSE);
|
||||
}
|
||||
else if (nsnull != mDocument) {
|
||||
nsIContent *root;
|
||||
root = mDocument->GetRootContent();
|
||||
PopulateWith(root, PR_TRUE);
|
||||
NS_RELEASE(root);
|
||||
}
|
||||
}
|
||||
|
||||
// Is the specified element a descendant of the root? If there
|
||||
// is no root, then yes. Otherwise keep tracing up the tree from
|
||||
// the element till we find our root, or until we reach the
|
||||
// document root.
|
||||
PRBool
|
||||
nsContentList::IsDescendantOfRoot(nsIContent* aContainer)
|
||||
{
|
||||
if (nsnull == mRootContent) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
else if (mRootContent == aContainer) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
else if (nsnull == aContainer) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
else {
|
||||
nsIContent* parent;
|
||||
PRBool ret;
|
||||
|
||||
aContainer->GetParent(parent);
|
||||
ret = IsDescendantOfRoot(parent);
|
||||
NS_IF_RELEASE(parent);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// Does this subtree contain the root?
|
||||
PRBool
|
||||
nsContentList::ContainsRoot(nsIContent* aContent)
|
||||
{
|
||||
if (nsnull == mRootContent) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
else if (mRootContent == aContent) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
else {
|
||||
PRInt32 i, count;
|
||||
|
||||
aContent->ChildCount(count);
|
||||
for (i = 0; i < count; i++) {
|
||||
nsIContent *child;
|
||||
aContent->ChildAt(i, child);
|
||||
if (ContainsRoot(child)) {
|
||||
NS_RELEASE(child);
|
||||
return PR_TRUE;
|
||||
}
|
||||
NS_RELEASE(child);
|
||||
}
|
||||
NS_RELEASE(content);
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::ContentInserted(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (MatchSelf(aChild)) {
|
||||
Reset();
|
||||
nsIContent *root = aDocument->GetRootContent();
|
||||
PopulateSelf(root);
|
||||
NS_RELEASE(root);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::ContentReplaced(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aOldChild,
|
||||
nsIContent* aNewChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (MatchSelf(aOldChild) || MatchSelf(aNewChild)) {
|
||||
Reset();
|
||||
nsIContent *root = aDocument->GetRootContent();
|
||||
PopulateSelf(root);
|
||||
NS_RELEASE(root);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::ContentRemoved(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (MatchSelf(aChild)) {
|
||||
Reset();
|
||||
nsIContent *root = aDocument->GetRootContent();
|
||||
PopulateSelf(root);
|
||||
NS_RELEASE(root);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::DocumentWillBeDestroyed(nsIDocument *aDocument)
|
||||
// Our root content has been disconnected from the
|
||||
// document, so stop observing. The list then becomes
|
||||
// a snapshot rather than a dynamic list.
|
||||
void
|
||||
nsContentList::DisconnectFromDocument()
|
||||
{
|
||||
if (nsnull != mDocument) {
|
||||
aDocument->RemoveObserver(this);
|
||||
mDocument->RemoveObserver(this);
|
||||
mDocument = nsnull;
|
||||
}
|
||||
Reset();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -45,23 +45,18 @@ public:
|
|||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Match(nsIContent *aContent, PRBool *aMatch);
|
||||
|
||||
NS_IMETHOD Add(nsIContent *aContent);
|
||||
|
||||
NS_IMETHOD Remove(nsIContent *aContent);
|
||||
|
||||
NS_IMETHOD Reset();
|
||||
|
||||
// nsIDOMHTMLCollection
|
||||
NS_IMETHOD GetLength(PRUint32* aLength);
|
||||
|
||||
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn);
|
||||
|
||||
NS_IMETHOD NamedItem(const nsString& aName, nsIDOMNode** aReturn);
|
||||
|
||||
// nsIScriptObjectOwner
|
||||
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
|
||||
NS_IMETHOD SetScriptObject(void *aScriptObject);
|
||||
|
||||
// nsIDocumentObserver
|
||||
NS_IMETHOD BeginUpdate(nsIDocument *aDocument) { return NS_OK; }
|
||||
NS_IMETHOD EndUpdate(nsIDocument *aDocument) { return NS_OK; }
|
||||
NS_IMETHOD BeginLoad(nsIDocument *aDocument) { return NS_OK; }
|
||||
|
@ -111,9 +106,18 @@ public:
|
|||
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument);
|
||||
|
||||
protected:
|
||||
nsresult Match(nsIContent *aContent, PRBool *aMatch);
|
||||
nsresult Add(nsIContent *aContent);
|
||||
nsresult Remove(nsIContent *aContent);
|
||||
nsresult Reset();
|
||||
void Init(nsIDocument *aDocument);
|
||||
void PopulateSelf(nsIContent *aContent);
|
||||
void PopulateWith(nsIContent *aContent, PRBool aIncludeRoot);
|
||||
PRBool MatchSelf(nsIContent *aContent);
|
||||
void PopulateSelf();
|
||||
void DisconnectFromDocument();
|
||||
PRBool IsDescendantOfRoot(nsIContent* aContainer);
|
||||
PRBool ContainsRoot(nsIContent* aContent);
|
||||
nsresult CheckDocumentExistence();
|
||||
|
||||
static nsIAtom* gWildCardAtom;
|
||||
|
||||
|
|
|
@ -883,6 +883,12 @@ nsDocument::BeginLoad()
|
|||
for (i = 0; i < count; i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i];
|
||||
observer->BeginLoad(this);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -894,6 +900,12 @@ nsDocument::EndLoad()
|
|||
for (i = 0; i < count; i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i];
|
||||
observer->EndLoad(this);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -906,6 +918,12 @@ nsDocument::ContentChanged(nsIContent* aContent,
|
|||
for (PRInt32 i = 0; i < count; i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->ContentChanged(this, aContent, aSubContent);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -918,6 +936,12 @@ nsDocument::ContentAppended(nsIContent* aContainer,
|
|||
for (PRInt32 i = 0; i < count; i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->ContentAppended(this, aContainer, aNewIndexInContainer);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -931,6 +955,12 @@ nsDocument::ContentInserted(nsIContent* aContainer,
|
|||
for (PRInt32 i = 0; i < count; i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->ContentInserted(this, aContainer, aChild, aIndexInContainer);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -946,6 +976,12 @@ nsDocument::ContentReplaced(nsIContent* aContainer,
|
|||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->ContentReplaced(this, aContainer, aOldChild, aNewChild,
|
||||
aIndexInContainer);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -960,6 +996,12 @@ nsDocument::ContentRemoved(nsIContent* aContainer,
|
|||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->ContentRemoved(this, aContainer,
|
||||
aChild, aIndexInContainer);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -973,6 +1015,12 @@ nsDocument::AttributeChanged(nsIContent* aChild,
|
|||
for (PRInt32 i = 0; i < count; i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->AttributeChanged(this, aChild, aAttribute, aHint);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -986,6 +1034,12 @@ nsDocument::StyleRuleChanged(nsIStyleSheet* aStyleSheet, nsIStyleRule* aStyleRul
|
|||
for (PRInt32 i = 0; i < count; i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->StyleRuleChanged(this, aStyleSheet, aStyleRule, aHint);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -997,6 +1051,12 @@ nsDocument::StyleRuleAdded(nsIStyleSheet* aStyleSheet, nsIStyleRule* aStyleRule)
|
|||
for (PRInt32 i = 0; i < count; i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->StyleRuleAdded(this, aStyleSheet, aStyleRule);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1008,6 +1068,12 @@ nsDocument::StyleRuleRemoved(nsIStyleSheet* aStyleSheet, nsIStyleRule* aStyleRul
|
|||
for (PRInt32 i = 0; i < count; i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->StyleRuleRemoved(this, aStyleSheet, aStyleRule);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "nsIDOMCSSStyleDeclaration.h"
|
||||
#include "nsDOMCSSDeclaration.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsContentList.h"
|
||||
#include "prprf.h"
|
||||
#include "prmem.h"
|
||||
|
||||
|
@ -119,7 +120,19 @@ nsChildContentList::GetScriptObject(nsIScriptContext *aContext, void** aScriptOb
|
|||
{
|
||||
nsresult res = NS_OK;
|
||||
if (nsnull == mScriptObject) {
|
||||
res = NS_NewScriptNodeList(aContext, (nsISupports *)(nsIDOMNodeList *)this, mContent, (void**)&mScriptObject);
|
||||
nsIDOMScriptObjectFactory *factory;
|
||||
|
||||
res = nsGenericElement::GetScriptObjectFactory(&factory);
|
||||
if (NS_OK != res) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = factory->NewScriptNodeList(aContext,
|
||||
(nsISupports *)(nsIDOMNodeList *)this,
|
||||
mContent,
|
||||
(void**)&mScriptObject);
|
||||
|
||||
NS_RELEASE(factory);
|
||||
}
|
||||
*aScriptObject = mScriptObject;
|
||||
return res;
|
||||
|
@ -519,7 +532,26 @@ nsresult
|
|||
nsGenericElement::GetElementsByTagName(const nsString& aTagname,
|
||||
nsIDOMNodeList** aReturn)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;/* XXX */
|
||||
nsIAtom* nameAtom;
|
||||
PRInt32 nameSpaceId;
|
||||
nsresult result = NS_OK;
|
||||
|
||||
result = mContent->ParseAttributeString(aTagname, nameAtom,
|
||||
nameSpaceId);
|
||||
if (NS_OK != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
nsContentList* list = new nsContentList(mDocument,
|
||||
nameAtom,
|
||||
nameSpaceId,
|
||||
mContent);
|
||||
NS_IF_RELEASE(nameAtom);
|
||||
if (nsnull == list) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return list->QueryInterface(kIDOMNodeListIID, (void **)aReturn);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -152,10 +152,8 @@ nsHTMLDocument::~nsHTMLDocument()
|
|||
nsIDOMHTMLMapElement* map = (nsIDOMHTMLMapElement*)mImageMaps.ElementAt(i);
|
||||
NS_RELEASE(map);
|
||||
}
|
||||
if (mForms) {
|
||||
mForms->Reset();
|
||||
NS_RELEASE(mForms);
|
||||
}
|
||||
NS_IF_RELEASE(mForms);
|
||||
|
||||
// XXX don't bother doing this until the dll is unloaded???
|
||||
// nsHTMLAtoms::ReleaseAtoms();
|
||||
|
||||
|
@ -228,10 +226,7 @@ nsHTMLDocument::Reset(nsIURL *aURL)
|
|||
nsIDOMHTMLMapElement* map = (nsIDOMHTMLMapElement*)mImageMaps.ElementAt(i);
|
||||
NS_RELEASE(map);
|
||||
}
|
||||
if (mForms) {
|
||||
mForms->Reset();
|
||||
NS_RELEASE(mForms);
|
||||
}
|
||||
NS_IF_RELEASE(mForms);
|
||||
|
||||
if (nsnull != mAttrStyleSheet) {
|
||||
mAttrStyleSheet->SetOwningDocument(nsnull);
|
||||
|
@ -2284,6 +2279,8 @@ nsHTMLDocument::GetBodyContent()
|
|||
NS_IMETHODIMP
|
||||
nsHTMLDocument::AddForm(nsIDOMHTMLFormElement *aForm)
|
||||
{
|
||||
#if 0
|
||||
// Not necessary anymore since forms are real content now
|
||||
NS_PRECONDITION(nsnull != aForm, "null ptr");
|
||||
if (nsnull == aForm) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
@ -2304,6 +2301,8 @@ nsHTMLDocument::AddForm(nsIDOMHTMLFormElement *aForm)
|
|||
NS_RELEASE(iContent);
|
||||
}
|
||||
return result;
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIDOMScriptObjectFactory.h"
|
||||
#include "nsGenericElement.h"
|
||||
|
||||
#include "nsHTMLAtoms.h" // XXX until atoms get factored into nsLayoutAtoms
|
||||
|
||||
|
@ -74,24 +76,16 @@ void nsContentList::Init(nsIDocument *aDocument)
|
|||
{
|
||||
NS_INIT_REFCNT();
|
||||
mScriptObject = nsnull;
|
||||
// XXX We don't reference count this reference.
|
||||
// We don't reference count the reference to the document
|
||||
// If the document goes away first, we'll be informed and we
|
||||
// can drop our reference.
|
||||
// If we go away first, we'll get rid of ourselves from the
|
||||
// document's observer list.
|
||||
mDocument = aDocument;
|
||||
mDocument->AddObserver(this);
|
||||
nsIContent *root;
|
||||
if (nsnull != mRootContent) {
|
||||
root = mRootContent;
|
||||
}
|
||||
else {
|
||||
root = mDocument->GetRootContent();
|
||||
}
|
||||
PopulateSelf(root);
|
||||
if (nsnull == mRootContent) {
|
||||
NS_RELEASE(root);
|
||||
if (nsnull != mDocument) {
|
||||
mDocument->AddObserver(this);
|
||||
}
|
||||
PopulateSelf();
|
||||
}
|
||||
|
||||
nsContentList::~nsContentList()
|
||||
|
@ -103,11 +97,8 @@ nsContentList::~nsContentList()
|
|||
NS_IF_RELEASE(mMatchAtom);
|
||||
}
|
||||
|
||||
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
|
||||
static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID);
|
||||
static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID);
|
||||
static NS_DEFINE_IID(kIDOMHTMLCollectionIID, NS_IDOMHTMLCOLLECTION_IID);
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
|
||||
nsresult nsContentList::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
|
@ -141,12 +132,194 @@ NS_IMPL_ADDREF(nsContentList)
|
|||
NS_IMPL_RELEASE(nsContentList)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::GetLength(PRUint32* aLength)
|
||||
{
|
||||
nsresult result = CheckDocumentExistence();
|
||||
if (NS_OK == result) {
|
||||
*aLength = mContent.Count();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
|
||||
{
|
||||
nsresult result = CheckDocumentExistence();
|
||||
if (NS_OK == result) {
|
||||
nsISupports *element = (nsISupports *)mContent.ElementAt(aIndex);
|
||||
|
||||
if (nsnull != element) {
|
||||
result = element->QueryInterface(kIDOMNodeIID, (void **)aReturn);
|
||||
}
|
||||
else {
|
||||
*aReturn = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
|
||||
{
|
||||
nsresult result = CheckDocumentExistence();
|
||||
|
||||
if (NS_OK == result) {
|
||||
PRInt32 i, count = mContent.Count();
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
nsIContent *content = (nsIContent *)mContent.ElementAt(i);
|
||||
if (nsnull != content) {
|
||||
nsAutoString name;
|
||||
// XXX Should it be an EqualsIgnoreCase?
|
||||
if (((content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::name, name) == NS_CONTENT_ATTR_HAS_VALUE) &&
|
||||
(aName.Equals(name))) ||
|
||||
((content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::id, name) == NS_CONTENT_ATTR_HAS_VALUE) &&
|
||||
(aName.Equals(name)))) {
|
||||
return content->QueryInterface(kIDOMNodeIID, (void **)aReturn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*aReturn = nsnull;
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
|
||||
{
|
||||
nsresult res = NS_OK;
|
||||
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
|
||||
|
||||
if (nsnull == mScriptObject) {
|
||||
nsIDOMScriptObjectFactory *factory;
|
||||
|
||||
res = nsGenericElement::GetScriptObjectFactory(&factory);
|
||||
if (NS_OK != res) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = factory->NewScriptHTMLCollection(aContext,
|
||||
(nsISupports*)(nsIDOMHTMLCollection*)this,
|
||||
global,
|
||||
(void**)&mScriptObject);
|
||||
NS_RELEASE(factory);
|
||||
}
|
||||
*aScriptObject = mScriptObject;
|
||||
|
||||
NS_RELEASE(global);
|
||||
return res;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::SetScriptObject(void *aScriptObject)
|
||||
{
|
||||
mScriptObject = aScriptObject;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::ContentAppended(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
PRInt32 aNewIndexInContainer)
|
||||
{
|
||||
PRInt32 i, count;
|
||||
aContainer->ChildCount(count);
|
||||
if ((count > 0) && IsDescendantOfRoot(aContainer)) {
|
||||
PRBool repopulate = PR_FALSE;
|
||||
for (i = aNewIndexInContainer; i <= count-1; i++) {
|
||||
nsIContent *content;
|
||||
aContainer->ChildAt(i, content);
|
||||
if (mMatchAll || MatchSelf(content)) {
|
||||
repopulate = PR_TRUE;
|
||||
}
|
||||
NS_RELEASE(content);
|
||||
}
|
||||
if (repopulate) {
|
||||
PopulateSelf();
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::ContentInserted(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (IsDescendantOfRoot(aContainer)) {
|
||||
if (mMatchAll || MatchSelf(aChild)) {
|
||||
PopulateSelf();
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::ContentReplaced(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aOldChild,
|
||||
nsIContent* aNewChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (IsDescendantOfRoot(aContainer)) {
|
||||
if (mMatchAll || MatchSelf(aOldChild) || MatchSelf(aNewChild)) {
|
||||
PopulateSelf();
|
||||
}
|
||||
}
|
||||
else if (ContainsRoot(aOldChild)) {
|
||||
DisconnectFromDocument();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::ContentRemoved(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (IsDescendantOfRoot(aContainer) && MatchSelf(aChild)) {
|
||||
PopulateSelf();
|
||||
}
|
||||
else if (ContainsRoot(aChild)) {
|
||||
DisconnectFromDocument();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::DocumentWillBeDestroyed(nsIDocument *aDocument)
|
||||
{
|
||||
if (nsnull != mDocument) {
|
||||
aDocument->RemoveObserver(this);
|
||||
mDocument = nsnull;
|
||||
}
|
||||
Reset();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// Returns whether the content element matches the
|
||||
// criterion
|
||||
nsresult
|
||||
nsContentList::Match(nsIContent *aContent, PRBool *aMatch)
|
||||
{
|
||||
if (nsnull != mMatchAtom) {
|
||||
nsIAtom *name = nsnull;
|
||||
aContent->GetTag(name);
|
||||
|
||||
// If we have to match all, only do those that have
|
||||
// a tagName i.e. only the elements.
|
||||
if (mMatchAll && (nsnull != name)) {
|
||||
*aMatch = PR_TRUE;
|
||||
}
|
||||
|
@ -170,7 +343,7 @@ nsContentList::Match(nsIContent *aContent, PRBool *aMatch)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsContentList::Add(nsIContent *aContent)
|
||||
{
|
||||
// Shouldn't hold a reference since we'll be
|
||||
|
@ -181,7 +354,7 @@ nsContentList::Add(nsIContent *aContent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsContentList::Remove(nsIContent *aContent)
|
||||
{
|
||||
mContent.RemoveElement(aContent);
|
||||
|
@ -189,7 +362,7 @@ nsContentList::Remove(nsIContent *aContent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsContentList::Reset()
|
||||
{
|
||||
mContent.Clear();
|
||||
|
@ -197,75 +370,28 @@ nsContentList::Reset()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::GetLength(PRUint32* aLength)
|
||||
// If we were created outside the context of a document and we
|
||||
// have root content, then check if our content has been added
|
||||
// to a document yet. If so, we'll become an observer of the document.
|
||||
nsresult
|
||||
nsContentList::CheckDocumentExistence()
|
||||
{
|
||||
*aLength = mContent.Count();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
|
||||
{
|
||||
nsISupports *element = (nsISupports *)mContent.ElementAt(aIndex);
|
||||
|
||||
if (nsnull != element) {
|
||||
return element->QueryInterface(kIDOMNodeIID, (void **)aReturn);
|
||||
}
|
||||
else {
|
||||
*aReturn = nsnull;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
|
||||
{
|
||||
PRInt32 i, count = mContent.Count();
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
nsIContent *content = (nsIContent *)mContent.ElementAt(i);
|
||||
if (nsnull != content) {
|
||||
nsAutoString name;
|
||||
// XXX Should it be an EqualsIgnoreCase?
|
||||
if (((content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::name, name) == NS_CONTENT_ATTR_HAS_VALUE) &&
|
||||
(aName.Equals(name))) ||
|
||||
((content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::id, name) == NS_CONTENT_ATTR_HAS_VALUE) &&
|
||||
(aName.Equals(name)))) {
|
||||
return content->QueryInterface(kIDOMNodeIID, (void **)aReturn);
|
||||
}
|
||||
nsresult result = NS_OK;
|
||||
if ((nsnull == mDocument) && (nsnull != mRootContent)) {
|
||||
result = mRootContent->GetDocument(mDocument);
|
||||
if (nsnull != mDocument) {
|
||||
mDocument->AddObserver(this);
|
||||
PopulateSelf();
|
||||
}
|
||||
}
|
||||
|
||||
*aReturn = nsnull;
|
||||
return NS_OK;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
|
||||
{
|
||||
nsresult res = NS_OK;
|
||||
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
|
||||
|
||||
if (nsnull == mScriptObject) {
|
||||
res = NS_NewScriptHTMLCollection(aContext, (nsISupports*)(nsIDOMHTMLCollection*)this, global, (void**)&mScriptObject);
|
||||
}
|
||||
*aScriptObject = mScriptObject;
|
||||
|
||||
NS_RELEASE(global);
|
||||
return res;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::SetScriptObject(void *aScriptObject)
|
||||
{
|
||||
mScriptObject = aScriptObject;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool nsContentList::MatchSelf(nsIContent *aContent)
|
||||
// Match recursively. See if anything in the subtree
|
||||
// matches the criterion.
|
||||
PRBool
|
||||
nsContentList::MatchSelf(nsIContent *aContent)
|
||||
{
|
||||
PRBool match;
|
||||
PRInt32 i, count;
|
||||
|
@ -289,104 +415,110 @@ PRBool nsContentList::MatchSelf(nsIContent *aContent)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
void nsContentList::PopulateSelf(nsIContent *aContent)
|
||||
// Add all elements in this subtree that match to
|
||||
// our list.
|
||||
void
|
||||
nsContentList::PopulateWith(nsIContent *aContent, PRBool aIncludeRoot)
|
||||
{
|
||||
PRBool match;
|
||||
PRInt32 i, count;
|
||||
|
||||
Match(aContent, &match);
|
||||
if (match) {
|
||||
Add(aContent);
|
||||
if (aIncludeRoot) {
|
||||
Match(aContent, &match);
|
||||
if (match) {
|
||||
Add(aContent);
|
||||
}
|
||||
}
|
||||
|
||||
aContent->ChildCount(count);
|
||||
for (i = 0; i < count; i++) {
|
||||
nsIContent *child;
|
||||
aContent->ChildAt(i, child);
|
||||
PopulateSelf(child);
|
||||
PopulateWith(child, PR_TRUE);
|
||||
NS_RELEASE(child);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::ContentAppended(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
PRInt32 aNewIndexInContainer)
|
||||
// Clear out our old list and build up a new one
|
||||
void
|
||||
nsContentList::PopulateSelf()
|
||||
{
|
||||
PRInt32 count;
|
||||
aContainer->ChildCount(count);
|
||||
if (count > 0) {
|
||||
nsIContent *content;
|
||||
aContainer->ChildAt(count-1, content);
|
||||
if (MatchSelf(content)) {
|
||||
Reset();
|
||||
nsIContent *root = aDocument->GetRootContent();
|
||||
PopulateSelf(root);
|
||||
NS_RELEASE(root);
|
||||
Reset();
|
||||
if (nsnull != mRootContent) {
|
||||
PopulateWith(mRootContent, PR_FALSE);
|
||||
}
|
||||
else if (nsnull != mDocument) {
|
||||
nsIContent *root;
|
||||
root = mDocument->GetRootContent();
|
||||
PopulateWith(root, PR_TRUE);
|
||||
NS_RELEASE(root);
|
||||
}
|
||||
}
|
||||
|
||||
// Is the specified element a descendant of the root? If there
|
||||
// is no root, then yes. Otherwise keep tracing up the tree from
|
||||
// the element till we find our root, or until we reach the
|
||||
// document root.
|
||||
PRBool
|
||||
nsContentList::IsDescendantOfRoot(nsIContent* aContainer)
|
||||
{
|
||||
if (nsnull == mRootContent) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
else if (mRootContent == aContainer) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
else if (nsnull == aContainer) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
else {
|
||||
nsIContent* parent;
|
||||
PRBool ret;
|
||||
|
||||
aContainer->GetParent(parent);
|
||||
ret = IsDescendantOfRoot(parent);
|
||||
NS_IF_RELEASE(parent);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// Does this subtree contain the root?
|
||||
PRBool
|
||||
nsContentList::ContainsRoot(nsIContent* aContent)
|
||||
{
|
||||
if (nsnull == mRootContent) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
else if (mRootContent == aContent) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
else {
|
||||
PRInt32 i, count;
|
||||
|
||||
aContent->ChildCount(count);
|
||||
for (i = 0; i < count; i++) {
|
||||
nsIContent *child;
|
||||
aContent->ChildAt(i, child);
|
||||
if (ContainsRoot(child)) {
|
||||
NS_RELEASE(child);
|
||||
return PR_TRUE;
|
||||
}
|
||||
NS_RELEASE(child);
|
||||
}
|
||||
NS_RELEASE(content);
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::ContentInserted(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (MatchSelf(aChild)) {
|
||||
Reset();
|
||||
nsIContent *root = aDocument->GetRootContent();
|
||||
PopulateSelf(root);
|
||||
NS_RELEASE(root);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::ContentReplaced(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aOldChild,
|
||||
nsIContent* aNewChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (MatchSelf(aOldChild) || MatchSelf(aNewChild)) {
|
||||
Reset();
|
||||
nsIContent *root = aDocument->GetRootContent();
|
||||
PopulateSelf(root);
|
||||
NS_RELEASE(root);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::ContentRemoved(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (MatchSelf(aChild)) {
|
||||
Reset();
|
||||
nsIContent *root = aDocument->GetRootContent();
|
||||
PopulateSelf(root);
|
||||
NS_RELEASE(root);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentList::DocumentWillBeDestroyed(nsIDocument *aDocument)
|
||||
// Our root content has been disconnected from the
|
||||
// document, so stop observing. The list then becomes
|
||||
// a snapshot rather than a dynamic list.
|
||||
void
|
||||
nsContentList::DisconnectFromDocument()
|
||||
{
|
||||
if (nsnull != mDocument) {
|
||||
aDocument->RemoveObserver(this);
|
||||
mDocument->RemoveObserver(this);
|
||||
mDocument = nsnull;
|
||||
}
|
||||
Reset();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -45,23 +45,18 @@ public:
|
|||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Match(nsIContent *aContent, PRBool *aMatch);
|
||||
|
||||
NS_IMETHOD Add(nsIContent *aContent);
|
||||
|
||||
NS_IMETHOD Remove(nsIContent *aContent);
|
||||
|
||||
NS_IMETHOD Reset();
|
||||
|
||||
// nsIDOMHTMLCollection
|
||||
NS_IMETHOD GetLength(PRUint32* aLength);
|
||||
|
||||
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn);
|
||||
|
||||
NS_IMETHOD NamedItem(const nsString& aName, nsIDOMNode** aReturn);
|
||||
|
||||
// nsIScriptObjectOwner
|
||||
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
|
||||
NS_IMETHOD SetScriptObject(void *aScriptObject);
|
||||
|
||||
// nsIDocumentObserver
|
||||
NS_IMETHOD BeginUpdate(nsIDocument *aDocument) { return NS_OK; }
|
||||
NS_IMETHOD EndUpdate(nsIDocument *aDocument) { return NS_OK; }
|
||||
NS_IMETHOD BeginLoad(nsIDocument *aDocument) { return NS_OK; }
|
||||
|
@ -111,9 +106,18 @@ public:
|
|||
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument);
|
||||
|
||||
protected:
|
||||
nsresult Match(nsIContent *aContent, PRBool *aMatch);
|
||||
nsresult Add(nsIContent *aContent);
|
||||
nsresult Remove(nsIContent *aContent);
|
||||
nsresult Reset();
|
||||
void Init(nsIDocument *aDocument);
|
||||
void PopulateSelf(nsIContent *aContent);
|
||||
void PopulateWith(nsIContent *aContent, PRBool aIncludeRoot);
|
||||
PRBool MatchSelf(nsIContent *aContent);
|
||||
void PopulateSelf();
|
||||
void DisconnectFromDocument();
|
||||
PRBool IsDescendantOfRoot(nsIContent* aContainer);
|
||||
PRBool ContainsRoot(nsIContent* aContent);
|
||||
nsresult CheckDocumentExistence();
|
||||
|
||||
static nsIAtom* gWildCardAtom;
|
||||
|
||||
|
|
|
@ -883,6 +883,12 @@ nsDocument::BeginLoad()
|
|||
for (i = 0; i < count; i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i];
|
||||
observer->BeginLoad(this);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -894,6 +900,12 @@ nsDocument::EndLoad()
|
|||
for (i = 0; i < count; i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i];
|
||||
observer->EndLoad(this);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -906,6 +918,12 @@ nsDocument::ContentChanged(nsIContent* aContent,
|
|||
for (PRInt32 i = 0; i < count; i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->ContentChanged(this, aContent, aSubContent);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -918,6 +936,12 @@ nsDocument::ContentAppended(nsIContent* aContainer,
|
|||
for (PRInt32 i = 0; i < count; i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->ContentAppended(this, aContainer, aNewIndexInContainer);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -931,6 +955,12 @@ nsDocument::ContentInserted(nsIContent* aContainer,
|
|||
for (PRInt32 i = 0; i < count; i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->ContentInserted(this, aContainer, aChild, aIndexInContainer);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -946,6 +976,12 @@ nsDocument::ContentReplaced(nsIContent* aContainer,
|
|||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->ContentReplaced(this, aContainer, aOldChild, aNewChild,
|
||||
aIndexInContainer);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -960,6 +996,12 @@ nsDocument::ContentRemoved(nsIContent* aContainer,
|
|||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->ContentRemoved(this, aContainer,
|
||||
aChild, aIndexInContainer);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -973,6 +1015,12 @@ nsDocument::AttributeChanged(nsIContent* aChild,
|
|||
for (PRInt32 i = 0; i < count; i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->AttributeChanged(this, aChild, aAttribute, aHint);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -986,6 +1034,12 @@ nsDocument::StyleRuleChanged(nsIStyleSheet* aStyleSheet, nsIStyleRule* aStyleRul
|
|||
for (PRInt32 i = 0; i < count; i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->StyleRuleChanged(this, aStyleSheet, aStyleRule, aHint);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -997,6 +1051,12 @@ nsDocument::StyleRuleAdded(nsIStyleSheet* aStyleSheet, nsIStyleRule* aStyleRule)
|
|||
for (PRInt32 i = 0; i < count; i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->StyleRuleAdded(this, aStyleSheet, aStyleRule);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1008,6 +1068,12 @@ nsDocument::StyleRuleRemoved(nsIStyleSheet* aStyleSheet, nsIStyleRule* aStyleRul
|
|||
for (PRInt32 i = 0; i < count; i++) {
|
||||
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
||||
observer->StyleRuleRemoved(this, aStyleSheet, aStyleRule);
|
||||
// Make sure that the observer didn't remove itself during the
|
||||
// notification. If it did, update our index and count.
|
||||
if (observer != (nsIDocumentObserver*)mObservers[i]) {
|
||||
i--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "nsIDOMCSSStyleDeclaration.h"
|
||||
#include "nsDOMCSSDeclaration.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsContentList.h"
|
||||
#include "prprf.h"
|
||||
#include "prmem.h"
|
||||
|
||||
|
@ -119,7 +120,19 @@ nsChildContentList::GetScriptObject(nsIScriptContext *aContext, void** aScriptOb
|
|||
{
|
||||
nsresult res = NS_OK;
|
||||
if (nsnull == mScriptObject) {
|
||||
res = NS_NewScriptNodeList(aContext, (nsISupports *)(nsIDOMNodeList *)this, mContent, (void**)&mScriptObject);
|
||||
nsIDOMScriptObjectFactory *factory;
|
||||
|
||||
res = nsGenericElement::GetScriptObjectFactory(&factory);
|
||||
if (NS_OK != res) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = factory->NewScriptNodeList(aContext,
|
||||
(nsISupports *)(nsIDOMNodeList *)this,
|
||||
mContent,
|
||||
(void**)&mScriptObject);
|
||||
|
||||
NS_RELEASE(factory);
|
||||
}
|
||||
*aScriptObject = mScriptObject;
|
||||
return res;
|
||||
|
@ -519,7 +532,26 @@ nsresult
|
|||
nsGenericElement::GetElementsByTagName(const nsString& aTagname,
|
||||
nsIDOMNodeList** aReturn)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;/* XXX */
|
||||
nsIAtom* nameAtom;
|
||||
PRInt32 nameSpaceId;
|
||||
nsresult result = NS_OK;
|
||||
|
||||
result = mContent->ParseAttributeString(aTagname, nameAtom,
|
||||
nameSpaceId);
|
||||
if (NS_OK != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
nsContentList* list = new nsContentList(mDocument,
|
||||
nameAtom,
|
||||
nameSpaceId,
|
||||
mContent);
|
||||
NS_IF_RELEASE(nameAtom);
|
||||
if (nsnull == list) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return list->QueryInterface(kIDOMNodeListIID, (void **)aReturn);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -152,10 +152,8 @@ nsHTMLDocument::~nsHTMLDocument()
|
|||
nsIDOMHTMLMapElement* map = (nsIDOMHTMLMapElement*)mImageMaps.ElementAt(i);
|
||||
NS_RELEASE(map);
|
||||
}
|
||||
if (mForms) {
|
||||
mForms->Reset();
|
||||
NS_RELEASE(mForms);
|
||||
}
|
||||
NS_IF_RELEASE(mForms);
|
||||
|
||||
// XXX don't bother doing this until the dll is unloaded???
|
||||
// nsHTMLAtoms::ReleaseAtoms();
|
||||
|
||||
|
@ -228,10 +226,7 @@ nsHTMLDocument::Reset(nsIURL *aURL)
|
|||
nsIDOMHTMLMapElement* map = (nsIDOMHTMLMapElement*)mImageMaps.ElementAt(i);
|
||||
NS_RELEASE(map);
|
||||
}
|
||||
if (mForms) {
|
||||
mForms->Reset();
|
||||
NS_RELEASE(mForms);
|
||||
}
|
||||
NS_IF_RELEASE(mForms);
|
||||
|
||||
if (nsnull != mAttrStyleSheet) {
|
||||
mAttrStyleSheet->SetOwningDocument(nsnull);
|
||||
|
@ -2284,6 +2279,8 @@ nsHTMLDocument::GetBodyContent()
|
|||
NS_IMETHODIMP
|
||||
nsHTMLDocument::AddForm(nsIDOMHTMLFormElement *aForm)
|
||||
{
|
||||
#if 0
|
||||
// Not necessary anymore since forms are real content now
|
||||
NS_PRECONDITION(nsnull != aForm, "null ptr");
|
||||
if (nsnull == aForm) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
@ -2304,6 +2301,8 @@ nsHTMLDocument::AddForm(nsIDOMHTMLFormElement *aForm)
|
|||
NS_RELEASE(iContent);
|
||||
}
|
||||
return result;
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
Загрузка…
Ссылка в новой задаче