Introduced nsContentLists. Added a DocumentWillBeDestroyed method to nsIDocumentObserver. Added a document parameter to all DocumentObserver notifications. Added the nsIDOMHTMLDocument interface to HTMLDocument. Implemented document.images, etc and getElementsByTagName.

This commit is contained in:
vidur%netscape.com 1998-07-22 23:32:19 +00:00
Родитель 2618db2426
Коммит ec8c40eeed
21 изменённых файлов: 1889 добавлений и 197 удалений

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

@ -23,6 +23,7 @@ class nsIContent;
class nsIPresShell; class nsIPresShell;
class nsIStyleSheet; class nsIStyleSheet;
class nsString; class nsString;
class nsIDocument;
#define NS_IDOCUMENT_OBSERVER_IID \ #define NS_IDOCUMENT_OBSERVER_IID \
{ 0xb3f92460, 0x944c, 0x11d1, {0x93, 0x23, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}} { 0xb3f92460, 0x944c, 0x11d1, {0x93, 0x23, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
@ -34,37 +35,37 @@ public:
* Notify that a content model update is beginning. This call can be * Notify that a content model update is beginning. This call can be
* nested. * nested.
*/ */
NS_IMETHOD BeginUpdate() = 0; NS_IMETHOD BeginUpdate(nsIDocument *aDocument) = 0;
/** /**
* Notify that a content model update is finished. This call can be * Notify that a content model update is finished. This call can be
* nested. * nested.
*/ */
NS_IMETHOD EndUpdate() = 0; NS_IMETHOD EndUpdate(nsIDocument *aDocument) = 0;
/** /**
* Notify the observer that a document load is beginning. * Notify the observer that a document load is beginning.
*/ */
NS_IMETHOD BeginLoad() = 0; NS_IMETHOD BeginLoad(nsIDocument *aDocument) = 0;
/** /**
* Notify the observer that a document load has finished. Note that * Notify the observer that a document load has finished. Note that
* the associated reflow of the document will be done <b>before</b> * the associated reflow of the document will be done <b>before</b>
* EndLoad is invoked, not after. * EndLoad is invoked, not after.
*/ */
NS_IMETHOD EndLoad() = 0; NS_IMETHOD EndLoad(nsIDocument *aDocument) = 0;
/** /**
* Notify the observer that the document is being reflowed in * Notify the observer that the document is being reflowed in
* the given presentation shell. * the given presentation shell.
*/ */
NS_IMETHOD BeginReflow(nsIPresShell* aShell) = 0; NS_IMETHOD BeginReflow(nsIDocument *aDocument, nsIPresShell* aShell) = 0;
/** /**
* Notify the observer that the document is done being reflowed in * Notify the observer that the document is done being reflowed in
* the given presentation shell. * the given presentation shell.
*/ */
NS_IMETHOD EndReflow(nsIPresShell* aShell) = 0; NS_IMETHOD EndReflow(nsIDocument *aDocument, nsIPresShell* aShell) = 0;
/** /**
* Notification that the content model has changed. This method is * Notification that the content model has changed. This method is
@ -78,11 +79,13 @@ public:
* added/removed from the document (the other notifications are used * added/removed from the document (the other notifications are used
* for that). * for that).
* *
* @param aDocument The document being observed
* @param aContent the piece of content that changed * @param aContent the piece of content that changed
* @param aSubContent subrange information about the piece of content * @param aSubContent subrange information about the piece of content
* that changed * that changed
*/ */
NS_IMETHOD ContentChanged(nsIContent* aContent, NS_IMETHOD ContentChanged(nsIDocument *aDocument,
nsIContent* aContent,
nsISupports* aSubContent) = 0; nsISupports* aSubContent) = 0;
/** /**
@ -93,9 +96,11 @@ public:
* method directly). The notification is passed on to all of the * method directly). The notification is passed on to all of the
* document observers. * document observers.
* *
* @param aDocument The document being observed
* @param aContainer the container that had a new child appended * @param aContainer the container that had a new child appended
*/ */
NS_IMETHOD ContentAppended(nsIContent* aContainer) = 0; NS_IMETHOD ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer) = 0;
/** /**
* Notification that content has been inserted. This method is called * Notification that content has been inserted. This method is called
@ -104,11 +109,13 @@ public:
* need to invoke this method directly). The notification is passed on * need to invoke this method directly). The notification is passed on
* to all of the document observers. * to all of the document observers.
* *
* @param aDocument The document being observed
* @param aContainer the container that now contains aChild * @param aContainer the container that now contains aChild
* @param aChild the child that was inserted * @param aChild the child that was inserted
* @param aIndexInContainer the index of the child in the container * @param aIndexInContainer the index of the child in the container
*/ */
NS_IMETHOD ContentInserted(nsIContent* aContainer, NS_IMETHOD ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild, nsIContent* aChild,
PRInt32 aIndexInContainer) = 0; PRInt32 aIndexInContainer) = 0;
@ -119,13 +126,15 @@ public:
* invoke this method directly). The notification is passed on to all * invoke this method directly). The notification is passed on to all
* of the document observers. * of the document observers.
* *
* @param aDocument The document being observed
* @param aContainer the container that now contains aChild * @param aContainer the container that now contains aChild
* @param aOldChild the child that was replaced * @param aOldChild the child that was replaced
* @param aNewChild the child that replaced aOldChild * @param aNewChild the child that replaced aOldChild
* @param aIndexInContainer the index of the old and new child in the * @param aIndexInContainer the index of the old and new child in the
* container * container
*/ */
NS_IMETHOD ContentReplaced(nsIContent* aContainer, NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild, nsIContent* aOldChild,
nsIContent* aNewChild, nsIContent* aNewChild,
PRInt32 aIndexInContainer) = 0; PRInt32 aIndexInContainer) = 0;
@ -137,11 +146,13 @@ public:
* there is normally no need to invoke this method directly). The * there is normally no need to invoke this method directly). The
* notification is passed on to all of the document observers. * notification is passed on to all of the document observers.
* *
* @param aDocument The document being observed
* @param aContainer the container that contains aChild * @param aContainer the container that contains aChild
* @param aChild the child that will be removed * @param aChild the child that will be removed
* @param aIndexInContainer the index of the child in the container * @param aIndexInContainer the index of the child in the container
*/ */
NS_IMETHOD ContentWillBeRemoved(nsIContent* aContainer, NS_IMETHOD ContentWillBeRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild, nsIContent* aChild,
PRInt32 aIndexInContainer) = 0; PRInt32 aIndexInContainer) = 0;
@ -152,12 +163,14 @@ public:
* invoke this method directly). The notification is passed on to all * invoke this method directly). The notification is passed on to all
* of the document observers. * of the document observers.
* *
* @param aDocument The document being observed
* @param aContainer the container that had a child removed * @param aContainer the container that had a child removed
* @param aChild the child that was just removed * @param aChild the child that was just removed
* @param aIndexInContainer the index of the child in the container * @param aIndexInContainer the index of the child in the container
* before it was removed * before it was removed
*/ */
NS_IMETHOD ContentHasBeenRemoved(nsIContent* aContainer, NS_IMETHOD ContentHasBeenRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild, nsIContent* aChild,
PRInt32 aIndexInContainer) = 0; PRInt32 aIndexInContainer) = 0;
@ -167,9 +180,20 @@ public:
* to the document. The notification is passed on to all of the * to the document. The notification is passed on to all of the
* document observers. * document observers.
* *
* @param aDocument The document being observed
* @param aStyleSheet the StyleSheet that has been added * @param aStyleSheet the StyleSheet that has been added
*/ */
NS_IMETHOD StyleSheetAdded(nsIStyleSheet* aStyleSheet) = 0; NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet) = 0;
/**
* The document is in the process of being destroyed.
* This method is called automatically during document
* destruction.
*
* @param aDocument The document being observed
*/
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument) = 0;
}; };
#endif /* nsIDocumentObserver_h___ */ #endif /* nsIDocumentObserver_h___ */

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

@ -0,0 +1,342 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsContentList.h"
#include "nsIContent.h"
#include "nsIDOMNode.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDocument.h"
nsContentList::nsContentList(nsIDocument *aDocument,
const nsString& aMatchTag)
{
mMatchTag = new nsString(aMatchTag);
mFunc = nsnull;
Init(aDocument);
}
nsContentList::nsContentList(nsIDocument *aDocument,
nsContentListMatchFunc aFunc)
{
mFunc = aFunc;
mMatchTag = nsnull;
Init(aDocument);
}
void nsContentList::Init(nsIDocument *aDocument)
{
NS_INIT_REFCNT();
mScriptObject = nsnull;
// XXX We don't reference count this reference.
// 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 = mDocument->GetRootContent();
PopulateSelf(root);
NS_RELEASE(root);
}
nsContentList::~nsContentList()
{
if (nsnull != mDocument) {
mDocument->RemoveObserver(this);
}
if (nsnull != mMatchTag) {
delete mMatchTag;
}
}
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)
{
if (nsnull == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIDOMNodeListIID)) {
*aInstancePtr = (void*)(nsIDOMNodeList*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kIDOMHTMLCollectionIID)) {
*aInstancePtr = (void*)(nsIDOMHTMLCollection*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
*aInstancePtr = (void*)(nsIScriptObjectOwner*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)(nsIDOMNodeList*)this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsContentList)
NS_IMPL_RELEASE(nsContentList)
NS_IMETHODIMP
nsContentList::Match(nsIContent *aContent, PRBool *aMatch)
{
if (nsnull != mMatchTag) {
nsIAtom *name = aContent->GetTag();
if ((nsnull !=name) && mMatchTag->EqualsIgnoreCase(name)) {
*aMatch = PR_TRUE;
}
else {
*aMatch = PR_FALSE;
}
NS_IF_RELEASE(name);
}
else if (nsnull != mFunc) {
*aMatch = (*mFunc)(aContent);
}
else {
*aMatch = PR_FALSE;
}
return NS_OK;
}
NS_IMETHODIMP
nsContentList::Add(nsIContent *aContent)
{
// XXX Should hold a reference ??
mContent.AppendElement(aContent);
return NS_OK;
}
NS_IMETHODIMP
nsContentList::Remove(nsIContent *aContent)
{
// XXX Should drop a reference ??
mContent.RemoveElement(aContent);
return NS_OK;
}
NS_IMETHODIMP
nsContentList::Reset()
{
// XXX Should drop references ??
mContent.Clear();
return NS_OK;
}
NS_IMETHODIMP
nsContentList::GetLength(PRUint32* aLength)
{
*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("name", name) == eContentAttr_HasValue) &&
(aName.Equals(name))) {
return content->QueryInterface(kIDOMNodeIID, (void **)aReturn);
}
}
}
*aReturn = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsContentList::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
if (nsnull == mScriptObject) {
res = NS_NewScriptHTMLCollection(aContext, this, global, (void**)&mScriptObject);
}
*aScriptObject = mScriptObject;
NS_RELEASE(global);
return res;
}
NS_IMETHODIMP
nsContentList::ResetScriptObject()
{
mScriptObject = nsnull;
return NS_OK;
}
PRBool nsContentList::MatchSelf(nsIContent *aContent)
{
PRBool match;
PRInt32 i, count;
Match(aContent, &match);
if (match) {
return PR_TRUE;
}
count = aContent->ChildCount();
for (i = 0; i < count; i++) {
nsIContent *child = aContent->ChildAt(i);
if (MatchSelf(child)) {
NS_RELEASE(child);
return PR_TRUE;
}
NS_RELEASE(child);
}
return PR_FALSE;
}
void nsContentList::PopulateSelf(nsIContent *aContent)
{
PRBool match;
PRInt32 i, count;
Match(aContent, &match);
if (match) {
Add(aContent);
}
count = aContent->ChildCount();
for (i = 0; i < count; i++) {
nsIContent *child = aContent->ChildAt(i);
PopulateSelf(child);
NS_RELEASE(child);
}
}
NS_IMETHODIMP
nsContentList::ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer)
{
if (aContainer->ChildCount() > 0) {
nsIContent *content = aContainer->ChildAt(aContainer->ChildCount()-1);
if (MatchSelf(content)) {
Reset();
nsIContent *root = aDocument->GetRootContent();
PopulateSelf(root);
NS_RELEASE(root);
}
NS_RELEASE(content);
}
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::ContentHasBeenRemoved(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)
{
if (nsnull != mDocument) {
aDocument->RemoveObserver(this);
mDocument = nsnull;
}
Reset();
return NS_OK;
}

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

@ -0,0 +1,104 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsContentList_h___
#define nsContentList_h___
#include "nsISupports.h"
#include "nsVoidArray.h"
#include "nsString.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDOMNodeList.h"
#include "nsIDocumentObserver.h"
#include "nsIScriptObjectOwner.h"
typedef PRBool (*nsContentListMatchFunc)(nsIContent *aContent);
class nsIDocument;
class nsContentList : public nsIDOMNodeList, public nsIDOMHTMLCollection, public nsIScriptObjectOwner, public nsIDocumentObserver {
public:
nsContentList(nsIDocument *aDocument, const nsString& aMatchTag);
nsContentList(nsIDocument *aDocument, nsContentListMatchFunc aFunc);
virtual ~nsContentList();
NS_DECL_ISUPPORTS
NS_IMETHOD Match(nsIContent *aContent, PRBool *aMatch);
NS_IMETHOD Add(nsIContent *aContent);
NS_IMETHOD Remove(nsIContent *aContent);
NS_IMETHOD Reset();
NS_IMETHOD GetLength(PRUint32* aLength);
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn);
NS_IMETHOD NamedItem(const nsString& aName, nsIDOMNode** aReturn);
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD ResetScriptObject();
NS_IMETHOD BeginUpdate(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD EndUpdate(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD BeginLoad(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD EndLoad(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD BeginReflow(nsIDocument *aDocument,
nsIPresShell* aShell) { return NS_OK; }
NS_IMETHOD EndReflow(nsIDocument *aDocument,
nsIPresShell* aShell) { return NS_OK; }
NS_IMETHOD ContentChanged(nsIDocument *aDocument,
nsIContent* aContent,
nsISupports* aSubContent) { return NS_OK; }
NS_IMETHOD ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer);
NS_IMETHOD ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentWillBeRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer) { return NS_OK; }
NS_IMETHOD ContentHasBeenRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet) { return NS_OK; }
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument);
protected:
void Init(nsIDocument *aDocument);
void PopulateSelf(nsIContent *aContent);
PRBool MatchSelf(nsIContent *aContent);
nsString *mMatchTag;
nsContentListMatchFunc mFunc;
nsVoidArray mContent;
void *mScriptObject;
nsIDocument *mDocument;
};
#endif // nsContentList_h___

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

