Bug 337543: Use nsINode more. r/sr+peterv

This commit is contained in:
cvshook%sicking.cc 2006-05-19 10:01:22 +00:00
Родитель c5ae726feb
Коммит 114883abc4
12 изменённых файлов: 291 добавлений и 535 удалений

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

@ -143,8 +143,8 @@ public:
* aPossibleAncestor (or is aPossibleAncestor). PR_FALSE
* otherwise.
*/
static PRBool ContentIsDescendantOf(nsIContent* aPossibleDescendant,
nsIContent* aPossibleAncestor);
static PRBool ContentIsDescendantOf(nsINode* aPossibleDescendant,
nsINode* aPossibleAncestor);
/*
* This method fills the |aArray| with all ancestor nodes of |aNode|
@ -339,7 +339,7 @@ public:
// Check if a node is in the document prolog, i.e. before the document
// element.
static PRBool InProlog(nsIDOMNode *aNode);
static PRBool InProlog(nsINode *aNode);
static nsIParserService* GetParserService();

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

@ -757,41 +757,19 @@ nsContentUtils::CanCallerAccess(nsIDOMNode *aNode)
//static
PRBool
nsContentUtils::InProlog(nsIDOMNode *aNode)
nsContentUtils::InProlog(nsINode *aNode)
{
NS_PRECONDITION(aNode, "missing node to nsContentUtils::InProlog");
// Check that there is an ancestor and that it is a document
nsCOMPtr<nsIDOMNode> parent;
aNode->GetParentNode(getter_AddRefs(parent));
if (!parent) {
nsINode* parent = aNode->GetNodeParent();
if (!parent || !parent->IsNodeOfType(nsINode::eDOCUMENT)) {
return PR_FALSE;
}
PRUint16 type;
parent->GetNodeType(&type);
if (type != nsIDOMNode::DOCUMENT_NODE) {
return PR_FALSE;
}
nsIDocument* doc = NS_STATIC_CAST(nsIDocument*, parent);
nsIContent* root = doc->GetRootContent();
nsCOMPtr<nsIDocument> doc = do_QueryInterface(parent);
NS_ASSERTION(doc, "document doesn't implement nsIDocument");
nsCOMPtr<nsIContent> cont = do_QueryInterface(aNode);
NS_ASSERTION(cont, "node doesn't implement nsIContent");
// Check that there are no elements before aNode to make sure we are not
// in the epilog
PRInt32 pos = doc->IndexOf(cont);
while (pos > 0) {
--pos;
nsIContent *sibl = doc->GetChildAt(pos);
if (sibl->IsNodeOfType(nsINode::eELEMENT)) {
return PR_FALSE;
}
}
return PR_TRUE;
return !root || doc->IndexOf(aNode) < doc->IndexOf(root);
}
// static
@ -1095,8 +1073,8 @@ nsContentUtils::InSameDoc(nsIDOMNode* aNode, nsIDOMNode* aOther)
// static
PRBool
nsContentUtils::ContentIsDescendantOf(nsIContent* aPossibleDescendant,
nsIContent* aPossibleAncestor)
nsContentUtils::ContentIsDescendantOf(nsINode* aPossibleDescendant,
nsINode* aPossibleAncestor)
{
NS_PRECONDITION(aPossibleDescendant, "The possible descendant is null!");
NS_PRECONDITION(aPossibleAncestor, "The possible ancestor is null!");
@ -1104,7 +1082,7 @@ nsContentUtils::ContentIsDescendantOf(nsIContent* aPossibleDescendant,
do {
if (aPossibleDescendant == aPossibleAncestor)
return PR_TRUE;
aPossibleDescendant = aPossibleDescendant->GetParent();
aPossibleDescendant = aPossibleDescendant->GetNodeParent();
} while (aPossibleDescendant);
return PR_FALSE;
@ -1628,12 +1606,12 @@ nsContentUtils::GenerateStateKey(nsIContent* aContent,
// Now start at aContent and append the indices of it and all its ancestors
// in their containers. That should at least pin down its position in the
// DOM...
nsIContent* parent = aContent->GetParent();
nsIContent* content = aContent;
nsINode* parent = aContent->GetNodeParent();
nsINode* content = aContent;
while (parent) {
KeyAppendInt(parent->IndexOf(content), aKey);
content = parent;
parent = content->GetParent();
parent = content->GetNodeParent();
}
}

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

@ -646,58 +646,6 @@ nsDOMImplementation::Init(nsIURI* aDocumentURI, nsIURI* aBaseURI,
return NS_OK;
}
// ==================================================================
// =
// ==================================================================
nsDocumentChildNodes::nsDocumentChildNodes(nsIDocument* aDocument)
{
MOZ_COUNT_CTOR(nsDocumentChildNodes);
// We don't reference count our document reference (to avoid circular
// references). We'll be told when the document goes away.
mDocument = aDocument;
}
nsDocumentChildNodes::~nsDocumentChildNodes()
{
MOZ_COUNT_DTOR(nsDocumentChildNodes);
}
NS_IMETHODIMP
nsDocumentChildNodes::GetLength(PRUint32* aLength)
{
if (mDocument) {
*aLength = mDocument->GetChildCount();
} else {
*aLength = 0;
}
return NS_OK;
}
NS_IMETHODIMP
nsDocumentChildNodes::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
*aReturn = nsnull;
if (mDocument) {
nsIContent *content = mDocument->GetChildAt(aIndex);
if (content) {
return CallQueryInterface(content, aReturn);
}
}
return NS_OK;
}
void
nsDocumentChildNodes::DropReference()
{
mDocument = nsnull;
}
// ==================================================================
// =
// ==================================================================
@ -3418,7 +3366,7 @@ NS_IMETHODIMP
nsDocument::GetChildNodes(nsIDOMNodeList** aChildNodes)
{
if (!mChildNodes) {
mChildNodes = new nsDocumentChildNodes(this);
mChildNodes = new nsChildContentList(this);
if (!mChildNodes) {
return NS_ERROR_OUT_OF_MEMORY;
}

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

@ -67,7 +67,6 @@
#include "nsIDOMEventTarget.h"
#include "nsIContent.h"
#include "nsIEventListenerManager.h"
#include "nsGenericDOMNodeList.h"
#include "nsIDOM3Node.h"
#include "nsIPrincipal.h"
#include "nsIParser.h"
@ -116,6 +115,7 @@ struct nsRadioGroupStruct;
class nsOnloadBlocker;
class nsUnblockOnloadEvent;
struct PLEvent;
class nsChildContentList;
PR_BEGIN_EXTERN_C
/* Note that these typedefs declare functions, not pointer to
@ -225,26 +225,6 @@ public:
nsDocHeaderData* mNext;
};
// Represents the children of a document (prolog, epilog and
// document element)
class nsDocumentChildNodes : public nsGenericDOMNodeList
{
public:
nsDocumentChildNodes(nsIDocument* aDocument);
~nsDocumentChildNodes();
NS_IMETHOD GetLength(PRUint32* aLength);
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn);
void DropReference();
protected:
nsDocumentChildNodes(); // Not implemented
nsIDocument* mDocument;
};
class nsDOMStyleSheetList : public nsIDOMStyleSheetList,
public nsStubDocumentObserver
{
@ -769,7 +749,7 @@ protected:
nsCOMPtr<nsIScriptLoader> mScriptLoader;
nsDocHeaderData* mHeaderData;
nsRefPtr<nsDocumentChildNodes> mChildNodes;
nsRefPtr<nsChildContentList> mChildNodes;
nsHashtable mRadioGroups;

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

@ -126,7 +126,6 @@ public:
NS_DECL_NSIDOM3NODE
// nsIContent
virtual void SetParent(nsIContent* aParent) { }
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsAString& aValue, PRBool aNotify)
{

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

@ -133,88 +133,42 @@ nsGenericDOMDataNode::SetNodeValue(const nsAString& aNodeValue)
nsresult
nsGenericDOMDataNode::GetParentNode(nsIDOMNode** aParentNode)
{
nsresult rv = NS_OK;
*aParentNode = nsnull;
nsINode *parent = GetNodeParent();
nsIContent *parent = GetParent();
if (parent) {
rv = CallQueryInterface(parent, aParentNode);
}
else if (IsInDoc()) {
rv = CallQueryInterface(GetCurrentDoc(), aParentNode);
}
else {
*aParentNode = nsnull;
}
NS_ASSERTION(NS_SUCCEEDED(rv), "Must be a DOM Node");
return rv;
return parent ? CallQueryInterface(parent, aParentNode) : NS_OK;
}
nsresult
nsGenericDOMDataNode::GetPreviousSibling(nsIDOMNode** aPrevSibling)
{
nsresult rv = NS_OK;
*aPrevSibling = nsnull;
nsIContent *sibling = nsnull;
nsIContent *parent = GetParent();
if (parent) {
PRInt32 pos = parent->IndexOf(this);
if (pos > 0) {
sibling = parent->GetChildAt(pos - 1);
}
}
else {
nsIDocument *doc = GetCurrentDoc();
if (doc) {
PRInt32 pos = doc->IndexOf(this);
if (pos > 0) {
sibling = doc->GetChildAt(pos - 1);
}
}
nsINode *parent = GetNodeParent();
if (!parent) {
return NS_OK;
}
if (sibling) {
rv = CallQueryInterface(sibling, aPrevSibling);
NS_ASSERTION(NS_SUCCEEDED(rv), "Must be a DOM Node");
} else {
*aPrevSibling = nsnull;
}
PRInt32 pos = parent->IndexOf(this);
nsIContent *sibling = parent->GetChildAt(pos - 1);
return rv;
return sibling ? CallQueryInterface(sibling, aPrevSibling) : NS_OK;
}
nsresult
nsGenericDOMDataNode::GetNextSibling(nsIDOMNode** aNextSibling)
{
nsresult rv = NS_OK;
*aNextSibling = nsnull;
nsIContent *sibling = nsnull;
nsIContent *parent = GetParent();
if (parent) {
PRInt32 pos = parent->IndexOf(this);
if (pos > -1) {
sibling = parent->GetChildAt(pos + 1);
}
}
else {
nsIDocument *doc = GetCurrentDoc();
if (doc) {
PRInt32 pos = doc->IndexOf(this);
if (pos > -1) {
sibling = doc->GetChildAt(pos + 1);
}
}
nsINode *parent = GetNodeParent();
if (!parent) {
return NS_OK;
}
if (sibling) {
rv = CallQueryInterface(sibling, aNextSibling);
NS_ASSERTION(NS_SUCCEEDED(rv), "Must be a DOM Node");
} else {
*aNextSibling = nsnull;
}
PRInt32 pos = parent->IndexOf(this);
nsIContent *sibling = parent->GetChildAt(pos + 1);
return rv;
return sibling ? CallQueryInterface(sibling, aNextSibling) : NS_OK;
}
nsresult
@ -622,15 +576,16 @@ nsGenericDOMDataNode::GetSCCIndex()
{
// This is an optimized way of walking nsIDOMNode::GetParentNode to
// the top of the tree.
nsIDOMGCParticipant *result = GetCurrentDoc();
if (!result) {
nsIContent *top = this;
while (top->GetParent())
top = top->GetParent();
result = top;
nsINode *top = GetCurrentDoc();
if (!top) {
top = this;
nsINode *parent;
while ((parent = top->GetNodeParent())) {
top = parent;
}
}
return result;
return top;
}
void

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

@ -310,25 +310,15 @@ nsIContent::SetNativeAnonymous(PRBool aAnonymous)
//----------------------------------------------------------------------
nsChildContentList::nsChildContentList(nsIContent *aContent)
{
// This reference is not reference-counted. The content
// object tells us when its about to go away.
mContent = aContent;
}
nsChildContentList::~nsChildContentList()
{
MOZ_COUNT_DTOR(nsChildContentList);
}
NS_IMETHODIMP
nsChildContentList::GetLength(PRUint32* aLength)
{
if (mContent) {
*aLength = mContent->GetChildCount();
} else {
*aLength = 0;
}
*aLength = mNode ? mNode->GetChildCount() : 0;
return NS_OK;
}
@ -336,8 +326,8 @@ nsChildContentList::GetLength(PRUint32* aLength)
NS_IMETHODIMP
nsChildContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
if (mContent) {
nsIContent *content = mContent->GetChildAt(aIndex);
if (mNode) {
nsIContent *content = mNode->GetChildAt(aIndex);
if (content) {
return CallQueryInterface(content, aReturn);
}
@ -348,11 +338,7 @@ nsChildContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
return NS_OK;
}
void
nsChildContentList::DropReference()
{
mContent = nsnull;
}
//----------------------------------------------------------------------
NS_INTERFACE_MAP_BEGIN(nsNode3Tearoff)
NS_INTERFACE_MAP_ENTRY(nsIDOM3Node)
@ -912,15 +898,16 @@ nsGenericElement::GetSCCIndex()
{
// This is an optimized way of walking nsIDOMNode::GetParentNode to
// the top of the tree.
nsIDOMGCParticipant *result = GetCurrentDoc();
if (!result) {
nsIContent *top = this;
while (top->GetParent())
top = top->GetParent();
result = top;
nsINode *top = GetCurrentDoc();
if (!top) {
top = this;
nsINode *parent;
while ((parent = top->GetNodeParent())) {
top = parent;
}
}
return result;
return top;
}
void
@ -977,14 +964,10 @@ nsGenericElement::GetNodeType(PRUint16* aNodeType)
NS_IMETHODIMP
nsGenericElement::GetParentNode(nsIDOMNode** aParentNode)
{
nsINode *parent = GetNodeParent();
if (parent) {
return CallQueryInterface(parent, aParentNode);
}
*aParentNode = nsnull;
nsINode *parent = GetNodeParent();
return NS_OK;
return parent ? CallQueryInterface(parent, aParentNode) : NS_OK;
}
NS_IMETHODIMP
@ -992,33 +975,15 @@ nsGenericElement::GetPreviousSibling(nsIDOMNode** aPrevSibling)
{
*aPrevSibling = nsnull;
nsIContent *sibling = nsnull;
nsresult rv = NS_OK;
nsIContent *parent = GetParent();
if (parent) {
PRInt32 pos = parent->IndexOf(this);
if (pos > 0 ) {
sibling = parent->GetChildAt(pos - 1);
}
} else {
nsIDocument* document = GetCurrentDoc();
if (document) {
// Nodes that are just below the document (their parent is the
// document) need to go to the document to find their next sibling.
PRInt32 pos = document->IndexOf(this);
if (pos > 0 ) {
sibling = document->GetChildAt(pos - 1);
}
}
nsINode *parent = GetNodeParent();
if (!parent) {
return NS_OK;
}
if (sibling) {
rv = CallQueryInterface(sibling, aPrevSibling);
NS_ASSERTION(*aPrevSibling, "Must be a DOM Node");
}
PRInt32 pos = parent->IndexOf(this);
nsIContent *sibling = parent->GetChildAt(pos - 1);
return rv;
return sibling ? CallQueryInterface(sibling, aPrevSibling) : NS_OK;
}
NS_IMETHODIMP
@ -1026,33 +991,15 @@ nsGenericElement::GetNextSibling(nsIDOMNode** aNextSibling)
{
*aNextSibling = nsnull;
nsIContent *sibling = nsnull;
nsresult rv = NS_OK;
nsIContent *parent = GetParent();
if (parent) {
PRInt32 pos = parent->IndexOf(this);
if (pos > -1 ) {
sibling = parent->GetChildAt(pos + 1);
}
} else {
nsIDocument* document = GetCurrentDoc();
if (document) {
// Nodes that are just below the document (their parent is the
// document) need to go to the document to find their next sibling.
PRInt32 pos = document->IndexOf(this);
if (pos > -1 ) {
sibling = document->GetChildAt(pos + 1);
}
}
nsINode *parent = GetNodeParent();
if (!parent) {
return NS_OK;
}
if (sibling) {
rv = CallQueryInterface(sibling, aNextSibling);
NS_ASSERTION(*aNextSibling, "Must be a DOM Node");
}
PRInt32 pos = parent->IndexOf(this);
nsIContent *sibling = parent->GetChildAt(pos + 1);
return rv;
return sibling ? CallQueryInterface(sibling, aNextSibling) : NS_OK;
}
NS_IMETHODIMP
@ -2293,7 +2240,8 @@ nsGenericElement::doInsertChildAt(nsIContent* aKid, PRUint32 aIndex,
// really need to stop running them while we're in the middle of modifying
// the DOM....
if (aDocument && aKid->GetCurrentDoc() == aDocument &&
(!aParent || aKid->GetParent() == aParent)) {
(aParent ? aKid->GetNodeParent() == aParent :
aKid->GetNodeParent() == aDocument)) {
if (aNotify) {
// Note that we always want to call ContentInserted when things are added
// as kids to documents
@ -2925,7 +2873,7 @@ nsGenericElement::doReplaceOrInsertBefore(PRBool aReplace,
PRUint16 tmpType = 0;
tmpNode->GetNodeType(&tmpType);
if (childContent->GetParent() || childContent->IsInDoc() ||
if (childContent->GetNodeParent() ||
!IsAllowedAsChild(childContent, tmpType, aParent, aDocument, PR_FALSE,
refContent)) {
res = NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
@ -3007,7 +2955,7 @@ nsGenericElement::doReplaceOrInsertBefore(PRBool aReplace,
return NS_ERROR_DOM_NOT_FOUND_ERR;
}
if (newContent->GetParent() || newContent->IsInDoc() ||
if (newContent->GetNodeParent() ||
!IsAllowedAsChild(newContent, nodeType, aParent, aDocument, PR_FALSE,
refContent)) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;

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

@ -84,21 +84,24 @@ typedef unsigned long PtrBits;
class nsChildContentList : public nsGenericDOMNodeList
{
public:
/**
* @param aContent the content whose children will make up the list
*/
nsChildContentList(nsIContent *aContent);
nsChildContentList(nsINode* aNode)
: mNode(aNode)
{
MOZ_COUNT_CTOR(nsChildContentList);
}
virtual ~nsChildContentList();
// nsIDOMNodeList interface
NS_DECL_NSIDOMNODELIST
/** Drop the reference to the content */
void DropReference();
void DropReference()
{
mNode = nsnull;
}
private:
/** The content whose children make up the list (weak reference) */
nsIContent *mContent;
// The node whose children make up the list (weak reference)
nsINode* mNode;
};
/**

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

@ -44,8 +44,7 @@
#include "nsTreeWalker.h"
#include "nsIDOMNode.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMEntityReference.h"
#include "nsIDOMNodeFilter.h"
#include "nsDOMError.h"
#include "nsIContent.h"
@ -54,6 +53,7 @@
#include "nsContentUtils.h"
#include "nsMemory.h"
#include "nsCOMArray.h"
#include "nsGkAtoms.h"
/*
* Factories, constructors and destructors
@ -64,13 +64,14 @@ NS_NewTreeWalker(nsIDOMNode *aRoot,
PRUint32 aWhatToShow,
nsIDOMNodeFilter *aFilter,
PRBool aEntityReferenceExpansion,
nsIDOMTreeWalker **aInstancePtrResult) {
nsIDOMTreeWalker **aInstancePtrResult)
{
NS_ENSURE_ARG_POINTER(aInstancePtrResult);
NS_ENSURE_TRUE(aRoot, NS_ERROR_DOM_NOT_SUPPORTED_ERR);
nsCOMPtr<nsINode> root = do_QueryInterface(aRoot);
NS_ENSURE_TRUE(root, NS_ERROR_DOM_NOT_SUPPORTED_ERR);
nsTreeWalker* walker = new nsTreeWalker(aRoot,
nsTreeWalker* walker = new nsTreeWalker(root,
aWhatToShow,
aFilter,
aEntityReferenceExpansion);
@ -79,7 +80,7 @@ NS_NewTreeWalker(nsIDOMNode *aRoot,
return CallQueryInterface(walker, aInstancePtrResult);
}
nsTreeWalker::nsTreeWalker(nsIDOMNode *aRoot,
nsTreeWalker::nsTreeWalker(nsINode *aRoot,
PRUint32 aWhatToShow,
nsIDOMNodeFilter *aFilter,
PRBool aExpandEntityReferences) :
@ -121,9 +122,12 @@ NS_IMPL_RELEASE(nsTreeWalker)
/* readonly attribute nsIDOMNode root; */
NS_IMETHODIMP nsTreeWalker::GetRoot(nsIDOMNode * *aRoot)
{
NS_ENSURE_ARG_POINTER(aRoot);
*aRoot = mRoot;
NS_ADDREF(*aRoot);
if (mRoot) {
return CallQueryInterface(mRoot, aRoot);
}
*aRoot = nsnull;
return NS_OK;
}
@ -156,20 +160,25 @@ nsTreeWalker::GetExpandEntityReferences(PRBool *aExpandEntityReferences)
/* attribute nsIDOMNode currentNode; */
NS_IMETHODIMP nsTreeWalker::GetCurrentNode(nsIDOMNode * *aCurrentNode)
{
NS_ENSURE_ARG_POINTER(aCurrentNode);
*aCurrentNode = mCurrentNode;
NS_ADDREF(*aCurrentNode);
if (mCurrentNode) {
CallQueryInterface(mCurrentNode, aCurrentNode);
}
*aCurrentNode = nsnull;
return NS_OK;
}
NS_IMETHODIMP nsTreeWalker::SetCurrentNode(nsIDOMNode * aCurrentNode)
{
NS_ENSURE_TRUE(aCurrentNode, NS_ERROR_DOM_NOT_SUPPORTED_ERR);
nsresult rv = nsContentUtils::CheckSameOrigin(mRoot, aCurrentNode);
if(NS_FAILED(rv))
return rv;
// This QI is dumb, but this shouldn't be a critical operation
nsCOMPtr<nsIDOMNode> domRoot = do_QueryInterface(mRoot);
nsresult rv = nsContentUtils::CheckSameOrigin(domRoot, aCurrentNode);
NS_ENSURE_SUCCESS(rv, rv);
mCurrentNode = do_QueryInterface(aCurrentNode);
mCurrentNode = aCurrentNode;
return NS_OK;
}
@ -180,17 +189,15 @@ NS_IMETHODIMP nsTreeWalker::SetCurrentNode(nsIDOMNode * aCurrentNode)
/* nsIDOMNode parentNode (); */
NS_IMETHODIMP nsTreeWalker::ParentNode(nsIDOMNode **_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
*_retval = nsnull;
nsCOMPtr<nsIDOMNode> node(mCurrentNode);
nsresult rv;
PRInt32 indexPos = mPossibleIndexesPos;
nsCOMPtr<nsINode> node = mCurrentNode;
while (node && node != mRoot) {
nsCOMPtr<nsIDOMNode> tmp(node);
rv = tmp->GetParentNode(getter_AddRefs(node));
NS_ENSURE_SUCCESS(rv, rv);
node = node->GetNodeParent();
indexPos--;
@ -201,76 +208,103 @@ NS_IMETHODIMP nsTreeWalker::ParentNode(nsIDOMNode **_retval)
if (filtered == nsIDOMNodeFilter::FILTER_ACCEPT) {
mCurrentNode = node;
mPossibleIndexesPos = indexPos >= 0 ? indexPos : -1;
*_retval = node;
NS_ADDREF(*_retval);
return NS_OK;
return CallQueryInterface(node, _retval);
}
}
}
*_retval = nsnull;
return NS_OK;
}
/* nsIDOMNode firstChild (); */
NS_IMETHODIMP nsTreeWalker::FirstChild(nsIDOMNode **_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
return FirstChildOf(mCurrentNode,
PR_FALSE,
mPossibleIndexesPos+1,
_retval);
*_retval = nsnull;
nsCOMPtr<nsINode> result;
nsresult rv = FirstChildOf(mCurrentNode,
PR_FALSE,
mPossibleIndexesPos + 1,
getter_AddRefs(result));
NS_ENSURE_SUCCESS(rv, rv);
return result ? CallQueryInterface(result, _retval) : NS_OK;
}
/* nsIDOMNode lastChild (); */
NS_IMETHODIMP nsTreeWalker::LastChild(nsIDOMNode **_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
return FirstChildOf(mCurrentNode,
PR_TRUE,
mPossibleIndexesPos+1,
_retval);
*_retval = nsnull;
nsCOMPtr<nsINode> result;
nsresult rv = FirstChildOf(mCurrentNode,
PR_TRUE,
mPossibleIndexesPos + 1,
getter_AddRefs(result));
NS_ENSURE_SUCCESS(rv, rv);
return result ? CallQueryInterface(result, _retval) : NS_OK;
}
/* nsIDOMNode previousSibling (); */
NS_IMETHODIMP nsTreeWalker::PreviousSibling(nsIDOMNode **_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
return NextSiblingOf(mCurrentNode,
PR_TRUE,
mPossibleIndexesPos,
_retval);
*_retval = nsnull;
nsCOMPtr<nsINode> result;
nsresult rv = NextSiblingOf(mCurrentNode,
PR_TRUE,
mPossibleIndexesPos,
getter_AddRefs(result));
NS_ENSURE_SUCCESS(rv, rv);
return result ? CallQueryInterface(result, _retval) : NS_OK;
}
/* nsIDOMNode nextSibling (); */
NS_IMETHODIMP nsTreeWalker::NextSibling(nsIDOMNode **_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
return NextSiblingOf(mCurrentNode,
PR_FALSE,
mPossibleIndexesPos,
_retval);
*_retval = nsnull;
nsCOMPtr<nsINode> result;
nsresult rv = NextSiblingOf(mCurrentNode,
PR_FALSE,
mPossibleIndexesPos,
getter_AddRefs(result));
NS_ENSURE_SUCCESS(rv, rv);
return result ? CallQueryInterface(result, _retval) : NS_OK;
}
/* nsIDOMNode previousNode (); */
NS_IMETHODIMP nsTreeWalker::PreviousNode(nsIDOMNode **_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
return NextInDocumentOrderOf(mCurrentNode,
PR_TRUE,
mPossibleIndexesPos,
_retval);
*_retval = nsnull;
nsCOMPtr<nsINode> result;
nsresult rv = NextInDocumentOrderOf(mCurrentNode,
PR_TRUE,
mPossibleIndexesPos,
getter_AddRefs(result));
NS_ENSURE_SUCCESS(rv, rv);
return result ? CallQueryInterface(result, _retval) : NS_OK;
}
/* nsIDOMNode nextNode (); */
NS_IMETHODIMP nsTreeWalker::NextNode(nsIDOMNode **_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
return NextInDocumentOrderOf(mCurrentNode,
PR_FALSE,
mPossibleIndexesPos,
_retval);
*_retval = nsnull;
nsCOMPtr<nsINode> result;
nsresult rv = NextInDocumentOrderOf(mCurrentNode,
PR_FALSE,
mPossibleIndexesPos,
getter_AddRefs(result));
NS_ENSURE_SUCCESS(rv, rv);
return result ? CallQueryInterface(result, _retval) : NS_OK;
}
/*
@ -311,37 +345,13 @@ nsTreeWalker::AppendReachableList(nsCOMArray<nsIDOMGCParticipant>& aArray)
* @returns Errorcode
*/
nsresult
nsTreeWalker::FirstChildOf(nsIDOMNode* aNode,
nsTreeWalker::FirstChildOf(nsINode* aNode,
PRBool aReversed,
PRInt32 aIndexPos,
nsIDOMNode** _retval)
nsINode** _retval)
{
nsresult rv;
// Don't step into entity references if expandEntityReferences = false
if (!mExpandEntityReferences) {
nsCOMPtr<nsIDOMEntityReference> ent(do_QueryInterface(aNode));
if (ent) {
*_retval = nsnull;
return NS_OK;
}
}
nsCOMPtr<nsIDOMNodeList> childNodes;
PRInt32 start;
if (!aReversed) {
start = -1;
}
else {
rv = aNode->GetChildNodes(getter_AddRefs(childNodes));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(childNodes, NS_ERROR_UNEXPECTED);
rv = childNodes->GetLength((PRUint32*)&start);
NS_ENSURE_SUCCESS(rv, rv);
}
*_retval = nsnull;
PRInt32 start = aReversed ? (PRInt32)aNode->GetChildCount() : -1;
return ChildOf(aNode, start, aReversed, aIndexPos, _retval);
}
@ -357,13 +367,13 @@ nsTreeWalker::FirstChildOf(nsIDOMNode* aNode,
* @returns Errorcode
*/
nsresult
nsTreeWalker::NextSiblingOf(nsIDOMNode* aNode,
nsTreeWalker::NextSiblingOf(nsINode* aNode,
PRBool aReversed,
PRInt32 aIndexPos,
nsIDOMNode** _retval)
nsINode** _retval)
{
nsresult rv;
nsCOMPtr<nsIDOMNode> node(aNode);
nsCOMPtr<nsINode> node = aNode;
PRInt16 filtered;
PRInt32 childNum;
@ -373,20 +383,16 @@ nsTreeWalker::NextSiblingOf(nsIDOMNode* aNode,
}
while (1) {
nsCOMPtr<nsIDOMNode> parent;
// Get our index in the parent
rv = node->GetParentNode(getter_AddRefs(parent));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsINode> parent = node->GetNodeParent();
if (!parent)
break;
rv = IndexOf(parent, node, aIndexPos, &childNum);
NS_ENSURE_SUCCESS(rv, rv);
childNum = IndexOf(parent, node, aIndexPos);
NS_ENSURE_TRUE(childNum >= 0, NS_ERROR_UNEXPECTED);
// Search siblings
ChildOf(parent, childNum, aReversed, aIndexPos, _retval);
rv = ChildOf(parent, childNum, aReversed, aIndexPos, _retval);
NS_ENSURE_SUCCESS(rv, rv);
if (*_retval)
@ -421,10 +427,10 @@ nsTreeWalker::NextSiblingOf(nsIDOMNode* aNode,
* @returns Errorcode
*/
nsresult
nsTreeWalker::NextInDocumentOrderOf(nsIDOMNode* aNode,
nsTreeWalker::NextInDocumentOrderOf(nsINode* aNode,
PRBool aReversed,
PRInt32 aIndexPos,
nsIDOMNode** _retval)
nsINode** _retval)
{
nsresult rv;
@ -441,35 +447,32 @@ nsTreeWalker::NextInDocumentOrderOf(nsIDOMNode* aNode,
return NS_OK;
}
nsCOMPtr<nsIDOMNode> node(aNode);
nsCOMPtr<nsIDOMNode> currentNodeBackup(mCurrentNode);
nsCOMPtr<nsINode> node = aNode;
nsCOMPtr<nsINode> currentNodeBackup = mCurrentNode;
PRInt16 filtered;
PRInt32 childNum;
while (1) {
nsCOMPtr<nsIDOMNode> parent;
// Get our index in the parent
rv = node->GetParentNode(getter_AddRefs(parent));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsINode> parent = node->GetNodeParent();
if (!parent)
break;
rv = IndexOf(parent, node, aIndexPos, &childNum);
NS_ENSURE_SUCCESS(rv, rv);
childNum = IndexOf(parent, node, aIndexPos);
NS_ENSURE_TRUE(childNum >= 0, NS_ERROR_UNEXPECTED);
// Search siblings
nsCOMPtr<nsIDOMNode> sibling;
ChildOf(parent, childNum, aReversed, aIndexPos, getter_AddRefs(sibling));
nsCOMPtr<nsINode> sibling;
rv = ChildOf(parent, childNum, aReversed, aIndexPos,
getter_AddRefs(sibling));
NS_ENSURE_SUCCESS(rv, rv);
if (sibling) {
if (aReversed) {
// in reversed walking we first test if there are
// any children. I don't like this piece of code :(
nsCOMPtr<nsIDOMNode> child(sibling);
while(child) {
nsCOMPtr<nsINode> child = sibling;
while (child) {
sibling = child;
rv = FirstChildOf(sibling,
PR_TRUE,
@ -528,37 +531,25 @@ nsTreeWalker::NextInDocumentOrderOf(nsIDOMNode* aNode,
* @returns Errorcode
*/
nsresult
nsTreeWalker::ChildOf(nsIDOMNode* aNode,
nsTreeWalker::ChildOf(nsINode* aNode,
PRInt32 childNum,
PRBool aReversed,
PRInt32 aIndexPos,
nsIDOMNode** _retval)
nsINode** _retval)
{
PRInt16 filtered;
nsresult rv;
nsCOMPtr<nsIDOMNodeList> childNodes;
rv = aNode->GetChildNodes(getter_AddRefs(childNodes));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(childNodes, NS_ERROR_UNEXPECTED);
PRInt32 dir, end;
if (!aReversed) {
dir = 1;
rv = childNodes->GetLength((PRUint32*)&end);
NS_ENSURE_SUCCESS(rv, rv);
}
else {
dir = -1;
end = -1;
}
PRInt32 dir = aReversed ? -1 : 1;
// Step through all children
PRInt32 i;
for (i = childNum+dir; i != end; i += dir) {
nsCOMPtr<nsIDOMNode> child;
rv = childNodes->Item(i, getter_AddRefs(child));
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 i = childNum;
while (1) {
i += dir;
nsCOMPtr<nsINode> child = aNode->GetChildAt(i);
if (!child) {
break;
}
rv = TestNode(child, &filtered);
NS_ENSURE_SUCCESS(rv, rv);
@ -606,24 +597,52 @@ nsTreeWalker::ChildOf(nsIDOMNode* aNode,
* @param _filtered Returned filtervalue. See nsIDOMNodeFilter.idl
* @returns Errorcode
*/
nsresult nsTreeWalker::TestNode(nsIDOMNode* aNode, PRInt16* _filtered)
nsresult nsTreeWalker::TestNode(nsINode* aNode, PRInt16* _filtered)
{
nsresult rv;
PRUint16 nodeType;
PRUint32 mask = 1;
rv = aNode->GetNodeType(&nodeType);
NS_ENSURE_SUCCESS(rv, rv);
*_filtered = nsIDOMNodeFilter::FILTER_SKIP;
if (nodeType <= 12 && !((mask << (nodeType-1)) & mWhatToShow)) {
*_filtered = nsIDOMNodeFilter::FILTER_SKIP;
PRUint16 nodeType = 0;
// Check the most common cases
if (aNode->IsNodeOfType(nsINode::eELEMENT)) {
nodeType = nsIDOMNode::ELEMENT_NODE;
}
else if (aNode->IsNodeOfType(nsINode::eCONTENT)) {
nsIAtom* tag = NS_STATIC_CAST(nsIContent*, aNode)->Tag();
if (tag == nsGkAtoms::textTagName) {
nodeType = nsIDOMNode::TEXT_NODE;
}
else if (tag == nsGkAtoms::cdataTagName) {
nodeType = nsIDOMNode::CDATA_SECTION_NODE;
}
else if (tag == nsGkAtoms::commentTagName) {
nodeType = nsIDOMNode::COMMENT_NODE;
}
else if (tag == nsGkAtoms::processingInstructionTagName) {
nodeType = nsIDOMNode::PROCESSING_INSTRUCTION_NODE;
}
}
nsCOMPtr<nsIDOMNode> domNode;
if (!nodeType) {
domNode = do_QueryInterface(aNode);
rv = domNode->GetNodeType(&nodeType);
NS_ENSURE_SUCCESS(rv, rv);
}
if (nodeType <= 12 && !((1 << (nodeType-1)) & mWhatToShow)) {
return NS_OK;
}
nsCOMPtr<nsIDOMNodeFilter> filter = mFilter.Get();
if (filter)
return filter->AcceptNode(aNode, _filtered);
if (filter) {
if (!domNode) {
domNode = do_QueryInterface(aNode);
}
return filter->AcceptNode(domNode, _filtered);
}
*_filtered = nsIDOMNodeFilter::FILTER_ACCEPT;
return NS_OK;
@ -637,91 +656,19 @@ nsresult nsTreeWalker::TestNode(nsIDOMNode* aNode, PRInt16* _filtered)
* @param aChild node to get the index of
* @param aIndexPos position in mPossibleIndexes that contains the possible.
* index
* @param _childNum returned index
* @returns Errorcode
* @returns resulting index
*/
nsresult nsTreeWalker::IndexOf(nsIDOMNode* aParent,
nsIDOMNode* aChild,
PRInt32 aIndexPos,
PRInt32* _childNum)
PRInt32 nsTreeWalker::IndexOf(nsINode* aParent,
nsINode* aChild,
PRInt32 aIndexPos)
{
PRInt32 possibleIndex = -1;
if (aIndexPos >= 0)
possibleIndex = NS_PTR_TO_INT32(mPossibleIndexes[aIndexPos]);
nsCOMPtr<nsIContent> contParent(do_QueryInterface(aParent));
if (contParent) {
nsCOMPtr<nsIContent> child(do_QueryInterface(aChild));
if (possibleIndex >= 0) {
if (child == contParent->GetChildAt(possibleIndex)) {
*_childNum = possibleIndex;
return NS_OK;
}
}
*_childNum = contParent->IndexOf(child);
return *_childNum >= 0 ? NS_OK : NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIDocument> docParent(do_QueryInterface(aParent));
if (docParent) {
nsCOMPtr<nsIContent> child(do_QueryInterface(aChild));
if (possibleIndex >= 0) {
if (child == docParent->GetChildAt(possibleIndex)) {
*_childNum = possibleIndex;
return NS_OK;
}
}
*_childNum = docParent->IndexOf(child);
return *_childNum >= 0 ? NS_OK : NS_ERROR_UNEXPECTED;
}
nsresult rv;
PRUint32 i, len;
nsCOMPtr<nsIDOMNodeList> childNodes;
rv = aParent->GetChildNodes(getter_AddRefs(childNodes));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(childNodes, NS_ERROR_UNEXPECTED);
if (possibleIndex >= 0) {
nsCOMPtr<nsIDOMNode> tmp;
childNodes->Item(possibleIndex, getter_AddRefs(tmp));
if (tmp == aChild) {
*_childNum = possibleIndex;
return NS_OK;
if (aIndexPos >= 0 && aIndexPos < mPossibleIndexes.Count()) {
PRInt32 possibleIndex =
NS_PTR_TO_INT32(mPossibleIndexes.FastElementAt(aIndexPos));
if (aChild == aParent->GetChildAt(possibleIndex)) {
return possibleIndex;
}
}
rv = childNodes->GetLength(&len);
NS_ENSURE_SUCCESS(rv, rv);
for (i = 0; i < len; ++i) {
nsCOMPtr<nsIDOMNode> node;
rv = childNodes->Item(i, getter_AddRefs(node));
NS_ENSURE_SUCCESS(rv, rv);
if (node == aChild) {
*_childNum = i;
return NS_OK;
}
}
return NS_ERROR_UNEXPECTED;
}
/*
* Sets the child index at the specified level. It doesn't matter if this
* fails since mPossibleIndexes should only be considered a hint
* @param aIndexPos position in mPossibleIndexes to set
* @param aChildIndex child index at specified position
*/
void nsTreeWalker::SetChildIndex(PRInt32 aIndexPos, PRInt32 aChildIndex)
{
mPossibleIndexes.ReplaceElementAt(NS_INT32_TO_PTR(aChildIndex), aIndexPos);
return aParent->IndexOf(aChild);
}

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

@ -44,14 +44,16 @@
#ifndef nsTreeWalker_h___
#define nsTreeWalker_h___
#include "nsIDOMNode.h"
#include "nsIDOMTreeWalker.h"
#include "nsIDOMNodeFilter.h"
#include "nsCOMPtr.h"
#include "nsVoidArray.h"
#include "nsIDOMGCParticipant.h"
#include "nsJSUtils.h"
class nsINode;
class nsIDOMNode;
class nsIDOMNodeFilter;
class nsTreeWalker : public nsIDOMTreeWalker, public nsIDOMGCParticipant
{
public:
@ -62,18 +64,18 @@ public:
virtual nsIDOMGCParticipant* GetSCCIndex();
virtual void AppendReachableList(nsCOMArray<nsIDOMGCParticipant>& aArray);
nsTreeWalker(nsIDOMNode *aRoot,
nsTreeWalker(nsINode *aRoot,
PRUint32 aWhatToShow,
nsIDOMNodeFilter *aFilter,
PRBool aExpandEntityReferences);
virtual ~nsTreeWalker();
/* additional members */
private:
nsCOMPtr<nsIDOMNode> mRoot;
nsCOMPtr<nsINode> mRoot;
PRUint32 mWhatToShow;
nsMarkedJSFunctionHolder<nsIDOMNodeFilter> mFilter;
PRBool mExpandEntityReferences;
nsCOMPtr<nsIDOMNode> mCurrentNode;
nsCOMPtr<nsINode> mCurrentNode;
/*
* Array with all child indexes up the tree. This should only be
@ -97,10 +99,10 @@ private:
* @param _retval Returned node. Null if no child is found
* @returns Errorcode
*/
nsresult FirstChildOf(nsIDOMNode* aNode,
nsresult FirstChildOf(nsINode* aNode,
PRBool aReversed,
PRInt32 aIndexPos,
nsIDOMNode** _retval);
nsINode** _retval);
/*
* Finds the following sibling of aNode and returns it. If a sibling
@ -112,10 +114,10 @@ private:
* @param _retval Returned node. Null if no sibling is found
* @returns Errorcode
*/
nsresult NextSiblingOf(nsIDOMNode* aNode,
nsresult NextSiblingOf(nsINode* aNode,
PRBool aReversed,
PRInt32 aIndexPos,
nsIDOMNode** _retval);
nsINode** _retval);
/*
* Finds the next node in document order of aNode and returns it.
@ -127,10 +129,10 @@ private:
* @param _retval Returned node. Null if no node is found
* @returns Errorcode
*/
nsresult NextInDocumentOrderOf(nsIDOMNode* aNode,
nsresult NextInDocumentOrderOf(nsINode* aNode,
PRBool aReversed,
PRInt32 aIndexPos,
nsIDOMNode** _retval);
nsINode** _retval);
/*
* Finds the first child of aNode after child N and returns it. If a
@ -144,11 +146,11 @@ private:
* @param _retval Returned node. Null if no child is found
* @returns Errorcode
*/
nsresult ChildOf(nsIDOMNode* aNode,
nsresult ChildOf(nsINode* aNode,
PRInt32 childNum,
PRBool aReversed,
PRInt32 aIndexPos,
nsIDOMNode** _retval);
nsINode** _retval);
/*
* Tests if and how a node should be filtered. Uses mWhatToShow and
@ -157,7 +159,7 @@ private:
* @param _filtered Returned filtervalue. See nsIDOMNodeFilter.idl
* @returns Errorcode
*/
nsresult TestNode(nsIDOMNode* aNode, PRInt16* _filtered);
nsresult TestNode(nsINode* aNode, PRInt16* _filtered);
/*
* Gets the child index of a node within it's parent. Gets a possible index
@ -167,13 +169,11 @@ private:
* @param aChild node to get the index of
* @param aIndexPos position in mPossibleIndexes that contains the possible.
* index
* @param _childNum returned index
* @returns Errorcode
* @returns resulting index
*/
nsresult IndexOf(nsIDOMNode* aParent,
nsIDOMNode* aChild,
PRInt32 aIndexPos,
PRInt32* _childNum);
PRInt32 IndexOf(nsINode* aParent,
nsINode* aChild,
PRInt32 aIndexPos);
/*
* Sets the child index at the specified level. It doesn't matter if this
@ -181,8 +181,11 @@ private:
* @param aIndexPos position in mPossibleIndexes to set
* @param aChildIndex child index at specified position
*/
void SetChildIndex(PRInt32 aIndexPos, PRInt32 aChildIndex);
void SetChildIndex(PRInt32 aIndexPos, PRInt32 aChildIndex)
{
mPossibleIndexes.ReplaceElementAt(NS_INT32_TO_PTR(aChildIndex),
aIndexPos);
}
};
// Make a new nsIDOMTreeWalker object

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

@ -1369,9 +1369,9 @@ nsGenericHTMLElement::FindForm(nsIForm* aCurrentForm)
NS_ASSERTION(formCOMPtr, "aCurrentForm isn't an nsIContent?");
// Use an nsIContent temporary to reduce addref/releasing as we go up the
// tree
nsIContent* iter = formCOMPtr;
nsINode* iter = formCOMPtr;
do {
iter = iter->GetParent();
iter = iter->GetNodeParent();
if (iter == prevContent) {
nsIDOMHTMLFormElement* form;
CallQueryInterface(aCurrentForm, &form);
@ -3131,18 +3131,15 @@ nsGenericHTMLFormElement::BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsAString* aValue, PRBool aNotify)
{
if (aNameSpaceID == kNameSpaceID_None) {
nsCOMPtr<nsIFormControl> thisControl;
nsAutoString tmp;
QueryInterface(NS_GET_IID(nsIFormControl), getter_AddRefs(thisControl));
// remove the control from the hashtable as needed
if (mForm && (aName == nsHTMLAtoms::name || aName == nsHTMLAtoms::id)) {
GetAttr(kNameSpaceID_None, aName, tmp);
if (!tmp.IsEmpty()) {
mForm->RemoveElementFromTable(thisControl, tmp);
mForm->RemoveElementFromTable(this, tmp);
}
}
@ -3150,16 +3147,16 @@ nsGenericHTMLFormElement::BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, tmp);
if (!tmp.IsEmpty()) {
mForm->RemoveElementFromTable(thisControl, tmp);
mForm->RemoveElementFromTable(this, tmp);
}
GetAttr(kNameSpaceID_None, nsHTMLAtoms::id, tmp);
if (!tmp.IsEmpty()) {
mForm->RemoveElementFromTable(thisControl, tmp);
mForm->RemoveElementFromTable(this, tmp);
}
mForm->RemoveElement(thisControl);
mForm->RemoveElement(this);
}
}
@ -3172,15 +3169,12 @@ nsGenericHTMLFormElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsAString* aValue, PRBool aNotify)
{
if (aNameSpaceID == kNameSpaceID_None) {
nsCOMPtr<nsIFormControl> thisControl =
do_QueryInterface(NS_STATIC_CAST(nsIContent*, this));
// add the control to the hashtable as needed
if (mForm && (aName == nsHTMLAtoms::name || aName == nsHTMLAtoms::id) &&
aValue) {
if (!aValue->IsEmpty()) {
mForm->AddElementToTable(thisControl, *aValue);
mForm->AddElementToTable(this, *aValue);
}
}
@ -3190,16 +3184,16 @@ nsGenericHTMLFormElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, tmp);
if (!tmp.IsEmpty()) {
mForm->AddElementToTable(thisControl, tmp);
mForm->AddElementToTable(this, tmp);
}
GetAttr(kNameSpaceID_None, nsHTMLAtoms::id, tmp);
if (!tmp.IsEmpty()) {
mForm->AddElementToTable(thisControl, tmp);
mForm->AddElementToTable(this, tmp);
}
mForm->AddElement(thisControl);
mForm->AddElement(this);
}
// And notify on content state changes, if any

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

@ -60,6 +60,7 @@
#include "nsHTMLAtoms.h"
#include "nsITextContent.h"
#include "nsIStreamListener.h"
#include "nsGenericDOMNodeList.h"
#include "nsXBLBinding.h"
#include "nsXBLPrototypeBinding.h"