зеркало из https://github.com/mozilla/gecko-dev.git
Fix for bug #176251 (Problems with nsContentIterator PRE traversal)
content/base/public/nsIContentIterator.h content/base/src/nsContentIterator.cpp content/base/src/nsGeneratedIterator.cpp content/build/nsContentCID.h content/build/nsContentModule.cpp embedding/components/find/src/nsFind.cpp layout/html/style/src/nsFrameContentIterator.cpp - Removed MakePre() and MakePost() from the nsIContentIterator interface. - Traversal must now be specified at time of creation. - Fixed nsContentIterator Init() methods so that they correctly calculate mFirst and mLast. - Modified PositionAt() to check if the node is in the traversal range. r=jfrancis@netscape.com sr=sfraser@netscape.com
This commit is contained in:
Родитель
b3ecf37dd5
Коммит
5d19412ecc
|
@ -172,6 +172,10 @@
|
|||
{/* {a6cf90e3-15b3-11d2-932e-00805f8add32}*/ \
|
||||
0xa6cf90e3, 0x15b3, 0x11d2, {0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32 } }
|
||||
|
||||
#define NS_PRECONTENTITERATOR_CID \
|
||||
{/* {80D7E247-D4B8-45d7-BB59-6F1DD56F384C} */ \
|
||||
0x80d7e247, 0xd4b8, 0x45d7, { 0xbb, 0x59, 0x6f, 0x1d, 0xd5, 0x6f, 0x38, 0x4c } }
|
||||
|
||||
#define NS_GENERATEDSUBTREEITERATOR_CID \
|
||||
{/* {9A45253B-EB8F-49f1-B925-E9EA90D3EB3A}*/ \
|
||||
0x9a45253b, 0xeb8f, 0x49f1, { 0xb9, 0x25, 0xe9, 0xea, 0x90, 0xd3, 0xeb, 0x3a } }
|
||||
|
|
|
@ -99,15 +99,6 @@ public:
|
|||
/** PositionAt will position the iterator to the supplied node
|
||||
*/
|
||||
NS_IMETHOD PositionAt(nsIContent* aCurNode)=0;
|
||||
|
||||
/** MakePre will make the iterator a pre-order iterator
|
||||
*/
|
||||
NS_IMETHOD MakePre()=0;
|
||||
|
||||
/** MakePost will make the iterator a post-order iterator
|
||||
*/
|
||||
NS_IMETHOD MakePost()=0;
|
||||
|
||||
};
|
||||
|
||||
class nsIPresShell;
|
||||
|
|
|
@ -108,6 +108,72 @@ GetChildAt(nsIDOMNode *aParent, PRInt32 aOffset)
|
|||
return resultNode;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ContentHasChildren: returns true if the content has children
|
||||
//
|
||||
static PRBool
|
||||
ContentHasChildren(nsIContent *aContent)
|
||||
{
|
||||
PRInt32 numChildren = 0;
|
||||
aContent->ChildCount(numChildren);
|
||||
return numChildren != 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ContentToParentOffset: returns the content node's parent and offset.
|
||||
//
|
||||
static void
|
||||
ContentToParentOffset(nsIContent *aContent, nsIDOMNode **aParent, PRInt32 *aOffset)
|
||||
{
|
||||
if (!aParent || !aOffset)
|
||||
return;
|
||||
|
||||
*aParent = nsnull;
|
||||
*aOffset = 0;
|
||||
|
||||
if (!aContent)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIContent> parent;
|
||||
nsresult rv = aContent->GetParent(*getter_AddRefs(parent));
|
||||
|
||||
if (NS_FAILED(rv) || !parent)
|
||||
return;
|
||||
|
||||
rv = parent->IndexOf(aContent, *aOffset);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
CallQueryInterface(parent, aParent);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ContentIsInTraversalRange: returns true if content is visited during
|
||||
// the traversal of the range in the specified mode.
|
||||
//
|
||||
static PRBool
|
||||
ContentIsInTraversalRange(nsIContent *aContent, PRBool aIsPreMode,
|
||||
nsIDOMNode *aStartNode, PRInt32 aStartOffset,
|
||||
nsIDOMNode *aEndNode, PRInt32 aEndOffset)
|
||||
{
|
||||
if (!aStartNode || !aEndNode || !aContent)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> parentNode;
|
||||
PRInt32 indx = 0;
|
||||
|
||||
ContentToParentOffset(aContent, getter_AddRefs(parentNode), &indx);
|
||||
|
||||
if (!parentNode)
|
||||
return PR_FALSE;
|
||||
|
||||
if (!aIsPreMode)
|
||||
++indx;
|
||||
|
||||
return (ComparePoints(aStartNode, aStartOffset, parentNode, indx) <= 0) &&
|
||||
(ComparePoints(aEndNode, aEndOffset, parentNode, indx) >= 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -142,11 +208,6 @@ public:
|
|||
|
||||
NS_IMETHOD PositionAt(nsIContent* aCurNode);
|
||||
|
||||
NS_IMETHOD MakePre();
|
||||
|
||||
NS_IMETHOD MakePost();
|
||||
|
||||
|
||||
// nsIEnumertor interface methods ------------------------------
|
||||
|
||||
//NS_IMETHOD CurrentItem(nsISupports **aItem);
|
||||
|
@ -204,6 +265,17 @@ private:
|
|||
};
|
||||
|
||||
|
||||
/*
|
||||
* A simple iterator class for traversing the content in "open tag" order
|
||||
*/
|
||||
|
||||
class nsPreContentIterator : public nsContentIterator
|
||||
{
|
||||
public:
|
||||
nsPreContentIterator() { mPre = PR_TRUE; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************
|
||||
* repository cruft
|
||||
|
@ -218,6 +290,15 @@ nsresult NS_NewContentIterator(nsIContentIterator** aInstancePtrResult)
|
|||
}
|
||||
|
||||
|
||||
nsresult NS_NewPreContentIterator(nsIContentIterator** aInstancePtrResult)
|
||||
{
|
||||
nsContentIterator * iter = new nsPreContentIterator();
|
||||
if (iter)
|
||||
return iter->QueryInterface(NS_GET_IID(nsIContentIterator), (void**) aInstancePtrResult);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************
|
||||
* XPCOM cruft
|
||||
******************************************************/
|
||||
|
@ -284,10 +365,21 @@ nsresult nsContentIterator::Init(nsIContent* aRoot)
|
|||
mIsDone = PR_FALSE;
|
||||
nsCOMPtr<nsIContent> root( do_QueryInterface(aRoot) );
|
||||
mIndexes.Clear();
|
||||
mFirst = GetDeepFirstChild(root, &mIndexes);
|
||||
mLast = root;
|
||||
|
||||
if (mPre)
|
||||
{
|
||||
mFirst = root;
|
||||
mLast = GetDeepLastChild(root, nsnull);
|
||||
}
|
||||
else
|
||||
{
|
||||
mFirst = GetDeepFirstChild(root, nsnull);
|
||||
mLast = root;
|
||||
}
|
||||
|
||||
mCommonParent = root;
|
||||
mCurNode = mFirst;
|
||||
RebuildIndexStack();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -298,7 +390,6 @@ nsresult nsContentIterator::Init(nsIDOMRange* aRange)
|
|||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> dN;
|
||||
nsCOMPtr<nsIContent> cChild;
|
||||
|
||||
nsCOMPtr<nsIContent> startCon;
|
||||
nsCOMPtr<nsIDOMNode> startDOM;
|
||||
|
@ -334,91 +425,152 @@ nsresult nsContentIterator::Init(nsIDOMRange* aRange)
|
|||
|
||||
aRange->GetEndOffset(&endIndx);
|
||||
|
||||
nsCOMPtr<nsIDOMCharacterData> cData(do_QueryInterface(startCon));
|
||||
|
||||
// short circuit when start node == end node
|
||||
if (startDOM == endDOM)
|
||||
{
|
||||
startCon->ChildAt(0,*getter_AddRefs(cChild));
|
||||
|
||||
if (!cChild) // no children, must be a text node or empty container
|
||||
{
|
||||
mFirst = startCon;
|
||||
mLast = startCon;
|
||||
mCurNode = startCon;
|
||||
RebuildIndexStack();
|
||||
return NS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (startIndx == endIndx) // collapsed range
|
||||
{
|
||||
MakeEmpty();
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// find first node in range
|
||||
startCon->ChildAt(0,*getter_AddRefs(cChild));
|
||||
|
||||
if (!cChild) // no children, must be a text node
|
||||
{
|
||||
mFirst = startCon;
|
||||
}
|
||||
else
|
||||
{
|
||||
startCon->ChildAt(startIndx,*getter_AddRefs(cChild));
|
||||
if (!cChild) // offset after last child, parent is first node
|
||||
{
|
||||
mFirst = startCon;
|
||||
}
|
||||
else
|
||||
{
|
||||
mFirst = GetDeepFirstChild(cChild, nsnull);
|
||||
}
|
||||
// Does that first node really intersect the range?
|
||||
// the range could be collapsed, or the range could be
|
||||
// 'degenerate', ie not collapsed but still containing
|
||||
// no content. In this case, we want the iterator to
|
||||
// be empty
|
||||
|
||||
if (!IsNodeIntersectsRange(mFirst, aRange))
|
||||
// Check to see if we have a collapsed range, if so,
|
||||
// there is nothing to iterate over.
|
||||
//
|
||||
// XXX: CharacterDataNodes (text nodes) are currently an exception,
|
||||
// since we always want to be able to iterate text nodes at
|
||||
// the end points of a range.
|
||||
|
||||
if (!cData && startIndx == endIndx)
|
||||
{
|
||||
MakeEmpty();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (cData)
|
||||
{
|
||||
// It's a textnode.
|
||||
|
||||
mFirst = startCon;
|
||||
mLast = startCon;
|
||||
mCurNode = startCon;
|
||||
|
||||
RebuildIndexStack();
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// find last node in range
|
||||
endCon->ChildAt(0,*getter_AddRefs(cChild));
|
||||
// Find first node in range.
|
||||
|
||||
nsCOMPtr<nsIContent> cChild;
|
||||
|
||||
if (!cData && ContentHasChildren(startCon))
|
||||
startCon->ChildAt(startIndx,*getter_AddRefs(cChild));
|
||||
|
||||
if (!cChild) // no children, must be a text node
|
||||
{
|
||||
mLast = endCon;
|
||||
}
|
||||
else if (endIndx == 0) // before first child, parent is last node
|
||||
{
|
||||
mLast = endCon;
|
||||
if (mPre)
|
||||
{
|
||||
// XXX: In the future, if start offset is after the last
|
||||
// character in the cdata node, should we set mFirst to
|
||||
// the next sibling?
|
||||
|
||||
if (!cData)
|
||||
{
|
||||
GetNextSibling(startCon, address_of(mFirst), nsnull);
|
||||
|
||||
// Does mFirst node really intersect the range?
|
||||
// The range could be 'degenerate', ie not collapsed
|
||||
// but still contain no content.
|
||||
|
||||
if (mFirst && !ContentIsInTraversalRange(mFirst, mPre, startDOM, startIndx, endDOM, endIndx))
|
||||
mFirst = nsnull;
|
||||
}
|
||||
else
|
||||
mFirst = startCon;
|
||||
}
|
||||
else // post-order
|
||||
mFirst = startCon;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (endIndx)
|
||||
endCon->ChildAt(--endIndx,*getter_AddRefs(cChild));
|
||||
|
||||
if (!cChild) // offset after last child, last child is last node
|
||||
if (mPre)
|
||||
mFirst = cChild;
|
||||
else // post-order
|
||||
{
|
||||
endCon->ChildCount(endIndx);
|
||||
endCon->ChildAt(--endIndx,*getter_AddRefs(cChild));
|
||||
if (!cChild)
|
||||
{
|
||||
NS_NOTREACHED("nsContentIterator::nsContentIterator");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mFirst = GetDeepFirstChild(cChild, nsnull);
|
||||
|
||||
// Does mFirst node really intersect the range?
|
||||
// The range could be 'degenerate', ie not collapsed
|
||||
// but still contain no content.
|
||||
|
||||
if (mFirst && !ContentIsInTraversalRange(mFirst, mPre, startDOM, startIndx, endDOM, endIndx))
|
||||
mFirst = nsnull;
|
||||
}
|
||||
mLast = cChild;
|
||||
}
|
||||
|
||||
|
||||
// Find last node in range.
|
||||
|
||||
cData = do_QueryInterface(endCon);
|
||||
|
||||
if (cData || !ContentHasChildren(endCon) || endIndx == 0)
|
||||
{
|
||||
if (mPre)
|
||||
mLast = endCon;
|
||||
else // post-order
|
||||
{
|
||||
// XXX: In the future, if end offset is before the first
|
||||
// character in the cdata node, should we set mLast to
|
||||
// the prev sibling?
|
||||
|
||||
if (!cData)
|
||||
{
|
||||
GetPrevSibling(endCon, address_of(mLast), nsnull);
|
||||
|
||||
if (!ContentIsInTraversalRange(mLast, mPre, startDOM, startIndx, endDOM, endIndx))
|
||||
mLast = nsnull;
|
||||
}
|
||||
else
|
||||
mLast = endCon;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PRInt32 indx = endIndx;
|
||||
|
||||
endCon->ChildAt(--indx, *getter_AddRefs(cChild));
|
||||
|
||||
if (!cChild) // No child at offset!
|
||||
{
|
||||
NS_NOTREACHED("nsContentIterator::nsContentIterator");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (mPre)
|
||||
{
|
||||
mLast = GetDeepLastChild(cChild, nsnull);
|
||||
|
||||
if (!ContentIsInTraversalRange(mLast, mPre, startDOM, startIndx, endDOM, endIndx))
|
||||
mLast = nsnull;
|
||||
}
|
||||
else // post-order
|
||||
mLast = cChild;
|
||||
}
|
||||
|
||||
// If either first or last is null, they both
|
||||
// have to be null!
|
||||
|
||||
if (!mFirst || !mLast)
|
||||
{
|
||||
mFirst = nsnull;
|
||||
mLast = nsnull;
|
||||
}
|
||||
|
||||
mCurNode = mFirst;
|
||||
RebuildIndexStack();
|
||||
mIsDone = !mCurNode;
|
||||
|
||||
if (!mCurNode)
|
||||
mIndexes.Clear();
|
||||
else
|
||||
RebuildIndexStack();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -455,11 +607,11 @@ nsresult nsContentIterator::RebuildIndexStack()
|
|||
void nsContentIterator::MakeEmpty()
|
||||
{
|
||||
nsCOMPtr<nsIContent> noNode;
|
||||
mCurNode = noNode;
|
||||
mFirst = noNode;
|
||||
mLast = noNode;
|
||||
mCurNode = noNode;
|
||||
mFirst = noNode;
|
||||
mLast = noNode;
|
||||
mCommonParent = noNode;
|
||||
mIsDone = PR_TRUE;
|
||||
mIsDone = PR_TRUE;
|
||||
mIndexes.Clear();
|
||||
}
|
||||
|
||||
|
@ -860,16 +1012,18 @@ nsresult nsContentIterator::PrevNode(nsCOMPtr<nsIContent> *ioNextNode, nsVoidArr
|
|||
|
||||
nsresult nsContentIterator::First()
|
||||
{
|
||||
if (!mFirst)
|
||||
if (!mFirst)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return PositionAt(mFirst);
|
||||
}
|
||||
|
||||
|
||||
nsresult nsContentIterator::Last()
|
||||
{
|
||||
if (!mLast)
|
||||
if (!mLast)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return PositionAt(mLast);
|
||||
}
|
||||
|
||||
|
@ -922,7 +1076,6 @@ nsresult nsContentIterator::PositionAt(nsIContent* aCurNode)
|
|||
nsCOMPtr<nsIContent> newCurNode;
|
||||
nsCOMPtr<nsIContent> tempNode(mCurNode);
|
||||
|
||||
// XXX need to confirm that aCurNode is within range
|
||||
if (!aCurNode)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
mCurNode = newCurNode = do_QueryInterface(aCurNode);
|
||||
|
@ -933,6 +1086,52 @@ nsresult nsContentIterator::PositionAt(nsIContent* aCurNode)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Check to see if the node falls within the traversal range.
|
||||
|
||||
nsCOMPtr<nsIDOMNode> firstNode(do_QueryInterface(mFirst));
|
||||
nsCOMPtr<nsIDOMNode> lastNode(do_QueryInterface(mLast));
|
||||
PRInt32 firstOffset=0, lastOffset=0;
|
||||
|
||||
if (firstNode && lastNode)
|
||||
{
|
||||
PRUint32 numChildren;
|
||||
|
||||
if (mPre)
|
||||
{
|
||||
ContentToParentOffset(mFirst, getter_AddRefs(firstNode), &firstOffset);
|
||||
|
||||
numChildren = GetNumChildren(lastNode);
|
||||
|
||||
if (numChildren)
|
||||
lastOffset = 0;
|
||||
else
|
||||
{
|
||||
ContentToParentOffset(mLast, getter_AddRefs(lastNode), &lastOffset);
|
||||
++lastOffset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
numChildren = GetNumChildren(firstNode);
|
||||
|
||||
if (numChildren)
|
||||
firstOffset = numChildren;
|
||||
else
|
||||
ContentToParentOffset(mFirst, getter_AddRefs(firstNode), &firstOffset);
|
||||
|
||||
ContentToParentOffset(mLast, getter_AddRefs(lastNode), &lastOffset);
|
||||
++lastOffset;
|
||||
}
|
||||
}
|
||||
|
||||
if (!firstNode || !lastNode ||
|
||||
!ContentIsInTraversalRange(mCurNode, mPre, firstNode, firstOffset,
|
||||
lastNode, lastOffset))
|
||||
{
|
||||
mIsDone = PR_TRUE;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// We can be at ANY node in the sequence.
|
||||
// Need to regenerate the array of indexes back to the root or common parent!
|
||||
nsCOMPtr<nsIContent> parent;
|
||||
|
@ -1017,21 +1216,6 @@ nsresult nsContentIterator::PositionAt(nsIContent* aCurNode)
|
|||
}
|
||||
|
||||
|
||||
nsresult nsContentIterator::MakePre()
|
||||
{
|
||||
// XXX need to confirm mCurNode is within range
|
||||
mPre = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsContentIterator::MakePost()
|
||||
{
|
||||
// XXX need to confirm mCurNode is within range
|
||||
mPre = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult nsContentIterator::CurrentNode(nsIContent **aNode)
|
||||
{
|
||||
if (!mCurNode)
|
||||
|
@ -1079,10 +1263,6 @@ public:
|
|||
|
||||
NS_IMETHOD PositionAt(nsIContent* aCurNode);
|
||||
|
||||
NS_IMETHOD MakePre();
|
||||
|
||||
NS_IMETHOD MakePost();
|
||||
|
||||
// Must override these because we don't do PositionAt
|
||||
NS_IMETHOD First();
|
||||
|
||||
|
@ -1420,16 +1600,6 @@ nsresult nsContentSubtreeIterator::PositionAt(nsIContent* aCurNode)
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult nsContentSubtreeIterator::MakePre()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult nsContentSubtreeIterator::MakePost()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* nsContentSubtreeIterator helper routines
|
||||
****************************************************************/
|
||||
|
|
|
@ -136,11 +136,6 @@ public:
|
|||
|
||||
NS_IMETHOD PositionAt(nsIContent* aCurNode);
|
||||
|
||||
NS_IMETHOD MakePre();
|
||||
|
||||
NS_IMETHOD MakePost();
|
||||
|
||||
|
||||
// nsIEnumertor interface methods ------------------------------
|
||||
|
||||
//NS_IMETHOD CurrentItem(nsISupports **aItem);
|
||||
|
@ -176,7 +171,6 @@ protected:
|
|||
nsIPresShell::GeneratedContentType mLastIterType;
|
||||
nsCOMPtr<nsIPresShell> mPresShell;
|
||||
PRBool mIsDone;
|
||||
PRBool mPre;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -249,7 +243,7 @@ nsresult nsGeneratedContentIterator::QueryInterface(const nsIID& aIID,
|
|||
|
||||
nsGeneratedContentIterator::nsGeneratedContentIterator() :
|
||||
// don't need to explicitly initialize |nsCOMPtr|s, they will automatically be NULL
|
||||
mIsDone(PR_FALSE), mPre(PR_FALSE)
|
||||
mIsDone(PR_FALSE)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
@ -653,11 +647,6 @@ nsresult nsGeneratedContentIterator::NextNode(nsCOMPtr<nsIContent> *ioNextNode)
|
|||
if (!ioNextNode)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (mPre) // if we are a Pre-order iterator, use pre-order
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
else // post-order*/
|
||||
if (mGenIter)
|
||||
{
|
||||
if (mGenIter->IsDone())
|
||||
|
@ -731,33 +720,25 @@ nsresult nsGeneratedContentIterator::PrevNode(nsCOMPtr<nsIContent> *ioNextNode)
|
|||
if (!ioNextNode)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (mPre) // if we are a Pre-order iterator, use pre-order
|
||||
nsCOMPtr<nsIContent> cN = *ioNextNode;
|
||||
nsCOMPtr<nsIContent> cLastChild;
|
||||
PRInt32 numChildren;
|
||||
|
||||
cN->ChildCount(numChildren);
|
||||
|
||||
// if it has children then prev node is last child
|
||||
if (numChildren)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (NS_FAILED(cN->ChildAt(--numChildren,*getter_AddRefs(cLastChild))))
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!cLastChild)
|
||||
return NS_ERROR_FAILURE;
|
||||
*ioNextNode = cLastChild;
|
||||
return NS_OK;
|
||||
}
|
||||
else // post-order
|
||||
{
|
||||
nsCOMPtr<nsIContent> cN = *ioNextNode;
|
||||
nsCOMPtr<nsIContent> cLastChild;
|
||||
PRInt32 numChildren;
|
||||
|
||||
cN->ChildCount(numChildren);
|
||||
|
||||
// if it has children then prev node is last child
|
||||
if (numChildren)
|
||||
{
|
||||
if (NS_FAILED(cN->ChildAt(--numChildren,*getter_AddRefs(cLastChild))))
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!cLastChild)
|
||||
return NS_ERROR_FAILURE;
|
||||
*ioNextNode = cLastChild;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// else prev sibling is previous
|
||||
return GetPrevSibling(cN, ioNextNode);
|
||||
}
|
||||
return NS_OK;
|
||||
// else prev sibling is previous
|
||||
return GetPrevSibling(cN, ioNextNode);
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
|
@ -841,20 +822,6 @@ nsresult nsGeneratedContentIterator::PositionAt(nsIContent* aCurNode)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsGeneratedContentIterator::MakePre()
|
||||
{
|
||||
// XXX need to confirm mCurNode is within range
|
||||
mPre = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsGeneratedContentIterator::MakePost()
|
||||
{
|
||||
// XXX need to confirm mCurNode is within range
|
||||
mPre = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult nsGeneratedContentIterator::CurrentNode(nsIContent **aNode)
|
||||
{
|
||||
|
@ -900,10 +867,6 @@ public:
|
|||
|
||||
NS_IMETHOD PositionAt(nsIContent* aCurNode);
|
||||
|
||||
NS_IMETHOD MakePre();
|
||||
|
||||
NS_IMETHOD MakePost();
|
||||
|
||||
//nsIGeneratedContentIterator
|
||||
NS_IMETHOD Init(nsIPresShell *aShell, nsIDOMRange* aRange);
|
||||
NS_IMETHOD Init(nsIPresShell *aShell, nsIContent* aContent);
|
||||
|
@ -1246,16 +1209,6 @@ nsresult nsGeneratedSubtreeIterator::PositionAt(nsIContent* aCurNode)
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult nsGeneratedSubtreeIterator::MakePre()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult nsGeneratedSubtreeIterator::MakePost()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* nsGeneratedSubtreeIterator helper routines
|
||||
****************************************************************/
|
||||
|
|
|
@ -172,6 +172,10 @@
|
|||
{/* {a6cf90e3-15b3-11d2-932e-00805f8add32}*/ \
|
||||
0xa6cf90e3, 0x15b3, 0x11d2, {0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32 } }
|
||||
|
||||
#define NS_PRECONTENTITERATOR_CID \
|
||||
{/* {80D7E247-D4B8-45d7-BB59-6F1DD56F384C} */ \
|
||||
0x80d7e247, 0xd4b8, 0x45d7, { 0xbb, 0x59, 0x6f, 0x1d, 0xd5, 0x6f, 0x38, 0x4c } }
|
||||
|
||||
#define NS_GENERATEDSUBTREEITERATOR_CID \
|
||||
{/* {9A45253B-EB8F-49f1-B925-E9EA90D3EB3A}*/ \
|
||||
0x9a45253b, 0xeb8f, 0x49f1, { 0xb9, 0x25, 0xe9, 0xea, 0x90, 0xd3, 0xeb, 0x3a } }
|
||||
|
|
|
@ -280,6 +280,7 @@ extern nsresult NS_NewDocumentViewer(nsIDocumentViewer** aResult);
|
|||
extern nsresult NS_NewRange(nsIDOMRange** aResult);
|
||||
extern nsresult NS_NewRangeUtils(nsIRangeUtils** aResult);
|
||||
extern nsresult NS_NewContentIterator(nsIContentIterator** aResult);
|
||||
extern nsresult NS_NewPreContentIterator(nsIContentIterator** aResult);
|
||||
extern nsresult NS_NewGenRegularIterator(nsIContentIterator** aResult);
|
||||
extern nsresult NS_NewContentSubtreeIterator(nsIContentIterator** aResult);
|
||||
extern nsresult NS_NewGenSubtreeIterator(nsIContentIterator** aInstancePtrResult);
|
||||
|
@ -354,6 +355,7 @@ MAKE_CTOR(CreateSelection, nsIFrameSelection, NS_NewSel
|
|||
MAKE_CTOR(CreateRange, nsIDOMRange, NS_NewRange)
|
||||
MAKE_CTOR(CreateRangeUtils, nsIRangeUtils, NS_NewRangeUtils)
|
||||
MAKE_CTOR(CreateContentIterator, nsIContentIterator, NS_NewContentIterator)
|
||||
MAKE_CTOR(CreatePreContentIterator, nsIContentIterator, NS_NewPreContentIterator)
|
||||
MAKE_CTOR(CreateGeneratedContentIterator, nsIContentIterator, NS_NewGenRegularIterator)
|
||||
MAKE_CTOR(CreateGeneratedSubtreeIterator, nsIContentIterator, NS_NewGenSubtreeIterator)
|
||||
MAKE_CTOR(CreateSubtreeIterator, nsIContentIterator, NS_NewContentSubtreeIterator)
|
||||
|
@ -641,6 +643,11 @@ static const nsModuleComponentInfo gComponents[] = {
|
|||
nsnull,
|
||||
CreateContentIterator },
|
||||
|
||||
{ "Pre Content iterator",
|
||||
NS_PRECONTENTITERATOR_CID,
|
||||
nsnull,
|
||||
CreatePreContentIterator },
|
||||
|
||||
{ "Generated Content iterator",
|
||||
NS_GENERATEDCONTENTITERATOR_CID,
|
||||
nsnull,
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
#define CHAR_TO_UNICHAR(c) ((PRUnichar)(const unsigned char)c)
|
||||
|
||||
static NS_DEFINE_CID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
|
||||
static NS_DEFINE_CID(kCPreContentIteratorCID, NS_PRECONTENTITERATOR_CID);
|
||||
static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
|
||||
static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
|
||||
|
||||
|
@ -168,10 +169,27 @@ nsFind::InitIterator(nsIDOMRange* aSearchRange)
|
|||
nsresult rv;
|
||||
if (!mIterator)
|
||||
{
|
||||
rv = nsComponentManager::CreateInstance(kCContentIteratorCID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsIContentIterator),
|
||||
getter_AddRefs(mIterator));
|
||||
if (mFindBackward) {
|
||||
// Use post-order in the reverse case, so we get parents
|
||||
// before children in case we want to prevent descending
|
||||
// into a node.
|
||||
|
||||
rv = nsComponentManager::CreateInstance(kCContentIteratorCID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsIContentIterator),
|
||||
getter_AddRefs(mIterator));
|
||||
}
|
||||
else {
|
||||
// Use pre-order in the forward case, so we get parents
|
||||
// before children in case we want to prevent descending
|
||||
// into a node.
|
||||
|
||||
rv = nsComponentManager::CreateInstance(kCPreContentIteratorCID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsIContentIterator),
|
||||
getter_AddRefs(mIterator));
|
||||
}
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_ARG_POINTER(mIterator);
|
||||
}
|
||||
|
@ -184,16 +202,9 @@ nsFind::InitIterator(nsIDOMRange* aSearchRange)
|
|||
|
||||
mIterator->Init(aSearchRange);
|
||||
if (mFindBackward) {
|
||||
// Use post-order in the reverse case,
|
||||
// so we get parents before children,
|
||||
// in case we want to prevent descending into a node.
|
||||
mIterator->MakePost();
|
||||
mIterator->Last();
|
||||
}
|
||||
else {
|
||||
// Use pre-order in the forward case.
|
||||
// Pre order is currently broken (will skip nodes!), so don't use it.
|
||||
//mIterator->MakePre();
|
||||
mIterator->First();
|
||||
}
|
||||
return NS_OK;
|
||||
|
|
|
@ -46,9 +46,6 @@ public:
|
|||
NS_IMETHOD IsDone();
|
||||
NS_IMETHOD PositionAt(nsIContent* aCurNode);
|
||||
|
||||
NS_IMETHOD MakePre();
|
||||
NS_IMETHOD MakePost();
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIPresContext> mPresContext;
|
||||
nsIFrame* mParentFrame;
|
||||
|
@ -275,18 +272,6 @@ nsFrameContentIterator::PositionAt(nsIContent* aCurNode)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameContentIterator::MakePre()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameContentIterator::MakePost()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewFrameContentIterator(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
|
|
|
@ -46,9 +46,6 @@ public:
|
|||
NS_IMETHOD IsDone();
|
||||
NS_IMETHOD PositionAt(nsIContent* aCurNode);
|
||||
|
||||
NS_IMETHOD MakePre();
|
||||
NS_IMETHOD MakePost();
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIPresContext> mPresContext;
|
||||
nsIFrame* mParentFrame;
|
||||
|
@ -275,18 +272,6 @@ nsFrameContentIterator::PositionAt(nsIContent* aCurNode)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameContentIterator::MakePre()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameContentIterator::MakePost()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewFrameContentIterator(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
|
|
Загрузка…
Ссылка в новой задаче