@ -30,7 +30,7 @@
#include "nsIScriptGlobalObject.h" #include "nsIScriptGlobalObject.h"
#include "nsIScriptContextOwner.h" #include "nsIScriptContextOwner.h"
#include "nsIParser.h" #include "nsIParser.h"
#include "nsContentList.h"
#include "nsCSSPropIDs.h" #include "nsCSSPropIDs.h"
#include "nsCSSProps.h" #include "nsCSSProps.h"
@ -143,6 +143,7 @@ nsDocument::nsDocument()
mScriptContextOwner = nsnull; mScriptContextOwner = nsnull;
mListenerManager = nsnull; mListenerManager = nsnull;
mParser = nsnull; mParser = nsnull;
mInDestructor = PR_FALSE;
if (NS_OK != NS_NewSelection(&mSelection)) { if (NS_OK != NS_NewSelection(&mSelection)) {
printf("*************** Error: nsDocument::nsDocument - Creation of Selection failed!\n"); printf("*************** Error: nsDocument::nsDocument - Creation of Selection failed!\n");
@ -153,6 +154,18 @@ nsDocument::nsDocument()
nsDocument::~nsDocument() nsDocument::~nsDocument()
{ {
// XXX Inform any remaining observers that we are going away.
// Note that this currently contradicts the rule that all
// observers must hold on to live references to the document.
// This notification will occur only after the reference has
// been dropped.
mInDestructor = PR_TRUE;
PRInt32 index, count = mObservers.Count();
for (index = 0; index < count; index++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(index);
observer->DocumentWillBeDestroyed(this);
}
if (nsnull != mDocumentTitle) { if (nsnull != mDocumentTitle) {
delete mDocumentTitle; delete mDocumentTitle;
mDocumentTitle = nsnull; mDocumentTitle = nsnull;
@ -162,7 +175,7 @@ nsDocument::~nsDocument()
mParentDocument = nsnull; mParentDocument = nsnull;
// Delete references to sub-documents // Delete references to sub-documents
PRInt32 index = mSubDocuments.Count(); index = mSubDocuments.Count();
while (--index >= 0) { while (--index >= 0) {
nsIDocument* subdoc = (nsIDocument*) mSubDocuments.ElementAt(index); nsIDocument* subdoc = (nsIDocument*) mSubDocuments.ElementAt(index);
NS_RELEASE(subdoc); NS_RELEASE(subdoc);
@ -399,7 +412,7 @@ void nsDocument::AddStyleSheet(nsIStyleSheet* aSheet)
count = mObservers.Count(); count = mObservers.Count();
for (index = 0; index < count; index++) { for (index = 0; index < count; index++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(index); nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(index);
observer->StyleSheetAdded(aSheet); observer->StyleSheetAdded(this, aSheet);
} }
} }
@ -453,7 +466,14 @@ void nsDocument::AddObserver(nsIDocumentObserver* aObserver)
PRBool nsDocument::RemoveObserver(nsIDocumentObserver* aObserver) PRBool nsDocument::RemoveObserver(nsIDocumentObserver* aObserver)
{ {
return mObservers.RemoveElement(aObserver); // If we're in the process of destroying the document (and we're
// informing the observers of the destruction), don't remove the
// observers from the list. This is not a big deal, since we
// don't hold a live reference to the observers.
if (!mInDestructor)
return mObservers.RemoveElement(aObserver);
else
return (mObservers.IndexOf(aObserver) != -1);
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -462,7 +482,7 @@ nsDocument::BeginLoad()
PRInt32 i, count = mObservers.Count(); PRInt32 i, count = mObservers.Count();
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i]; nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i];
observer->BeginLoad(); observer->BeginLoad(this);
} }
return NS_OK; return NS_OK;
} }
@ -473,7 +493,7 @@ nsDocument::EndLoad()
PRInt32 i, count = mObservers.Count(); PRInt32 i, count = mObservers.Count();
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i]; nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i];
observer->EndLoad(); observer->EndLoad(this);
} }
return NS_OK; return NS_OK;
} }
@ -484,7 +504,7 @@ void nsDocument::ContentChanged(nsIContent* aContent,
PRInt32 count = mObservers.Count(); PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) { for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentChanged(aContent, aSubContent); observer->ContentChanged(this, aContent, aSubContent);
} }
} }
@ -493,7 +513,7 @@ void nsDocument::ContentAppended(nsIContent* aContainer)
PRInt32 count = mObservers.Count(); PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) { for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentAppended(aContainer); observer->ContentAppended(this, aContainer);
} }
} }
@ -504,7 +524,7 @@ void nsDocument::ContentInserted(nsIContent* aContainer,
PRInt32 count = mObservers.Count(); PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) { for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentInserted(aContainer, aChild, aIndexInContainer); observer->ContentInserted(this, aContainer, aChild, aIndexInContainer);
} }
} }
@ -516,7 +536,7 @@ void nsDocument::ContentReplaced(nsIContent* aContainer,
PRInt32 count = mObservers.Count(); PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) { for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentReplaced(aContainer, aOldChild, aNewChild, observer->ContentReplaced(this, aContainer, aOldChild, aNewChild,
aIndexInContainer); aIndexInContainer);
} }
} }
@ -528,7 +548,8 @@ void nsDocument::ContentWillBeRemoved(nsIContent* aContainer,
PRInt32 count = mObservers.Count(); PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) { for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentWillBeRemoved(aContainer, aChild, aIndexInContainer); observer->ContentWillBeRemoved(this, aContainer,
aChild, aIndexInContainer);
} }
} }
@ -539,7 +560,8 @@ void nsDocument::ContentHasBeenRemoved(nsIContent* aContainer,
PRInt32 count = mObservers.Count(); PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) { for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentHasBeenRemoved(aContainer, aChild, aIndexInContainer); observer->ContentHasBeenRemoved(this, aContainer,
aChild, aIndexInContainer);
} }
} }
@ -679,8 +701,14 @@ NS_IMETHODIMP
nsDocument::GetElementsByTagName(const nsString& aTagname, nsDocument::GetElementsByTagName(const nsString& aTagname,
nsIDOMNodeList** aReturn) nsIDOMNodeList** aReturn)
{ {
//XXX TBI nsContentList* list = new nsContentList(this, aTagname);
return NS_ERROR_NOT_IMPLEMENTED; if (nsnull == list) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aReturn = (nsIDOMNodeList *)list;
NS_ADDREF(list);
return NS_OK;
} }
// //
@ -993,7 +1021,6 @@ void nsDocument::GetSelectionText(nsString & aText) {
} }
void nsDocument::BeginConvertToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode) void nsDocument::BeginConvertToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode)
{ {
nsIContent* content = nsnull; nsIContent* content = nsnull;

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

@ -218,7 +218,7 @@ public:
NS_IMETHOD CreateTextNode(const nsString& aData, nsIDOMText** aReturn); NS_IMETHOD CreateTextNode(const nsString& aData, nsIDOMText** aReturn);
NS_IMETHOD GetElementsByTagName(const nsString& aTagname, nsIDOMNodeList** aReturn); NS_IMETHOD GetElementsByTagName(const nsString& aTagname, nsIDOMNodeList** aReturn);
// nsIDOMNode // nsIDOMNode interface
NS_IMETHOD GetNodeName(nsString& aNodeName); NS_IMETHOD GetNodeName(nsString& aNodeName);
NS_IMETHOD GetNodeValue(nsString& aNodeValue); NS_IMETHOD GetNodeValue(nsString& aNodeValue);
NS_IMETHOD SetNodeValue(const nsString& aNodeValue); NS_IMETHOD SetNodeValue(const nsString& aNodeValue);
@ -284,6 +284,7 @@ protected:
nsIScriptContextOwner *mScriptContextOwner; nsIScriptContextOwner *mScriptContextOwner;
nsIParser *mParser; nsIParser *mParser;
nsIEventListenerManager* mListenerManager; nsIEventListenerManager* mListenerManager;
PRBool mInDestructor;
}; };
#endif /* nsDocument_h___ */ #endif /* nsDocument_h___ */

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

@ -37,7 +37,8 @@
#include "nsIWebShell.h" #include "nsIWebShell.h"
#include "nsIDocumentLoader.h" #include "nsIDocumentLoader.h"
#include "CNavDTD.h" #include "CNavDTD.h"
#include "nsIScriptGlobalObject.h"
#include "nsContentList.h"
//#define rickgdebug 1 //#define rickgdebug 1
#ifdef rickgdebug #ifdef rickgdebug
@ -49,6 +50,7 @@ static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID);
static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID); static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID); static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLDocumentIID, NS_IDOMHTMLDOCUMENT_IID);
NS_LAYOUT nsresult NS_LAYOUT nsresult
NS_NewHTMLDocument(nsIDocument** aInstancePtrResult) NS_NewHTMLDocument(nsIDocument** aInstancePtrResult)
@ -61,11 +63,21 @@ nsHTMLDocument::nsHTMLDocument()
: nsMarkupDocument(), : nsMarkupDocument(),
mAttrStyleSheet(nsnull) mAttrStyleSheet(nsnull)
{ {
mImages = nsnull;
mApplets = nsnull;
mEmbeds = nsnull;
mLinks = nsnull;
mAnchors = nsnull;
nsHTMLAtoms::AddrefAtoms(); nsHTMLAtoms::AddrefAtoms();
} }
nsHTMLDocument::~nsHTMLDocument() nsHTMLDocument::~nsHTMLDocument()
{ {
NS_IF_RELEASE(mImages);
NS_IF_RELEASE(mApplets);
NS_IF_RELEASE(mEmbeds);
NS_IF_RELEASE(mLinks);
NS_IF_RELEASE(mAnchors);
NS_IF_RELEASE(mAttrStyleSheet); NS_IF_RELEASE(mAttrStyleSheet);
nsHTMLAtoms::ReleaseAtoms(); nsHTMLAtoms::ReleaseAtoms();
} }
@ -79,12 +91,26 @@ NS_IMETHODIMP nsHTMLDocument::QueryInterface(REFNSIID aIID,
} }
if (aIID.Equals(kIHTMLDocumentIID)) { if (aIID.Equals(kIHTMLDocumentIID)) {
AddRef(); AddRef();
*aInstancePtr = (void**) &mIHTMLDocument; *aInstancePtr = (void**) (nsIHTMLDocument *)this;
return NS_OK;
}
if (aIID.Equals(kIDOMHTMLDocumentIID)) {
AddRef();
*aInstancePtr = (void**) (nsIDOMHTMLDocument *)this;
return NS_OK; return NS_OK;
} }
return nsDocument::QueryInterface(aIID, aInstancePtr); return nsDocument::QueryInterface(aIID, aInstancePtr);
} }
nsrefcnt nsHTMLDocument::AddRef()
{
return nsDocument::AddRef();
}
nsrefcnt nsHTMLDocument::Release()
{
return nsDocument::Release();
}
NS_IMETHODIMP NS_IMETHODIMP
nsHTMLDocument::StartDocumentLoad(nsIURL *aURL, nsHTMLDocument::StartDocumentLoad(nsIURL *aURL,
@ -244,6 +270,9 @@ void nsHTMLDocument::AddStyleSheetToSet(nsIStyleSheet* aSheet, nsIStyleSet* aSet
} }
} }
//
// nsIDOMDocument interface implementation
//
NS_IMETHODIMP NS_IMETHODIMP
nsHTMLDocument::CreateElement(const nsString& aTagName, nsHTMLDocument::CreateElement(const nsString& aTagName,
nsIDOMNamedNodeMap* aAttributes, nsIDOMNamedNodeMap* aAttributes,
@ -271,42 +300,270 @@ nsHTMLDocument::CreateTextNode(const nsString& aData, nsIDOMText** aTextNode)
return rv; return rv;
} }
//---------------------------------------------------------------------- NS_IMETHODIMP
nsHTMLDocument::GetDocumentType(nsIDOMDocumentType** aDocumentType)
// Aggregation class to give nsHTMLDocument the nsIHTMLDocument interface
#define GET_OUTER() \
((nsHTMLDocument*) ((char*)this - nsHTMLDocument::GetOuterOffset()))
nsHTMLDocument::AggIHTMLDocument::AggIHTMLDocument() {
NS_INIT_REFCNT();
}
nsHTMLDocument::AggIHTMLDocument::~AggIHTMLDocument() { }
NS_IMETHODIMP_(nsrefcnt) nsHTMLDocument::AggIHTMLDocument::AddRef() {
return GET_OUTER()->AddRef();
}
NS_IMETHODIMP_(nsrefcnt) nsHTMLDocument::AggIHTMLDocument::Release() {
return GET_OUTER()->Release();
}
NS_IMETHODIMP nsHTMLDocument::AggIHTMLDocument::QueryInterface(REFNSIID aIID,
void** aInstancePtr)
{ {
return GET_OUTER()->QueryInterface(aIID, aInstancePtr); // There's no document type for a HTML document
*aDocumentType = nsnull;
return NS_OK;
} }
NS_IMETHODIMP nsHTMLDocument::AggIHTMLDocument::SetTitle(const nsString& aTitle) { //
return GET_OUTER()->SetTitle(aTitle); // nsIDOMHTMLDocument interface implementation
//
NS_IMETHODIMP
nsHTMLDocument::GetTitle(nsString& aTitle)
{
if (nsnull != mDocumentTitle) {
aTitle.SetString(*mDocumentTitle);
}
return NS_OK;
} }
NS_IMETHODIMP nsHTMLDocument::AggIHTMLDocument::AddImageMap(nsIImageMap* aMap) { NS_IMETHODIMP
return GET_OUTER()->AddImageMap(aMap); nsHTMLDocument::GetReferrer(nsString& aReferrer)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
} }
NS_IMETHODIMP nsHTMLDocument::AggIHTMLDocument::GetImageMap(const nsString& aMapName, NS_IMETHODIMP
nsIImageMap** aResult) { nsHTMLDocument::GetFileSize(nsString& aFileSize)
return GET_OUTER()->GetImageMap(aMapName, aResult); {
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
} }
NS_IMETHODIMP
nsHTMLDocument::GetFileCreatedDate(nsString& aFileCreatedDate)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::GetFileModifiedDate(nsString& aFileModifiedDate)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::GetFileUpdatedDate(nsString& aFileUpdatedDate)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::GetDomain(nsString& aDomain)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::GetURL(nsString& aURL)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::GetBody(nsIDOMHTMLElement** aBody)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::SetBody(nsIDOMHTMLElement* aBody)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::GetImages(nsIDOMHTMLCollection** aImages)
{
if (nsnull == mImages) {
mImages = new nsContentList(this, "IMG");
if (nsnull == mImages) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(mImages);
}
*aImages = (nsIDOMHTMLCollection *)mImages;
NS_ADDREF(mImages);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLDocument::GetApplets(nsIDOMHTMLCollection** aApplets)
{
if (nsnull == mApplets) {
mApplets = new nsContentList(this, "APPLET");
if (nsnull == mApplets) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(mApplets);
}
*aApplets = (nsIDOMHTMLCollection *)mImages;
NS_ADDREF(mImages);
return NS_OK;
}
PRBool
nsHTMLDocument::MatchLinks(nsIContent *aContent)
{
nsIAtom *name = aContent->GetTag();
static nsAutoString area("AREA"), anchor("A");
nsAutoString attr;
PRBool result = PR_FALSE;
if ((nsnull != name) &&
(area.EqualsIgnoreCase(name) || anchor.EqualsIgnoreCase(name)) &&
(eContentAttr_HasValue == aContent->GetAttribute("HREF", attr))) {
result = PR_TRUE;
}
NS_IF_RELEASE(name);
return result;
}
NS_IMETHODIMP
nsHTMLDocument::GetLinks(nsIDOMHTMLCollection** aLinks)
{
if (nsnull == mLinks) {
mLinks = new nsContentList(this, MatchLinks);
if (nsnull == mLinks) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(mLinks);
}
*aLinks = (nsIDOMHTMLCollection *)mLinks;
NS_ADDREF(mLinks);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLDocument::GetForms(nsIDOMHTMLCollection** aForms)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
PRBool
nsHTMLDocument::MatchAnchors(nsIContent *aContent)
{
nsIAtom *name = aContent->GetTag();
static nsAutoString anchor("A");
nsAutoString attr;
PRBool result = PR_FALSE;
if ((nsnull != name) &&
anchor.EqualsIgnoreCase(name) &&
(eContentAttr_HasValue == aContent->GetAttribute("NAME", attr))) {
result = PR_TRUE;
}
NS_IF_RELEASE(name);
return result;
}
NS_IMETHODIMP
nsHTMLDocument::GetAnchors(nsIDOMHTMLCollection** aAnchors)
{
if (nsnull == mAnchors) {
mAnchors = new nsContentList(this, MatchAnchors);
if (nsnull == mAnchors) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(mAnchors);
}
*aAnchors = (nsIDOMHTMLCollection *)mAnchors;
NS_ADDREF(mAnchors);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLDocument::GetCookie(nsString& aCookie)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::SetCookie(const nsString& aCookie)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::Open(JSContext *cx, jsval *argv, PRUint32 argc)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::Close()
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::Write(JSContext *cx, jsval *argv, PRUint32 argc)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::Writeln(JSContext *cx, jsval *argv, PRUint32 argc)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::GetElementById(const nsString& aElementId, nsIDOMElement** aReturn)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::GetElementsByName(const nsString& aElementName, nsIDOMNodeList** aReturn)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
if (nsnull == mScriptObject) {
res = NS_NewScriptHTMLDocument(aContext, this, (nsISupports *)global, (void**)&mScriptObject);
}
*aScriptObject = mScriptObject;
NS_RELEASE(global);
return res;
}

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

@ -21,17 +21,22 @@
#include "nsDocument.h" #include "nsDocument.h"
#include "nsMarkupDocument.h" #include "nsMarkupDocument.h"
#include "nsIHTMLDocument.h" #include "nsIHTMLDocument.h"
#include "nsIDOMHTMLDocument.h"
class nsIHTMLStyleSheet; class nsIHTMLStyleSheet;
class nsContentList;
class nsIContentViewerContainer; class nsIContentViewerContainer;
class nsHTMLDocument : public nsMarkupDocument { class nsHTMLDocument : public nsMarkupDocument, public nsIHTMLDocument, public nsIDOMHTMLDocument {
public: public:
nsHTMLDocument(); nsHTMLDocument();
virtual ~nsHTMLDocument(); virtual ~nsHTMLDocument();
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
NS_IMETHOD_(nsrefcnt) AddRef(void);
NS_IMETHOD_(nsrefcnt) Release(void);
NS_IMETHOD StartDocumentLoad(nsIURL* aUrl, NS_IMETHOD StartDocumentLoad(nsIURL* aUrl,
nsIContentViewerContainer* aContainer, nsIContentViewerContainer* aContainer,
nsIStreamListener** aDocListener); nsIStreamListener** aDocListener);
@ -42,35 +47,108 @@ public:
NS_IMETHOD GetImageMap(const nsString& aMapName, nsIImageMap** aResult); NS_IMETHOD GetImageMap(const nsString& aMapName, nsIImageMap** aResult);
static PRInt32 GetOuterOffset() { // nsIDOMDocument interface
return offsetof(nsHTMLDocument,mIHTMLDocument); NS_IMETHOD GetMasterDoc(nsIDOMDocument **aDocument)
} { return nsDocument::GetMasterDoc(aDocument); }
NS_IMETHOD GetDocumentType(nsIDOMDocumentType** aDocumentType);
NS_IMETHOD GetProlog(nsIDOMNodeList** aProlog)
{ return nsDocument::GetProlog(aProlog); }
NS_IMETHOD GetEpilog(nsIDOMNodeList** aEpilog)
{ return nsDocument::GetEpilog(aEpilog); }
NS_IMETHOD GetDocumentElement(nsIDOMElement** aDocumentElement)
{ return nsDocument::GetDocumentElement(aDocumentElement); }
NS_IMETHOD CreateDocumentFragment(nsIDOMDocumentFragment** aReturn)
{ return nsDocument::CreateDocumentFragment(aReturn); }
NS_IMETHOD CreateComment(const nsString& aData, nsIDOMComment** aReturn)
{ return nsDocument::CreateComment(aData, aReturn); }
NS_IMETHOD CreateProcessingInstruction(const nsString& aTarget, const nsString& aData, nsIDOMProcessingInstruction** aReturn)
{ return nsDocument::CreateProcessingInstruction(aTarget, aData, aReturn); }
NS_IMETHOD CreateAttribute(const nsString& aName, nsIDOMNode* aValue, nsIDOMAttribute** aReturn)
{ return nsDocument::CreateAttribute(aName, aValue, aReturn); }
NS_IMETHOD CreateElement(const nsString& aTagName, NS_IMETHOD CreateElement(const nsString& aTagName,
nsIDOMNamedNodeMap* aAttributes, nsIDOMNamedNodeMap* aAttributes,
nsIDOMElement** aReturn); nsIDOMElement** aReturn);
NS_IMETHOD CreateTextNode(const nsString& aData, nsIDOMText** aReturn); NS_IMETHOD CreateTextNode(const nsString& aData, nsIDOMText** aReturn);
NS_IMETHOD GetElementsByTagName(const nsString& aTagname, nsIDOMNodeList** aReturn)
{ return nsDocument::GetElementsByTagName(aTagname, aReturn); }
// nsIDOMNode interface
NS_IMETHOD GetNodeName(nsString& aNodeName)
{ return nsDocument::GetNodeName(aNodeName); }
NS_IMETHOD GetNodeValue(nsString& aNodeValue)
{ return nsDocument::GetNodeValue(aNodeValue); }
NS_IMETHOD SetNodeValue(const nsString& aNodeValue)
{ return nsDocument::SetNodeValue(aNodeValue); }
NS_IMETHOD GetNodeType(PRInt32* aNodeType)
{ return nsDocument::GetNodeType(aNodeType); }
NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode)
{ return nsDocument::GetParentNode(aParentNode); }
NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes)
{ return nsDocument::GetChildNodes(aChildNodes); }
NS_IMETHOD GetHasChildNodes(PRBool* aHasChildNodes)
{ return nsDocument::GetHasChildNodes(aHasChildNodes); }
NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild)
{ return nsDocument::GetFirstChild(aFirstChild); }
NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild)
{ return nsDocument::GetLastChild(aLastChild); }
NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling)
{ return nsDocument::GetPreviousSibling(aPreviousSibling); }
NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling)
{ return nsDocument::GetNextSibling(aNextSibling); }
NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes)
{ return nsDocument::GetAttributes(aAttributes); }
NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aReturn)
{ return nsDocument::InsertBefore(aNewChild, aRefChild, aReturn); }
NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
{ return nsDocument::ReplaceChild(aNewChild, aOldChild, aReturn); }
NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
{ return nsDocument::RemoveChild(aOldChild, aReturn); }
NS_IMETHOD CloneNode(nsIDOMNode** aReturn)
{ return nsDocument::CloneNode(aReturn); }
NS_IMETHOD Equals(nsIDOMNode* aNode, PRBool aDeep, PRBool* aReturn)
{ return nsDocument::Equals(aNode, aDeep, aReturn); }
// nsIDOMHTMLDocument interface
NS_IMETHOD GetTitle(nsString& aTitle);
NS_IMETHOD GetReferrer(nsString& aReferrer);
NS_IMETHOD GetFileSize(nsString& aFileSize);
NS_IMETHOD GetFileCreatedDate(nsString& aFileCreatedDate);
NS_IMETHOD GetFileModifiedDate(nsString& aFileModifiedDate);
NS_IMETHOD GetFileUpdatedDate(nsString& aFileUpdatedDate);
NS_IMETHOD GetDomain(nsString& aDomain);
NS_IMETHOD GetURL(nsString& aURL);
NS_IMETHOD GetBody(nsIDOMHTMLElement** aBody);
NS_IMETHOD SetBody(nsIDOMHTMLElement* aBody);
NS_IMETHOD GetImages(nsIDOMHTMLCollection** aImages);
NS_IMETHOD GetApplets(nsIDOMHTMLCollection** aApplets);
NS_IMETHOD GetLinks(nsIDOMHTMLCollection** aLinks);
NS_IMETHOD GetForms(nsIDOMHTMLCollection** aForms);
NS_IMETHOD GetAnchors(nsIDOMHTMLCollection** aAnchors);
NS_IMETHOD GetCookie(nsString& aCookie);
NS_IMETHOD SetCookie(const nsString& aCookie);
NS_IMETHOD Open(JSContext *cx, jsval *argv, PRUint32 argc);
NS_IMETHOD Close();
NS_IMETHOD Write(JSContext *cx, jsval *argv, PRUint32 argc);
NS_IMETHOD Writeln(JSContext *cx, jsval *argv, PRUint32 argc);
NS_IMETHOD GetElementById(const nsString& aElementId, nsIDOMElement** aReturn);
NS_IMETHOD GetElementsByName(const nsString& aElementName, nsIDOMNodeList** aReturn);
// From nsIScriptObjectOwner interface, implemented by nsDocument
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
protected: protected:
virtual void AddStyleSheetToSet(nsIStyleSheet* aSheet, nsIStyleSet* aSet); virtual void AddStyleSheetToSet(nsIStyleSheet* aSheet, nsIStyleSet* aSet);
static PRBool MatchLinks(nsIContent *aContent);
static PRBool MatchAnchors(nsIContent *aContent);
class AggIHTMLDocument : public nsIHTMLDocument {
public:
AggIHTMLDocument();
~AggIHTMLDocument();
NS_DECL_ISUPPORTS
NS_IMETHOD SetTitle(const nsString& aTitle);
NS_IMETHOD AddImageMap(nsIImageMap* aMap);
NS_IMETHOD GetImageMap(const nsString& aMapName, nsIImageMap** aResult);
};
AggIHTMLDocument mIHTMLDocument;
nsIHTMLStyleSheet* mAttrStyleSheet; nsIHTMLStyleSheet* mAttrStyleSheet;
nsVoidArray mImageMaps; nsVoidArray mImageMaps;
nsContentList *mImages;
nsContentList *mApplets;
nsContentList *mEmbeds;
nsContentList *mLinks;
nsContentList *mAnchors;
}; };
#endif /* nsHTMLDocument_h___ */ #endif /* nsHTMLDocument_h___ */

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

@ -23,6 +23,7 @@ class nsIContent;
class nsIPresShell; class nsIPresShell;
class nsIStyleSheet; class nsIStyleSheet;
class nsString; class nsString;
class nsIDocument;
#define NS_IDOCUMENT_OBSERVER_IID \ #define NS_IDOCUMENT_OBSERVER_IID \
{ 0xb3f92460, 0x944c, 0x11d1, {0x93, 0x23, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}} { 0xb3f92460, 0x944c, 0x11d1, {0x93, 0x23, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
@ -34,37 +35,37 @@ public:
* Notify that a content model update is beginning. This call can be * Notify that a content model update is beginning. This call can be
* nested. * nested.
*/ */
NS_IMETHOD BeginUpdate() = 0; NS_IMETHOD BeginUpdate(nsIDocument *aDocument) = 0;
/** /**
* Notify that a content model update is finished. This call can be * Notify that a content model update is finished. This call can be
* nested. * nested.
*/ */
NS_IMETHOD EndUpdate() = 0; NS_IMETHOD EndUpdate(nsIDocument *aDocument) = 0;
/** /**
* Notify the observer that a document load is beginning. * Notify the observer that a document load is beginning.
*/ */
NS_IMETHOD BeginLoad() = 0; NS_IMETHOD BeginLoad(nsIDocument *aDocument) = 0;
/** /**
* Notify the observer that a document load has finished. Note that * Notify the observer that a document load has finished. Note that
* the associated reflow of the document will be done <b>before</b> * the associated reflow of the document will be done <b>before</b>
* EndLoad is invoked, not after. * EndLoad is invoked, not after.
*/ */
NS_IMETHOD EndLoad() = 0; NS_IMETHOD EndLoad(nsIDocument *aDocument) = 0;
/** /**
* Notify the observer that the document is being reflowed in * Notify the observer that the document is being reflowed in
* the given presentation shell. * the given presentation shell.
*/ */
NS_IMETHOD BeginReflow(nsIPresShell* aShell) = 0; NS_IMETHOD BeginReflow(nsIDocument *aDocument, nsIPresShell* aShell) = 0;
/** /**
* Notify the observer that the document is done being reflowed in * Notify the observer that the document is done being reflowed in
* the given presentation shell. * the given presentation shell.
*/ */
NS_IMETHOD EndReflow(nsIPresShell* aShell) = 0; NS_IMETHOD EndReflow(nsIDocument *aDocument, nsIPresShell* aShell) = 0;
/** /**
* Notification that the content model has changed. This method is * Notification that the content model has changed. This method is
@ -78,11 +79,13 @@ public:
* added/removed from the document (the other notifications are used * added/removed from the document (the other notifications are used
* for that). * for that).
* *
* @param aDocument The document being observed
* @param aContent the piece of content that changed * @param aContent the piece of content that changed
* @param aSubContent subrange information about the piece of content * @param aSubContent subrange information about the piece of content
* that changed * that changed
*/ */
NS_IMETHOD ContentChanged(nsIContent* aContent, NS_IMETHOD ContentChanged(nsIDocument *aDocument,
nsIContent* aContent,
nsISupports* aSubContent) = 0; nsISupports* aSubContent) = 0;
/** /**
@ -93,9 +96,11 @@ public:
* method directly). The notification is passed on to all of the * method directly). The notification is passed on to all of the
* document observers. * document observers.
* *
* @param aDocument The document being observed
* @param aContainer the container that had a new child appended * @param aContainer the container that had a new child appended
*/ */
NS_IMETHOD ContentAppended(nsIContent* aContainer) = 0; NS_IMETHOD ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer) = 0;
/** /**
* Notification that content has been inserted. This method is called * Notification that content has been inserted. This method is called
@ -104,11 +109,13 @@ public:
* need to invoke this method directly). The notification is passed on * need to invoke this method directly). The notification is passed on
* to all of the document observers. * to all of the document observers.
* *
* @param aDocument The document being observed
* @param aContainer the container that now contains aChild * @param aContainer the container that now contains aChild
* @param aChild the child that was inserted * @param aChild the child that was inserted
* @param aIndexInContainer the index of the child in the container * @param aIndexInContainer the index of the child in the container
*/ */
NS_IMETHOD ContentInserted(nsIContent* aContainer, NS_IMETHOD ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild, nsIContent* aChild,
PRInt32 aIndexInContainer) = 0; PRInt32 aIndexInContainer) = 0;
@ -119,13 +126,15 @@ public:
* invoke this method directly). The notification is passed on to all * invoke this method directly). The notification is passed on to all
* of the document observers. * of the document observers.
* *
* @param aDocument The document being observed
* @param aContainer the container that now contains aChild * @param aContainer the container that now contains aChild
* @param aOldChild the child that was replaced * @param aOldChild the child that was replaced
* @param aNewChild the child that replaced aOldChild * @param aNewChild the child that replaced aOldChild
* @param aIndexInContainer the index of the old and new child in the * @param aIndexInContainer the index of the old and new child in the
* container * container
*/ */
NS_IMETHOD ContentReplaced(nsIContent* aContainer, NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild, nsIContent* aOldChild,
nsIContent* aNewChild, nsIContent* aNewChild,
PRInt32 aIndexInContainer) = 0; PRInt32 aIndexInContainer) = 0;
@ -137,11 +146,13 @@ public:
* there is normally no need to invoke this method directly). The * there is normally no need to invoke this method directly). The
* notification is passed on to all of the document observers. * notification is passed on to all of the document observers.
* *
* @param aDocument The document being observed
* @param aContainer the container that contains aChild * @param aContainer the container that contains aChild
* @param aChild the child that will be removed * @param aChild the child that will be removed
* @param aIndexInContainer the index of the child in the container * @param aIndexInContainer the index of the child in the container
*/ */
NS_IMETHOD ContentWillBeRemoved(nsIContent* aContainer, NS_IMETHOD ContentWillBeRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild, nsIContent* aChild,
PRInt32 aIndexInContainer) = 0; PRInt32 aIndexInContainer) = 0;
@ -152,12 +163,14 @@ public:
* invoke this method directly). The notification is passed on to all * invoke this method directly). The notification is passed on to all
* of the document observers. * of the document observers.
* *
* @param aDocument The document being observed
* @param aContainer the container that had a child removed * @param aContainer the container that had a child removed
* @param aChild the child that was just removed * @param aChild the child that was just removed
* @param aIndexInContainer the index of the child in the container * @param aIndexInContainer the index of the child in the container
* before it was removed * before it was removed
*/ */
NS_IMETHOD ContentHasBeenRemoved(nsIContent* aContainer, NS_IMETHOD ContentHasBeenRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild, nsIContent* aChild,
PRInt32 aIndexInContainer) = 0; PRInt32 aIndexInContainer) = 0;
@ -167,9 +180,20 @@ public:
* to the document. The notification is passed on to all of the * to the document. The notification is passed on to all of the
* document observers. * document observers.
* *
* @param aDocument The document being observed
* @param aStyleSheet the StyleSheet that has been added * @param aStyleSheet the StyleSheet that has been added
*/ */
NS_IMETHOD StyleSheetAdded(nsIStyleSheet* aStyleSheet) = 0; NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet) = 0;
/**
* The document is in the process of being destroyed.
* This method is called automatically during document
* destruction.
*
* @param aDocument The document being observed
*/
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument) = 0;
}; };
#endif /* nsIDocumentObserver_h___ */ #endif /* nsIDocumentObserver_h___ */

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

@ -23,6 +23,7 @@ DEFINES = -D_IMPL_NS_LAYOUT
CPPSRCS = \ CPPSRCS = \
nsContainerFrame.cpp \ nsContainerFrame.cpp \
nsContentList.cpp \
nsDocument.cpp \ nsDocument.cpp \
nsFrame.cpp \ nsFrame.cpp \
nsFrameImageLoader.cpp \ nsFrameImageLoader.cpp \

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

@ -22,6 +22,7 @@ DEFINES=-D_IMPL_NS_LAYOUT -DWIN32_LEAN_AND_MEAN
CPPSRCS = \ CPPSRCS = \
nsContainerFrame.cpp \ nsContainerFrame.cpp \
nsContentList.cpp \
nsDocument.cpp \ nsDocument.cpp \
nsFrame.cpp \ nsFrame.cpp \
nsFrameImageLoader.cpp \ nsFrameImageLoader.cpp \
@ -46,6 +47,7 @@ EXPORTS=nsSelectionRange.h nsSelectionPoint.h
CPP_OBJS= \ CPP_OBJS= \
.\$(OBJDIR)\nsContainerFrame.obj \ .\$(OBJDIR)\nsContainerFrame.obj \
.\$(OBJDIR)\nsContentList.obj \
.\$(OBJDIR)\nsDocument.obj \ .\$(OBJDIR)\nsDocument.obj \
.\$(OBJDIR)\nsFrame.obj \ .\$(OBJDIR)\nsFrame.obj \
.\$(OBJDIR)\nsFrameImageLoader.obj \ .\$(OBJDIR)\nsFrameImageLoader.obj \

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

@ -0,0 +1,342 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsContentList.h"
#include "nsIContent.h"
#include "nsIDOMNode.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDocument.h"
nsContentList::nsContentList(nsIDocument *aDocument,
const nsString& aMatchTag)
{
mMatchTag = new nsString(aMatchTag);
mFunc = nsnull;
Init(aDocument);
}
nsContentList::nsContentList(nsIDocument *aDocument,
nsContentListMatchFunc aFunc)
{
mFunc = aFunc;
mMatchTag = nsnull;
Init(aDocument);
}
void nsContentList::Init(nsIDocument *aDocument)
{
NS_INIT_REFCNT();
mScriptObject = nsnull;
// XXX We don't reference count this reference.
// 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 = mDocument->GetRootContent();
PopulateSelf(root);
NS_RELEASE(root);
}
nsContentList::~nsContentList()
{
if (nsnull != mDocument) {
mDocument->RemoveObserver(this);
}
if (nsnull != mMatchTag) {
delete mMatchTag;
}
}
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)
{
if (nsnull == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIDOMNodeListIID)) {
*aInstancePtr = (void*)(nsIDOMNodeList*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kIDOMHTMLCollectionIID)) {
*aInstancePtr = (void*)(nsIDOMHTMLCollection*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
*aInstancePtr = (void*)(nsIScriptObjectOwner*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)(nsIDOMNodeList*)this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsContentList)
NS_IMPL_RELEASE(nsContentList)
NS_IMETHODIMP
nsContentList::Match(nsIContent *aContent, PRBool *aMatch)
{
if (nsnull != mMatchTag) {
nsIAtom *name = aContent->GetTag();
if ((nsnull !=name) && mMatchTag->EqualsIgnoreCase(name)) {
*aMatch = PR_TRUE;
}
else {
*aMatch = PR_FALSE;
}
NS_IF_RELEASE(name);
}
else if (nsnull != mFunc) {
*aMatch = (*mFunc)(aContent);
}
else {
*aMatch = PR_FALSE;
}
return NS_OK;
}
NS_IMETHODIMP
nsContentList::Add(nsIContent *aContent)
{
// XXX Should hold a reference ??
mContent.AppendElement(aContent);
return NS_OK;
}
NS_IMETHODIMP
nsContentList::Remove(nsIContent *aContent)
{
// XXX Should drop a reference ??
mContent.RemoveElement(aContent);
return NS_OK;
}
NS_IMETHODIMP
nsContentList::Reset()
{
// XXX Should drop references ??
mContent.Clear();
return NS_OK;
}
NS_IMETHODIMP
nsContentList::GetLength(PRUint32* aLength)
{
*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("name", name) == eContentAttr_HasValue) &&
(aName.Equals(name))) {
return content->QueryInterface(kIDOMNodeIID, (void **)aReturn);
}
}
}
*aReturn = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsContentList::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
if (nsnull == mScriptObject) {
res = NS_NewScriptHTMLCollection(aContext, this, global, (void**)&mScriptObject);
}
*aScriptObject = mScriptObject;
NS_RELEASE(global);
return res;
}
NS_IMETHODIMP
nsContentList::ResetScriptObject()
{
mScriptObject = nsnull;
return NS_OK;
}
PRBool nsContentList::MatchSelf(nsIContent *aContent)
{
PRBool match;
PRInt32 i, count;
Match(aContent, &match);
if (match) {
return PR_TRUE;
}
count = aContent->ChildCount();
for (i = 0; i < count; i++) {
nsIContent *child = aContent->ChildAt(i);
if (MatchSelf(child)) {
NS_RELEASE(child);
return PR_TRUE;
}
NS_RELEASE(child);
}
return PR_FALSE;
}
void nsContentList::PopulateSelf(nsIContent *aContent)
{
PRBool match;
PRInt32 i, count;
Match(aContent, &match);
if (match) {
Add(aContent);
}
count = aContent->ChildCount();
for (i = 0; i < count; i++) {
nsIContent *child = aContent->ChildAt(i);
PopulateSelf(child);
NS_RELEASE(child);
}
}
NS_IMETHODIMP
nsContentList::ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer)
{
if (aContainer->ChildCount() > 0) {
nsIContent *content = aContainer->ChildAt(aContainer->ChildCount()-1);
if (MatchSelf(content)) {
Reset();
nsIContent *root = aDocument->GetRootContent();
PopulateSelf(root);
NS_RELEASE(root);
}
NS_RELEASE(content);
}
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::ContentHasBeenRemoved(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)
{
if (nsnull != mDocument) {
aDocument->RemoveObserver(this);
mDocument = nsnull;
}
Reset();
return NS_OK;
}

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

@ -0,0 +1,104 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsContentList_h___
#define nsContentList_h___
#include "nsISupports.h"
#include "nsVoidArray.h"
#include "nsString.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDOMNodeList.h"
#include "nsIDocumentObserver.h"
#include "nsIScriptObjectOwner.h"
typedef PRBool (*nsContentListMatchFunc)(nsIContent *aContent);
class nsIDocument;
class nsContentList : public nsIDOMNodeList, public nsIDOMHTMLCollection, public nsIScriptObjectOwner, public nsIDocumentObserver {
public:
nsContentList(nsIDocument *aDocument, const nsString& aMatchTag);
nsContentList(nsIDocument *aDocument, nsContentListMatchFunc aFunc);
virtual ~nsContentList();
NS_DECL_ISUPPORTS
NS_IMETHOD Match(nsIContent *aContent, PRBool *aMatch);
NS_IMETHOD Add(nsIContent *aContent);
NS_IMETHOD Remove(nsIContent *aContent);
NS_IMETHOD Reset();
NS_IMETHOD GetLength(PRUint32* aLength);
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn);
NS_IMETHOD NamedItem(const nsString& aName, nsIDOMNode** aReturn);
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD ResetScriptObject();
NS_IMETHOD BeginUpdate(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD EndUpdate(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD BeginLoad(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD EndLoad(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD BeginReflow(nsIDocument *aDocument,
nsIPresShell* aShell) { return NS_OK; }
NS_IMETHOD EndReflow(nsIDocument *aDocument,
nsIPresShell* aShell) { return NS_OK; }
NS_IMETHOD ContentChanged(nsIDocument *aDocument,
nsIContent* aContent,
nsISupports* aSubContent) { return NS_OK; }
NS_IMETHOD ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer);
NS_IMETHOD ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentWillBeRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer) { return NS_OK; }
NS_IMETHOD ContentHasBeenRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet) { return NS_OK; }
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument);
protected:
void Init(nsIDocument *aDocument);
void PopulateSelf(nsIContent *aContent);
PRBool MatchSelf(nsIContent *aContent);
nsString *mMatchTag;
nsContentListMatchFunc mFunc;
nsVoidArray mContent;
void *mScriptObject;
nsIDocument *mDocument;
};
#endif // nsContentList_h___

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

@ -30,7 +30,7 @@
#include "nsIScriptGlobalObject.h" #include "nsIScriptGlobalObject.h"
#include "nsIScriptContextOwner.h" #include "nsIScriptContextOwner.h"
#include "nsIParser.h" #include "nsIParser.h"
#include "nsContentList.h"
#include "nsCSSPropIDs.h" #include "nsCSSPropIDs.h"
#include "nsCSSProps.h" #include "nsCSSProps.h"
@ -143,6 +143,7 @@ nsDocument::nsDocument()
mScriptContextOwner = nsnull; mScriptContextOwner = nsnull;
mListenerManager = nsnull; mListenerManager = nsnull;
mParser = nsnull; mParser = nsnull;
mInDestructor = PR_FALSE;
if (NS_OK != NS_NewSelection(&mSelection)) { if (NS_OK != NS_NewSelection(&mSelection)) {
printf("*************** Error: nsDocument::nsDocument - Creation of Selection failed!\n"); printf("*************** Error: nsDocument::nsDocument - Creation of Selection failed!\n");
@ -153,6 +154,18 @@ nsDocument::nsDocument()
nsDocument::~nsDocument() nsDocument::~nsDocument()
{ {
// XXX Inform any remaining observers that we are going away.
// Note that this currently contradicts the rule that all
// observers must hold on to live references to the document.
// This notification will occur only after the reference has
// been dropped.
mInDestructor = PR_TRUE;
PRInt32 index, count = mObservers.Count();
for (index = 0; index < count; index++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(index);
observer->DocumentWillBeDestroyed(this);
}
if (nsnull != mDocumentTitle) { if (nsnull != mDocumentTitle) {
delete mDocumentTitle; delete mDocumentTitle;
mDocumentTitle = nsnull; mDocumentTitle = nsnull;
@ -162,7 +175,7 @@ nsDocument::~nsDocument()
mParentDocument = nsnull; mParentDocument = nsnull;
// Delete references to sub-documents // Delete references to sub-documents
PRInt32 index = mSubDocuments.Count(); index = mSubDocuments.Count();
while (--index >= 0) { while (--index >= 0) {
nsIDocument* subdoc = (nsIDocument*) mSubDocuments.ElementAt(index); nsIDocument* subdoc = (nsIDocument*) mSubDocuments.ElementAt(index);
NS_RELEASE(subdoc); NS_RELEASE(subdoc);
@ -399,7 +412,7 @@ void nsDocument::AddStyleSheet(nsIStyleSheet* aSheet)
count = mObservers.Count(); count = mObservers.Count();
for (index = 0; index < count; index++) { for (index = 0; index < count; index++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(index); nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(index);
observer->StyleSheetAdded(aSheet); observer->StyleSheetAdded(this, aSheet);
} }
} }
@ -453,7 +466,14 @@ void nsDocument::AddObserver(nsIDocumentObserver* aObserver)
PRBool nsDocument::RemoveObserver(nsIDocumentObserver* aObserver) PRBool nsDocument::RemoveObserver(nsIDocumentObserver* aObserver)
{ {
return mObservers.RemoveElement(aObserver); // If we're in the process of destroying the document (and we're
// informing the observers of the destruction), don't remove the
// observers from the list. This is not a big deal, since we
// don't hold a live reference to the observers.
if (!mInDestructor)
return mObservers.RemoveElement(aObserver);
else
return (mObservers.IndexOf(aObserver) != -1);
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -462,7 +482,7 @@ nsDocument::BeginLoad()
PRInt32 i, count = mObservers.Count(); PRInt32 i, count = mObservers.Count();
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i]; nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i];
observer->BeginLoad(); observer->BeginLoad(this);
} }
return NS_OK; return NS_OK;
} }
@ -473,7 +493,7 @@ nsDocument::EndLoad()
PRInt32 i, count = mObservers.Count(); PRInt32 i, count = mObservers.Count();
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i]; nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i];
observer->EndLoad(); observer->EndLoad(this);
} }
return NS_OK; return NS_OK;
} }
@ -484,7 +504,7 @@ void nsDocument::ContentChanged(nsIContent* aContent,
PRInt32 count = mObservers.Count(); PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) { for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentChanged(aContent, aSubContent); observer->ContentChanged(this, aContent, aSubContent);
} }
} }
@ -493,7 +513,7 @@ void nsDocument::ContentAppended(nsIContent* aContainer)
PRInt32 count = mObservers.Count(); PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) { for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentAppended(aContainer); observer->ContentAppended(this, aContainer);
} }
} }
@ -504,7 +524,7 @@ void nsDocument::ContentInserted(nsIContent* aContainer,
PRInt32 count = mObservers.Count(); PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) { for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentInserted(aContainer, aChild, aIndexInContainer); observer->ContentInserted(this, aContainer, aChild, aIndexInContainer);
} }
} }
@ -516,7 +536,7 @@ void nsDocument::ContentReplaced(nsIContent* aContainer,
PRInt32 count = mObservers.Count(); PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) { for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentReplaced(aContainer, aOldChild, aNewChild, observer->ContentReplaced(this, aContainer, aOldChild, aNewChild,
aIndexInContainer); aIndexInContainer);
} }
} }
@ -528,7 +548,8 @@ void nsDocument::ContentWillBeRemoved(nsIContent* aContainer,
PRInt32 count = mObservers.Count(); PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) { for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentWillBeRemoved(aContainer, aChild, aIndexInContainer); observer->ContentWillBeRemoved(this, aContainer,
aChild, aIndexInContainer);
} }
} }
@ -539,7 +560,8 @@ void nsDocument::ContentHasBeenRemoved(nsIContent* aContainer,
PRInt32 count = mObservers.Count(); PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) { for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentHasBeenRemoved(aContainer, aChild, aIndexInContainer); observer->ContentHasBeenRemoved(this, aContainer,
aChild, aIndexInContainer);
} }
} }
@ -679,8 +701,14 @@ NS_IMETHODIMP
nsDocument::GetElementsByTagName(const nsString& aTagname, nsDocument::GetElementsByTagName(const nsString& aTagname,
nsIDOMNodeList** aReturn) nsIDOMNodeList** aReturn)
{ {
//XXX TBI nsContentList* list = new nsContentList(this, aTagname);
return NS_ERROR_NOT_IMPLEMENTED; if (nsnull == list) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aReturn = (nsIDOMNodeList *)list;
NS_ADDREF(list);
return NS_OK;
} }
// //
@ -993,7 +1021,6 @@ void nsDocument::GetSelectionText(nsString & aText) {
} }
void nsDocument::BeginConvertToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode) void nsDocument::BeginConvertToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode)
{ {
nsIContent* content = nsnull; nsIContent* content = nsnull;

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

@ -218,7 +218,7 @@ public:
NS_IMETHOD CreateTextNode(const nsString& aData, nsIDOMText** aReturn); NS_IMETHOD CreateTextNode(const nsString& aData, nsIDOMText** aReturn);
NS_IMETHOD GetElementsByTagName(const nsString& aTagname, nsIDOMNodeList** aReturn); NS_IMETHOD GetElementsByTagName(const nsString& aTagname, nsIDOMNodeList** aReturn);
// nsIDOMNode // nsIDOMNode interface
NS_IMETHOD GetNodeName(nsString& aNodeName); NS_IMETHOD GetNodeName(nsString& aNodeName);
NS_IMETHOD GetNodeValue(nsString& aNodeValue); NS_IMETHOD GetNodeValue(nsString& aNodeValue);
NS_IMETHOD SetNodeValue(const nsString& aNodeValue); NS_IMETHOD SetNodeValue(const nsString& aNodeValue);
@ -284,6 +284,7 @@ protected:
nsIScriptContextOwner *mScriptContextOwner; nsIScriptContextOwner *mScriptContextOwner;
nsIParser *mParser; nsIParser *mParser;
nsIEventListenerManager* mListenerManager; nsIEventListenerManager* mListenerManager;
PRBool mInDestructor;
}; };
#endif /* nsDocument_h___ */ #endif /* nsDocument_h___ */

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

@ -147,29 +147,37 @@ public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
// nsIDocumentObserver // nsIDocumentObserver
NS_IMETHOD BeginUpdate(); NS_IMETHOD BeginUpdate(nsIDocument *aDocument);
NS_IMETHOD EndUpdate(); NS_IMETHOD EndUpdate(nsIDocument *aDocument);
NS_IMETHOD BeginLoad(); NS_IMETHOD BeginLoad(nsIDocument *aDocument);
NS_IMETHOD EndLoad(); NS_IMETHOD EndLoad(nsIDocument *aDocument);
NS_IMETHOD BeginReflow(nsIPresShell* aShell); NS_IMETHOD BeginReflow(nsIDocument *aDocument, nsIPresShell* aShell);
NS_IMETHOD EndReflow(nsIPresShell* aShell); NS_IMETHOD EndReflow(nsIDocument *aDocument, nsIPresShell* aShell);
NS_IMETHOD ContentChanged(nsIContent* aContent, NS_IMETHOD ContentChanged(nsIDocument *aDocument,
nsIContent* aContent,
nsISupports* aSubContent); nsISupports* aSubContent);
NS_IMETHOD ContentAppended(nsIContent* aContainer); NS_IMETHOD ContentAppended(nsIDocument *aDocument,
NS_IMETHOD ContentInserted(nsIContent* aContainer, nsIContent* aContainer);
NS_IMETHOD ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild, nsIContent* aChild,
PRInt32 aIndexInContainer); PRInt32 aIndexInContainer);
NS_IMETHOD ContentReplaced(nsIContent* aContainer, NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild, nsIContent* aOldChild,
nsIContent* aNewChild, nsIContent* aNewChild,
PRInt32 aIndexInContainer); PRInt32 aIndexInContainer);
NS_IMETHOD ContentWillBeRemoved(nsIContent* aContainer, NS_IMETHOD ContentWillBeRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild, nsIContent* aChild,
PRInt32 aIndexInContainer); PRInt32 aIndexInContainer);
NS_IMETHOD ContentHasBeenRemoved(nsIContent* aContainer, NS_IMETHOD ContentHasBeenRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild, nsIContent* aChild,
PRInt32 aIndexInContainer); PRInt32 aIndexInContainer);
NS_IMETHOD StyleSheetAdded(nsIStyleSheet* aStyleSheet); NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet);
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument);
// nsIPresShell // nsIPresShell
NS_IMETHOD Init(nsIDocument* aDocument, NS_IMETHOD Init(nsIDocument* aDocument,
@ -487,14 +495,14 @@ PresShell::GetRootFrame()
} }
NS_IMETHODIMP NS_IMETHODIMP
PresShell::BeginUpdate() PresShell::BeginUpdate(nsIDocument *aDocument)
{ {
mUpdateCount++; mUpdateCount++;
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
PresShell::EndUpdate() PresShell::EndUpdate(nsIDocument *aDocument)
{ {
NS_PRECONDITION(0 != mUpdateCount, "too many EndUpdate's"); NS_PRECONDITION(0 != mUpdateCount, "too many EndUpdate's");
if (--mUpdateCount == 0) { if (--mUpdateCount == 0) {
@ -504,25 +512,25 @@ PresShell::EndUpdate()
} }
NS_IMETHODIMP NS_IMETHODIMP
PresShell::BeginLoad() PresShell::BeginLoad(nsIDocument *aDocument)
{ {
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
PresShell::EndLoad() PresShell::EndLoad(nsIDocument *aDocument)
{ {
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
PresShell::BeginReflow(nsIPresShell* aShell) PresShell::BeginReflow(nsIDocument *aDocument, nsIPresShell* aShell)
{ {
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
PresShell::EndReflow(nsIPresShell* aShell) PresShell::EndReflow(nsIDocument *aDocument, nsIPresShell* aShell)
{ {
return NS_OK; return NS_OK;
} }
@ -594,7 +602,8 @@ ContentTag(nsIContent* aContent, PRIntn aSlot)
#endif #endif
NS_IMETHODIMP NS_IMETHODIMP
PresShell::ContentChanged(nsIContent* aContent, PresShell::ContentChanged(nsIDocument *aDocument,
nsIContent* aContent,
nsISupports* aSubContent) nsISupports* aSubContent)
{ {
NS_PRECONDITION(nsnull != mRootFrame, "null root frame"); NS_PRECONDITION(nsnull != mRootFrame, "null root frame");
@ -620,7 +629,8 @@ PresShell::ContentChanged(nsIContent* aContent,
} }
NS_IMETHODIMP NS_IMETHODIMP
PresShell::ContentAppended(nsIContent* aContainer) PresShell::ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer)
{ {
NS_PRECONDITION(nsnull != mRootFrame, "null root frame"); NS_PRECONDITION(nsnull != mRootFrame, "null root frame");
@ -644,7 +654,8 @@ PresShell::ContentAppended(nsIContent* aContainer)
} }
NS_IMETHODIMP NS_IMETHODIMP
PresShell::ContentInserted(nsIContent* aContainer, PresShell::ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild, nsIContent* aChild,
PRInt32 aIndexInContainer) PRInt32 aIndexInContainer)
{ {
@ -667,7 +678,8 @@ PresShell::ContentInserted(nsIContent* aContainer,
} }
NS_IMETHODIMP NS_IMETHODIMP
PresShell::ContentReplaced(nsIContent* aContainer, PresShell::ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild, nsIContent* aOldChild,
nsIContent* aNewChild, nsIContent* aNewChild,
PRInt32 aIndexInContainer) PRInt32 aIndexInContainer)
@ -692,7 +704,8 @@ PresShell::ContentReplaced(nsIContent* aContainer,
// XXX keep this? // XXX keep this?
NS_IMETHODIMP NS_IMETHODIMP
PresShell::ContentWillBeRemoved(nsIContent* aContainer, PresShell::ContentWillBeRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild, nsIContent* aChild,
PRInt32 aIndexInContainer) PRInt32 aIndexInContainer)
{ {
@ -704,7 +717,8 @@ PresShell::ContentWillBeRemoved(nsIContent* aContainer,
} }
NS_IMETHODIMP NS_IMETHODIMP
PresShell::ContentHasBeenRemoved(nsIContent* aContainer, PresShell::ContentHasBeenRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild, nsIContent* aChild,
PRInt32 aIndexInContainer) PRInt32 aIndexInContainer)
{ {
@ -722,7 +736,14 @@ PresShell::ContentHasBeenRemoved(nsIContent* aContainer,
} }
NS_IMETHODIMP NS_IMETHODIMP
PresShell::StyleSheetAdded(nsIStyleSheet* aStyleSheet) PresShell::StyleSheetAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet)
{
return NS_OK;
}
NS_IMETHODIMP
PresShell::DocumentWillBeDestroyed(nsIDocument *aDocument)
{ {
return NS_OK; return NS_OK;
} }

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

@ -3066,7 +3066,7 @@ nsCSSBlockFrame::ContentInserted(nsIPresShell* aShell,
} }
else { else {
// Insert frame into the line. // Insert frame into the line.
NS_ASSERTION(line->GetLastContentIsComplete(), "bad line LCIC"); // NS_ASSERTION(line->GetLastContentIsComplete(), "bad line LCIC");
line->mChildCount++; line->mChildCount++;
line->MarkDirty(); line->MarkDirty();
} }

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

@ -527,7 +527,8 @@ nsHTMLContent::GetPreviousSibling(nsIDOMNode** aNode)
} }
} }
return NS_ERROR_FAILURE; *aNode = nsnull;
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -547,7 +548,8 @@ nsHTMLContent::GetNextSibling(nsIDOMNode** aNextSibling)
} }
} }
return NS_ERROR_FAILURE; *aNextSibling = nsnull;
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP

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

@ -37,7 +37,8 @@
#include "nsIWebShell.h" #include "nsIWebShell.h"
#include "nsIDocumentLoader.h" #include "nsIDocumentLoader.h"
#include "CNavDTD.h" #include "CNavDTD.h"
#include "nsIScriptGlobalObject.h"
#include "nsContentList.h"
//#define rickgdebug 1 //#define rickgdebug 1
#ifdef rickgdebug #ifdef rickgdebug
@ -49,6 +50,7 @@ static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID);
static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID); static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID); static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLDocumentIID, NS_IDOMHTMLDOCUMENT_IID);
NS_LAYOUT nsresult NS_LAYOUT nsresult
NS_NewHTMLDocument(nsIDocument** aInstancePtrResult) NS_NewHTMLDocument(nsIDocument** aInstancePtrResult)
@ -61,11 +63,21 @@ nsHTMLDocument::nsHTMLDocument()
: nsMarkupDocument(), : nsMarkupDocument(),
mAttrStyleSheet(nsnull) mAttrStyleSheet(nsnull)
{ {
mImages = nsnull;
mApplets = nsnull;
mEmbeds = nsnull;
mLinks = nsnull;
mAnchors = nsnull;
nsHTMLAtoms::AddrefAtoms(); nsHTMLAtoms::AddrefAtoms();
} }
nsHTMLDocument::~nsHTMLDocument() nsHTMLDocument::~nsHTMLDocument()
{ {
NS_IF_RELEASE(mImages);
NS_IF_RELEASE(mApplets);
NS_IF_RELEASE(mEmbeds);
NS_IF_RELEASE(mLinks);
NS_IF_RELEASE(mAnchors);
NS_IF_RELEASE(mAttrStyleSheet); NS_IF_RELEASE(mAttrStyleSheet);
nsHTMLAtoms::ReleaseAtoms(); nsHTMLAtoms::ReleaseAtoms();
} }
@ -79,12 +91,26 @@ NS_IMETHODIMP nsHTMLDocument::QueryInterface(REFNSIID aIID,
} }
if (aIID.Equals(kIHTMLDocumentIID)) { if (aIID.Equals(kIHTMLDocumentIID)) {
AddRef(); AddRef();
*aInstancePtr = (void**) &mIHTMLDocument; *aInstancePtr = (void**) (nsIHTMLDocument *)this;
return NS_OK;
}
if (aIID.Equals(kIDOMHTMLDocumentIID)) {
AddRef();
*aInstancePtr = (void**) (nsIDOMHTMLDocument *)this;
return NS_OK; return NS_OK;
} }
return nsDocument::QueryInterface(aIID, aInstancePtr); return nsDocument::QueryInterface(aIID, aInstancePtr);
} }
nsrefcnt nsHTMLDocument::AddRef()
{
return nsDocument::AddRef();
}
nsrefcnt nsHTMLDocument::Release()
{
return nsDocument::Release();
}
NS_IMETHODIMP NS_IMETHODIMP
nsHTMLDocument::StartDocumentLoad(nsIURL *aURL, nsHTMLDocument::StartDocumentLoad(nsIURL *aURL,
@ -244,6 +270,9 @@ void nsHTMLDocument::AddStyleSheetToSet(nsIStyleSheet* aSheet, nsIStyleSet* aSet
} }
} }
//
// nsIDOMDocument interface implementation
//
NS_IMETHODIMP NS_IMETHODIMP
nsHTMLDocument::CreateElement(const nsString& aTagName, nsHTMLDocument::CreateElement(const nsString& aTagName,
nsIDOMNamedNodeMap* aAttributes, nsIDOMNamedNodeMap* aAttributes,
@ -271,42 +300,270 @@ nsHTMLDocument::CreateTextNode(const nsString& aData, nsIDOMText** aTextNode)
return rv; return rv;
} }
//---------------------------------------------------------------------- NS_IMETHODIMP
nsHTMLDocument::GetDocumentType(nsIDOMDocumentType** aDocumentType)
// Aggregation class to give nsHTMLDocument the nsIHTMLDocument interface
#define GET_OUTER() \
((nsHTMLDocument*) ((char*)this - nsHTMLDocument::GetOuterOffset()))
nsHTMLDocument::AggIHTMLDocument::AggIHTMLDocument() {
NS_INIT_REFCNT();
}
nsHTMLDocument::AggIHTMLDocument::~AggIHTMLDocument() { }
NS_IMETHODIMP_(nsrefcnt) nsHTMLDocument::AggIHTMLDocument::AddRef() {
return GET_OUTER()->AddRef();
}
NS_IMETHODIMP_(nsrefcnt) nsHTMLDocument::AggIHTMLDocument::Release() {
return GET_OUTER()->Release();
}
NS_IMETHODIMP nsHTMLDocument::AggIHTMLDocument::QueryInterface(REFNSIID aIID,
void** aInstancePtr)
{ {
return GET_OUTER()->QueryInterface(aIID, aInstancePtr); // There's no document type for a HTML document
*aDocumentType = nsnull;
return NS_OK;
} }
NS_IMETHODIMP nsHTMLDocument::AggIHTMLDocument::SetTitle(const nsString& aTitle) { //
return GET_OUTER()->SetTitle(aTitle); // nsIDOMHTMLDocument interface implementation
//
NS_IMETHODIMP
nsHTMLDocument::GetTitle(nsString& aTitle)
{
if (nsnull != mDocumentTitle) {
aTitle.SetString(*mDocumentTitle);
}
return NS_OK;
} }
NS_IMETHODIMP nsHTMLDocument::AggIHTMLDocument::AddImageMap(nsIImageMap* aMap) { NS_IMETHODIMP
return GET_OUTER()->AddImageMap(aMap); nsHTMLDocument::GetReferrer(nsString& aReferrer)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
} }
NS_IMETHODIMP nsHTMLDocument::AggIHTMLDocument::GetImageMap(const nsString& aMapName, NS_IMETHODIMP
nsIImageMap** aResult) { nsHTMLDocument::GetFileSize(nsString& aFileSize)
return GET_OUTER()->GetImageMap(aMapName, aResult); {
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
} }
NS_IMETHODIMP
nsHTMLDocument::GetFileCreatedDate(nsString& aFileCreatedDate)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::GetFileModifiedDate(nsString& aFileModifiedDate)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::GetFileUpdatedDate(nsString& aFileUpdatedDate)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::GetDomain(nsString& aDomain)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::GetURL(nsString& aURL)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::GetBody(nsIDOMHTMLElement** aBody)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::SetBody(nsIDOMHTMLElement* aBody)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::GetImages(nsIDOMHTMLCollection** aImages)
{
if (nsnull == mImages) {
mImages = new nsContentList(this, "IMG");
if (nsnull == mImages) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(mImages);
}
*aImages = (nsIDOMHTMLCollection *)mImages;
NS_ADDREF(mImages);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLDocument::GetApplets(nsIDOMHTMLCollection** aApplets)
{
if (nsnull == mApplets) {
mApplets = new nsContentList(this, "APPLET");
if (nsnull == mApplets) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(mApplets);
}
*aApplets = (nsIDOMHTMLCollection *)mImages;
NS_ADDREF(mImages);
return NS_OK;
}
PRBool
nsHTMLDocument::MatchLinks(nsIContent *aContent)
{
nsIAtom *name = aContent->GetTag();
static nsAutoString area("AREA"), anchor("A");
nsAutoString attr;
PRBool result = PR_FALSE;
if ((nsnull != name) &&
(area.EqualsIgnoreCase(name) || anchor.EqualsIgnoreCase(name)) &&
(eContentAttr_HasValue == aContent->GetAttribute("HREF", attr))) {
result = PR_TRUE;
}
NS_IF_RELEASE(name);
return result;
}
NS_IMETHODIMP
nsHTMLDocument::GetLinks(nsIDOMHTMLCollection** aLinks)
{
if (nsnull == mLinks) {
mLinks = new nsContentList(this, MatchLinks);
if (nsnull == mLinks) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(mLinks);
}
*aLinks = (nsIDOMHTMLCollection *)mLinks;
NS_ADDREF(mLinks);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLDocument::GetForms(nsIDOMHTMLCollection** aForms)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
PRBool
nsHTMLDocument::MatchAnchors(nsIContent *aContent)
{
nsIAtom *name = aContent->GetTag();
static nsAutoString anchor("A");
nsAutoString attr;
PRBool result = PR_FALSE;
if ((nsnull != name) &&
anchor.EqualsIgnoreCase(name) &&
(eContentAttr_HasValue == aContent->GetAttribute("NAME", attr))) {
result = PR_TRUE;
}
NS_IF_RELEASE(name);
return result;
}
NS_IMETHODIMP
nsHTMLDocument::GetAnchors(nsIDOMHTMLCollection** aAnchors)
{
if (nsnull == mAnchors) {
mAnchors = new nsContentList(this, MatchAnchors);
if (nsnull == mAnchors) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(mAnchors);
}
*aAnchors = (nsIDOMHTMLCollection *)mAnchors;
NS_ADDREF(mAnchors);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLDocument::GetCookie(nsString& aCookie)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::SetCookie(const nsString& aCookie)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::Open(JSContext *cx, jsval *argv, PRUint32 argc)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::Close()
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::Write(JSContext *cx, jsval *argv, PRUint32 argc)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::Writeln(JSContext *cx, jsval *argv, PRUint32 argc)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::GetElementById(const nsString& aElementId, nsIDOMElement** aReturn)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::GetElementsByName(const nsString& aElementName, nsIDOMNodeList** aReturn)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLDocument::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
if (nsnull == mScriptObject) {
res = NS_NewScriptHTMLDocument(aContext, this, (nsISupports *)global, (void**)&mScriptObject);
}
*aScriptObject = mScriptObject;
NS_RELEASE(global);
return res;
}

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

@ -21,17 +21,22 @@
#include "nsDocument.h" #include "nsDocument.h"
#include "nsMarkupDocument.h" #include "nsMarkupDocument.h"
#include "nsIHTMLDocument.h" #include "nsIHTMLDocument.h"
#include "nsIDOMHTMLDocument.h"
class nsIHTMLStyleSheet; class nsIHTMLStyleSheet;
class nsContentList;
class nsIContentViewerContainer; class nsIContentViewerContainer;
class nsHTMLDocument : public nsMarkupDocument { class nsHTMLDocument : public nsMarkupDocument, public nsIHTMLDocument, public nsIDOMHTMLDocument {
public: public:
nsHTMLDocument(); nsHTMLDocument();
virtual ~nsHTMLDocument(); virtual ~nsHTMLDocument();
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
NS_IMETHOD_(nsrefcnt) AddRef(void);
NS_IMETHOD_(nsrefcnt) Release(void);
NS_IMETHOD StartDocumentLoad(nsIURL* aUrl, NS_IMETHOD StartDocumentLoad(nsIURL* aUrl,
nsIContentViewerContainer* aContainer, nsIContentViewerContainer* aContainer,
nsIStreamListener** aDocListener); nsIStreamListener** aDocListener);
@ -42,35 +47,108 @@ public:
NS_IMETHOD GetImageMap(const nsString& aMapName, nsIImageMap** aResult); NS_IMETHOD GetImageMap(const nsString& aMapName, nsIImageMap** aResult);
static PRInt32 GetOuterOffset() { // nsIDOMDocument interface
return offsetof(nsHTMLDocument,mIHTMLDocument); NS_IMETHOD GetMasterDoc(nsIDOMDocument **aDocument)
} { return nsDocument::GetMasterDoc(aDocument); }
NS_IMETHOD GetDocumentType(nsIDOMDocumentType** aDocumentType);
NS_IMETHOD GetProlog(nsIDOMNodeList** aProlog)
{ return nsDocument::GetProlog(aProlog); }
NS_IMETHOD GetEpilog(nsIDOMNodeList** aEpilog)
{ return nsDocument::GetEpilog(aEpilog); }
NS_IMETHOD GetDocumentElement(nsIDOMElement** aDocumentElement)
{ return nsDocument::GetDocumentElement(aDocumentElement); }
NS_IMETHOD CreateDocumentFragment(nsIDOMDocumentFragment** aReturn)
{ return nsDocument::CreateDocumentFragment(aReturn); }
NS_IMETHOD CreateComment(const nsString& aData, nsIDOMComment** aReturn)
{ return nsDocument::CreateComment(aData, aReturn); }
NS_IMETHOD CreateProcessingInstruction(const nsString& aTarget, const nsString& aData, nsIDOMProcessingInstruction** aReturn)
{ return nsDocument::CreateProcessingInstruction(aTarget, aData, aReturn); }
NS_IMETHOD CreateAttribute(const nsString& aName, nsIDOMNode* aValue, nsIDOMAttribute** aReturn)
{ return nsDocument::CreateAttribute(aName, aValue, aReturn); }
NS_IMETHOD CreateElement(const nsString& aTagName, NS_IMETHOD CreateElement(const nsString& aTagName,
nsIDOMNamedNodeMap* aAttributes, nsIDOMNamedNodeMap* aAttributes,
nsIDOMElement** aReturn); nsIDOMElement** aReturn);
NS_IMETHOD CreateTextNode(const nsString& aData, nsIDOMText** aReturn); NS_IMETHOD CreateTextNode(const nsString& aData, nsIDOMText** aReturn);
NS_IMETHOD GetElementsByTagName(const nsString& aTagname, nsIDOMNodeList** aReturn)
{ return nsDocument::GetElementsByTagName(aTagname, aReturn); }
// nsIDOMNode interface
NS_IMETHOD GetNodeName(nsString& aNodeName)
{ return nsDocument::GetNodeName(aNodeName); }
NS_IMETHOD GetNodeValue(nsString& aNodeValue)
{ return nsDocument::GetNodeValue(aNodeValue); }
NS_IMETHOD SetNodeValue(const nsString& aNodeValue)
{ return nsDocument::SetNodeValue(aNodeValue); }
NS_IMETHOD GetNodeType(PRInt32* aNodeType)
{ return nsDocument::GetNodeType(aNodeType); }
NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode)
{ return nsDocument::GetParentNode(aParentNode); }
NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes)
{ return nsDocument::GetChildNodes(aChildNodes); }
NS_IMETHOD GetHasChildNodes(PRBool* aHasChildNodes)
{ return nsDocument::GetHasChildNodes(aHasChildNodes); }
NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild)
{ return nsDocument::GetFirstChild(aFirstChild); }
NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild)
{ return nsDocument::GetLastChild(aLastChild); }
NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling)
{ return nsDocument::GetPreviousSibling(aPreviousSibling); }
NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling)
{ return nsDocument::GetNextSibling(aNextSibling); }
NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes)
{ return nsDocument::GetAttributes(aAttributes); }
NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aReturn)
{ return nsDocument::InsertBefore(aNewChild, aRefChild, aReturn); }
NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
{ return nsDocument::ReplaceChild(aNewChild, aOldChild, aReturn); }
NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
{ return nsDocument::RemoveChild(aOldChild, aReturn); }
NS_IMETHOD CloneNode(nsIDOMNode** aReturn)
{ return nsDocument::CloneNode(aReturn); }
NS_IMETHOD Equals(nsIDOMNode* aNode, PRBool aDeep, PRBool* aReturn)
{ return nsDocument::Equals(aNode, aDeep, aReturn); }
// nsIDOMHTMLDocument interface
NS_IMETHOD GetTitle(nsString& aTitle);
NS_IMETHOD GetReferrer(nsString& aReferrer);
NS_IMETHOD GetFileSize(nsString& aFileSize);
NS_IMETHOD GetFileCreatedDate(nsString& aFileCreatedDate);
NS_IMETHOD GetFileModifiedDate(nsString& aFileModifiedDate);
NS_IMETHOD GetFileUpdatedDate(nsString& aFileUpdatedDate);
NS_IMETHOD GetDomain(nsString& aDomain);
NS_IMETHOD GetURL(nsString& aURL);
NS_IMETHOD GetBody(nsIDOMHTMLElement** aBody);
NS_IMETHOD SetBody(nsIDOMHTMLElement* aBody);
NS_IMETHOD GetImages(nsIDOMHTMLCollection** aImages);
NS_IMETHOD GetApplets(nsIDOMHTMLCollection** aApplets);
NS_IMETHOD GetLinks(nsIDOMHTMLCollection** aLinks);
NS_IMETHOD GetForms(nsIDOMHTMLCollection** aForms);
NS_IMETHOD GetAnchors(nsIDOMHTMLCollection** aAnchors);
NS_IMETHOD GetCookie(nsString& aCookie);
NS_IMETHOD SetCookie(const nsString& aCookie);
NS_IMETHOD Open(JSContext *cx, jsval *argv, PRUint32 argc);
NS_IMETHOD Close();
NS_IMETHOD Write(JSContext *cx, jsval *argv, PRUint32 argc);
NS_IMETHOD Writeln(JSContext *cx, jsval *argv, PRUint32 argc);
NS_IMETHOD GetElementById(const nsString& aElementId, nsIDOMElement** aReturn);
NS_IMETHOD GetElementsByName(const nsString& aElementName, nsIDOMNodeList** aReturn);
// From nsIScriptObjectOwner interface, implemented by nsDocument
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
protected: protected:
virtual void AddStyleSheetToSet(nsIStyleSheet* aSheet, nsIStyleSet* aSet); virtual void AddStyleSheetToSet(nsIStyleSheet* aSheet, nsIStyleSet* aSet);
static PRBool MatchLinks(nsIContent *aContent);
static PRBool MatchAnchors(nsIContent *aContent);
class AggIHTMLDocument : public nsIHTMLDocument {
public:
AggIHTMLDocument();
~AggIHTMLDocument();
NS_DECL_ISUPPORTS
NS_IMETHOD SetTitle(const nsString& aTitle);
NS_IMETHOD AddImageMap(nsIImageMap* aMap);
NS_IMETHOD GetImageMap(const nsString& aMapName, nsIImageMap** aResult);
};
AggIHTMLDocument mIHTMLDocument;
nsIHTMLStyleSheet* mAttrStyleSheet; nsIHTMLStyleSheet* mAttrStyleSheet;
nsVoidArray mImageMaps; nsVoidArray mImageMaps;
nsContentList *mImages;
nsContentList *mApplets;
nsContentList *mEmbeds;
nsContentList *mLinks;
nsContentList *mAnchors;
}; };
#endif /* nsHTMLDocument_h___ */ #endif /* nsHTMLDocument_h___ */

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

@ -15,7 +15,7 @@ And now a lot more text. And now a lot more text. And now a lot more text.
<font face="Times New Roman, Times, serif">And now a lot more text. And now a lot more text. And now a lot more text. </font> <font face="Times New Roman, Times, serif">And now a lot more text. And now a lot more text. And now a lot more text. </font>
And now a lot more text. And now a lot more text. And now a lot more text. And now a lot more text. And now a lot more text. And now a lot more text.
<table border=2> <table border=2>
<tr><td><center><IMG SRC="http://zabadubop/layers/tests/mzcolor.gif">A table!</center></td><td><center>You're a brave man, Kipp.</center></td></tr> <tr><td><center><img SRC="http://zabadubop/layers/tests/mzcolor.gif">A table!</center></td><td><center>You're a brave man, Kipp.</center></td></tr>
<tr><td><center>And more text.</center></td><td><center>And still more text.</center></td></tr> <tr><td><center>And more text.</center></td><td><center>And still more text.</center></td></tr>
</table> </table>
And now a lot more text. And now a lot more text. And now a lot more text. And now a lot more text. And now a lot more text. And now a lot more text.

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

@ -19,7 +19,7 @@
var body = document.documentElement.childNodes[1]; var body = document.documentElement.childNodes[1];
var para = body.childNodes[1]; var para = body.childNodes[1];
var img1 = para.childNodes[5]; var img1 = para.childNodes[5];
var tbody = body.childNodes[2].childNodes[1]; var tbody = document.getElementsByTagName("TBODY")[0];
var tparent = tbody.childNodes[0].childNodes[0]; var tparent = tbody.childNodes[0].childNodes[0];
var img2 = tparent.childNodes[0].childNodes[0]; var img2 = tparent.childNodes[0].childNodes[0];