diff --git a/mozilla/content/base/src/nsGeneratedIterator.cpp b/mozilla/content/base/src/nsGeneratedIterator.cpp index c02a34f10cd..8bb59e3b2c5 100644 --- a/mozilla/content/base/src/nsGeneratedIterator.cpp +++ b/mozilla/content/base/src/nsGeneratedIterator.cpp @@ -152,8 +152,11 @@ protected: nsCOMPtr mCommonParent; nsCOMPtr mFirstIter; + nsCOMPtr mLastIter; nsCOMPtr mGenIter; nsIPresShell::GeneratedContentType mIterType; + nsIPresShell::GeneratedContentType mFirstIterType; + nsIPresShell::GeneratedContentType mLastIterType; nsCOMPtr mPresShell; PRBool mIsDone; PRBool mPre; @@ -253,11 +256,13 @@ nsresult nsGeneratedContentIterator::Init(nsIContent* aRoot) nsCOMPtr root( do_QueryInterface(aRoot) ); mFirst = GetDeepFirstChild(root); if (mGenIter)//we have generated + { mFirstIter = mGenIter; + mFirstIterType = mIterType; + } mLast = root; mCommonParent = root; mCurNode = mFirst; - mIterType = nsIPresShell::Before; return NS_OK; } @@ -358,7 +363,10 @@ nsresult nsGeneratedContentIterator::Init(nsIDOMRange* aRange) { mFirst = GetDeepFirstChild(cChild); if (mGenIter) + { mFirstIter = mGenIter; + mFirstIterType = mIterType; + } } // Does that first node really intersect the range? // the range could be collapsed, or the range could be @@ -505,7 +513,6 @@ nsCOMPtr nsGeneratedContentIterator::GetDeepLastChild(nsCOMPtrLast(); - result = mGenIter->CurrentNode(getter_AddRefs(deepFirstChild)); mIterType = nsIPresShell::After; return cChild; } @@ -556,8 +563,8 @@ nsresult nsGeneratedContentIterator::GetNextSibling(nsCOMPtr aNode, if (NS_SUCCEEDED(result) && mGenIter) { //ok we have a generated iter all bets are off mGenIter->First(); - result = mGenIter->CurrentNode(getter_AddRefs(*aSibling)); - if (NS_SUCCEEDED(result) && *aSibling) + mIterType = nsIPresShell::After; + *aSibling = parent; return result; } #endif @@ -606,9 +613,9 @@ nsresult nsGeneratedContentIterator::GetPrevSibling(nsCOMPtr aNode, if (NS_SUCCEEDED(result) && mGenIter) { //ok we have a generated iter all bets are off mGenIter->Last(); - result = mGenIter->CurrentNode(getter_AddRefs(*aSibling)); - if (NS_SUCCEEDED(result) && *aSibling) - return result; + *aSibling = parent; + mIterType = nsIPresShell::Before; + return result; } else #endif @@ -629,27 +636,9 @@ nsresult nsGeneratedContentIterator::NextNode(nsCOMPtr *ioNextNode) if (!ioNextNode) return NS_ERROR_NULL_POINTER; -/* if (mPre) // if we are a Pre-order iterator, use pre-order + if (mPre) // if we are a Pre-order iterator, use pre-order { - nsCOMPtr cN = *ioNextNode; - nsCOMPtr cFirstChild; - PRInt32 numChildren; - - cN->ChildCount(numChildren); - - // if it has children then next node is first child - if (numChildren) - { - if (NS_FAILED(cN->ChildAt(0,*getter_AddRefs(cFirstChild)))) - return NS_ERROR_FAILURE; - if (!cFirstChild) - return NS_ERROR_FAILURE; - *ioNextNode = cFirstChild; - return NS_OK; - } - - // else next sibling is next - return GetNextSibling(cN, ioNextNode); + return NS_ERROR_NOT_IMPLEMENTED; } else // post-order*/ if (mGenIter) @@ -698,7 +687,6 @@ nsresult nsGeneratedContentIterator::NextNode(nsCOMPtr *ioNextNode) { mGenIter = 0; } -#if DO_AFTER else//check for after node. { nsresult result = NS_ERROR_FAILURE; @@ -708,12 +696,10 @@ nsresult nsGeneratedContentIterator::NextNode(nsCOMPtr *ioNextNode) { //ok we have a generated iter all bets are off mGenIter->First(); mIterType = nsIPresShell::After; - //*ioNextNode = parent; } else mGenIter = 0; } -#endif // else it's the parent *ioNextNode = parent; @@ -728,35 +714,11 @@ nsresult nsGeneratedContentIterator::PrevNode(nsCOMPtr *ioNextNode) if (!ioNextNode) return NS_ERROR_NULL_POINTER; - /* if (mPre) // if we are a Pre-order iterator, use pre-order { - nsCOMPtr cN = *ioNextNode; - nsCOMPtr cSibling; - nsCOMPtr parent; - PRInt32 indx; - - // get prev sibling if there is one - if (NS_FAILED(cN->GetParent(*getter_AddRefs(parent)))) - return NS_ERROR_FAILURE; - if (!parent || NS_FAILED(parent->IndexOf(cN, indx))) - { - // a little noise to catch some iterator usage bugs. - NS_NOTREACHED("nsGeneratedContentIterator::PrevNode() : no parent found"); - return NS_ERROR_FAILURE; - } - if (indx && NS_SUCCEEDED(parent->ChildAt(--indx,*getter_AddRefs(cSibling))) && cSibling) - { - // prev node is siblings "deep right" child - *ioNextNode = GetDeepLastChild(cSibling); - return NS_OK; - } - - // else it's the parent - *ioNextNode = parent; + return NS_ERROR_NOT_IMPLEMENTED; } else // post-order - */ { nsCOMPtr cN = *ioNextNode; nsCOMPtr cLastChild; @@ -790,8 +752,6 @@ nsresult nsGeneratedContentIterator::First() if (!mFirst) return NS_ERROR_FAILURE; mIsDone = PR_FALSE; - if (mFirst == mCurNode) - return NS_OK; mCurNode = mFirst; mGenIter = mFirstIter; if (mGenIter)//set directionback to before... @@ -805,10 +765,8 @@ nsresult nsGeneratedContentIterator::Last() if (!mLast) return NS_ERROR_FAILURE; mIsDone = PR_FALSE; - if (mLast == mCurNode) - return NS_OK; + mGenIter = mLastIter; mCurNode = mLast; - mGenIter = 0; return NS_OK; } @@ -940,7 +898,6 @@ protected: // no copy's or assigns FIX ME nsGeneratedSubtreeIterator(const nsGeneratedSubtreeIterator&); nsGeneratedSubtreeIterator& operator=(const nsGeneratedSubtreeIterator&); - nsCOMPtr mPresShell; nsCOMPtr mRange; }; @@ -1079,15 +1036,26 @@ nsresult nsGeneratedSubtreeIterator::Init(nsIDOMRange* aRange) return NS_OK; } } - - firstCandidate = GetDeepFirstChild(firstCandidate); - + if (mGenIter) + { + mFirstIter = mGenIter; + mFirstIterType = mIterType; + } + if (!mFirstIter) + { + firstCandidate = GetDeepFirstChild(firstCandidate); + if (mGenIter) + { + mFirstIter = mGenIter; + mFirstIterType = mIterType; + } + } // confirm that this first possible contained node // is indeed contained. Else we have a range that // does not fully contain any node. - PRBool nodeBefore, nodeAfter; - if (NS_FAILED(CompareNodeToRange(firstCandidate, aRange, &nodeBefore, &nodeAfter))) + PRBool nodeBefore(PR_FALSE), nodeAfter(PR_FALSE); + if (!mFirstIter && NS_FAILED(CompareNodeToRange(firstCandidate, aRange, &nodeBefore, &nodeAfter))) return NS_ERROR_FAILURE; if (nodeBefore || nodeAfter) { @@ -1098,8 +1066,15 @@ nsresult nsGeneratedSubtreeIterator::Init(nsIDOMRange* aRange) // cool, we have the first node in the range. Now we walk // up it's ancestors to find the most senior that is still // in the range. That's the real first node. - if (NS_FAILED(GetTopAncestorInRange(firstCandidate, &mFirst))) + if (NS_SUCCEEDED(GetTopAncestorInRange(firstCandidate, &mFirst))) + { + mFirstIter = 0;//ancestor has one no + mGenIter = 0; + } + else if (!mFirstIter) //something bad happened and its not generated content iterators fault return NS_ERROR_FAILURE; + else + mFirst = firstCandidate;//setting last candidate to parent of generated content this is ok @@ -1143,15 +1118,29 @@ nsresult nsGeneratedSubtreeIterator::Init(nsIDOMRange* aRange) return NS_OK; } } - - lastCandidate = GetDeepLastChild(lastCandidate); + if (mGenIter) + { + mLastIter = mGenIter; + mLastIterType = mIterType; + } + if (!mLastIter)//dont ever set last candidate to a generated node! + { + lastCandidate = GetDeepLastChild(lastCandidate); + if (mGenIter) + { + mLastIter = mGenIter; + mLastIterType = mIterType; + } + } // confirm that this first possible contained node // is indeed contained. Else we have a range that // does not fully contain any node. - if (NS_FAILED(CompareNodeToRange(lastCandidate, aRange, &nodeBefore, &nodeAfter))) + if (!mLastIter && NS_FAILED(CompareNodeToRange(lastCandidate, aRange, &nodeBefore, &nodeAfter))) return NS_ERROR_FAILURE; + + if (nodeBefore || nodeAfter) { MakeEmpty(); @@ -1161,11 +1150,19 @@ nsresult nsGeneratedSubtreeIterator::Init(nsIDOMRange* aRange) // cool, we have the last node in the range. Now we walk // up it's ancestors to find the most senior that is still // in the range. That's the real first node. - if (NS_FAILED(GetTopAncestorInRange(lastCandidate, &mLast))) + if (NS_SUCCEEDED(GetTopAncestorInRange(lastCandidate, &mLast))) + { + mLastIter = 0;//ancestor has one no + mGenIter = 0; + } + else if (!mLastIter) //something bad happened and its not generated content iterators fault return NS_ERROR_FAILURE; + else + mLast = lastCandidate;//setting last candidate to parent of generated content this is ok mCurNode = mFirst; - + mGenIter = mFirstIter; + mIterType = mFirstIterType ; return NS_OK; } @@ -1178,40 +1175,53 @@ nsresult nsGeneratedSubtreeIterator::Next() { if (mIsDone) return NS_OK; - if (!mCurNode) - return NS_OK; - if (mCurNode == mLast) + nsCOMPtr curnode; + nsCOMPtr nextNode; + if (mGenIter) { - mIsDone = PR_TRUE; - return NS_OK; + if (mGenIter->IsDone()) + { + mGenIter = 0; + if (mIterType == nsIPresShell::After || NS_FAILED(mCurNode->ChildAt(0,*getter_AddRefs(nextNode)))) + { + if (NS_FAILED(GetNextSibling(mCurNode, &nextNode))) + return NS_OK; + } + } + else + return mGenIter->Next(); + } + else + { + if (mCurNode == mLast) + { + mIsDone = PR_TRUE; + return NS_OK; + } + if (NS_FAILED(GetNextSibling(mCurNode, &nextNode))) + return NS_OK; } - nsCOMPtr nextNode; - if (NS_FAILED(GetNextSibling(mCurNode, &nextNode))) - return NS_OK; - nextNode = GetDeepFirstChild(nextNode); - return GetTopAncestorInRange(nextNode, &mCurNode); + + + if (!mGenIter) + nextNode = GetDeepFirstChild(nextNode); + if (NS_SUCCEEDED(GetTopAncestorInRange(nextNode, &mCurNode))) + { + mGenIter = 0; + } + else if (!mGenIter) //something bad happened and its not generated content iterators fault + return NS_ERROR_FAILURE; + else + mCurNode = nextNode;//setting last candidate to parent of generated content this is ok + return NS_OK; } nsresult nsGeneratedSubtreeIterator::Prev() { - if (mIsDone) - return NS_OK; - if (!mCurNode) - return NS_OK; - if (mCurNode == mFirst) - { - mIsDone = PR_TRUE; - return NS_OK; - } - - nsCOMPtr prevNode; - prevNode = GetDeepFirstChild(mCurNode); - if (NS_FAILED(PrevNode(&prevNode))) - return NS_OK; - prevNode = GetDeepLastChild(prevNode); - return GetTopAncestorInRange(prevNode, &mCurNode); +//notimplemented + return NS_ERROR_NOT_IMPLEMENTED; } nsresult nsGeneratedSubtreeIterator::PositionAt(nsIContent* aCurNode) diff --git a/mozilla/content/base/src/nsSelection.cpp b/mozilla/content/base/src/nsSelection.cpp index 00738fc0340..9ef2ad73f15 100644 --- a/mozilla/content/base/src/nsSelection.cpp +++ b/mozilla/content/base/src/nsSelection.cpp @@ -69,6 +69,7 @@ //static NS_DEFINE_IID(kCContentIteratorCID, NS_CONTENTITERATOR_CID); static NS_DEFINE_IID(kCGenContentIteratorCID, NS_GENERATEDCONTENTITERATOR_CID); +static NS_DEFINE_IID(kCGenSubtreeIteratorCID, NS_GENERATEDSUBTREEITERATOR_CID); static NS_DEFINE_IID(kCSubtreeIteratorCID, NS_SUBTREEITERATOR_CID); //PROTOTYPES @@ -2968,7 +2969,7 @@ nsDOMSelection::selectFrames(nsIPresContext* aPresContext, nsCOMPtr genericiter = do_QueryInterface(aInnerIter); if (genericiter && aPresShell) { - genericiter->Init(aPresShell,aContent); + result = genericiter->Init(aPresShell,aContent); } else result = aInnerIter->Init(aContent); @@ -3016,7 +3017,7 @@ nsDOMSelection::selectFrames(nsIPresContext* aPresContext, nsIDOMRange *aRange, return NS_ERROR_NULL_POINTER; nsCOMPtr iter; nsCOMPtr inneriter; - nsresult result = nsComponentManager::CreateInstance(kCSubtreeIteratorCID, nsnull, + nsresult result = nsComponentManager::CreateInstance(kCGenSubtreeIteratorCID, nsnull, NS_GET_IID(nsIContentIterator), getter_AddRefs(iter)); if (NS_FAILED(result)) @@ -3027,11 +3028,16 @@ nsDOMSelection::selectFrames(nsIPresContext* aPresContext, nsIDOMRange *aRange, if ((NS_SUCCEEDED(result)) && iter && inneriter) { - iter->Init(aRange); nsCOMPtr presShell; result = aPresContext->GetShell(getter_AddRefs(presShell)); if (NS_FAILED(result) && presShell) presShell = 0; + nsCOMPtr genericiter = do_QueryInterface(iter); + if (genericiter && presShell) + result = genericiter->Init(presShell,aRange); + else + result = iter->Init(aRange); + // loop through the content iterator for each content node // for each text node: // get the frame for the content, and from it the style context diff --git a/mozilla/layout/base/src/nsGeneratedIterator.cpp b/mozilla/layout/base/src/nsGeneratedIterator.cpp index c02a34f10cd..8bb59e3b2c5 100644 --- a/mozilla/layout/base/src/nsGeneratedIterator.cpp +++ b/mozilla/layout/base/src/nsGeneratedIterator.cpp @@ -152,8 +152,11 @@ protected: nsCOMPtr mCommonParent; nsCOMPtr mFirstIter; + nsCOMPtr mLastIter; nsCOMPtr mGenIter; nsIPresShell::GeneratedContentType mIterType; + nsIPresShell::GeneratedContentType mFirstIterType; + nsIPresShell::GeneratedContentType mLastIterType; nsCOMPtr mPresShell; PRBool mIsDone; PRBool mPre; @@ -253,11 +256,13 @@ nsresult nsGeneratedContentIterator::Init(nsIContent* aRoot) nsCOMPtr root( do_QueryInterface(aRoot) ); mFirst = GetDeepFirstChild(root); if (mGenIter)//we have generated + { mFirstIter = mGenIter; + mFirstIterType = mIterType; + } mLast = root; mCommonParent = root; mCurNode = mFirst; - mIterType = nsIPresShell::Before; return NS_OK; } @@ -358,7 +363,10 @@ nsresult nsGeneratedContentIterator::Init(nsIDOMRange* aRange) { mFirst = GetDeepFirstChild(cChild); if (mGenIter) + { mFirstIter = mGenIter; + mFirstIterType = mIterType; + } } // Does that first node really intersect the range? // the range could be collapsed, or the range could be @@ -505,7 +513,6 @@ nsCOMPtr nsGeneratedContentIterator::GetDeepLastChild(nsCOMPtrLast(); - result = mGenIter->CurrentNode(getter_AddRefs(deepFirstChild)); mIterType = nsIPresShell::After; return cChild; } @@ -556,8 +563,8 @@ nsresult nsGeneratedContentIterator::GetNextSibling(nsCOMPtr aNode, if (NS_SUCCEEDED(result) && mGenIter) { //ok we have a generated iter all bets are off mGenIter->First(); - result = mGenIter->CurrentNode(getter_AddRefs(*aSibling)); - if (NS_SUCCEEDED(result) && *aSibling) + mIterType = nsIPresShell::After; + *aSibling = parent; return result; } #endif @@ -606,9 +613,9 @@ nsresult nsGeneratedContentIterator::GetPrevSibling(nsCOMPtr aNode, if (NS_SUCCEEDED(result) && mGenIter) { //ok we have a generated iter all bets are off mGenIter->Last(); - result = mGenIter->CurrentNode(getter_AddRefs(*aSibling)); - if (NS_SUCCEEDED(result) && *aSibling) - return result; + *aSibling = parent; + mIterType = nsIPresShell::Before; + return result; } else #endif @@ -629,27 +636,9 @@ nsresult nsGeneratedContentIterator::NextNode(nsCOMPtr *ioNextNode) if (!ioNextNode) return NS_ERROR_NULL_POINTER; -/* if (mPre) // if we are a Pre-order iterator, use pre-order + if (mPre) // if we are a Pre-order iterator, use pre-order { - nsCOMPtr cN = *ioNextNode; - nsCOMPtr cFirstChild; - PRInt32 numChildren; - - cN->ChildCount(numChildren); - - // if it has children then next node is first child - if (numChildren) - { - if (NS_FAILED(cN->ChildAt(0,*getter_AddRefs(cFirstChild)))) - return NS_ERROR_FAILURE; - if (!cFirstChild) - return NS_ERROR_FAILURE; - *ioNextNode = cFirstChild; - return NS_OK; - } - - // else next sibling is next - return GetNextSibling(cN, ioNextNode); + return NS_ERROR_NOT_IMPLEMENTED; } else // post-order*/ if (mGenIter) @@ -698,7 +687,6 @@ nsresult nsGeneratedContentIterator::NextNode(nsCOMPtr *ioNextNode) { mGenIter = 0; } -#if DO_AFTER else//check for after node. { nsresult result = NS_ERROR_FAILURE; @@ -708,12 +696,10 @@ nsresult nsGeneratedContentIterator::NextNode(nsCOMPtr *ioNextNode) { //ok we have a generated iter all bets are off mGenIter->First(); mIterType = nsIPresShell::After; - //*ioNextNode = parent; } else mGenIter = 0; } -#endif // else it's the parent *ioNextNode = parent; @@ -728,35 +714,11 @@ nsresult nsGeneratedContentIterator::PrevNode(nsCOMPtr *ioNextNode) if (!ioNextNode) return NS_ERROR_NULL_POINTER; - /* if (mPre) // if we are a Pre-order iterator, use pre-order { - nsCOMPtr cN = *ioNextNode; - nsCOMPtr cSibling; - nsCOMPtr parent; - PRInt32 indx; - - // get prev sibling if there is one - if (NS_FAILED(cN->GetParent(*getter_AddRefs(parent)))) - return NS_ERROR_FAILURE; - if (!parent || NS_FAILED(parent->IndexOf(cN, indx))) - { - // a little noise to catch some iterator usage bugs. - NS_NOTREACHED("nsGeneratedContentIterator::PrevNode() : no parent found"); - return NS_ERROR_FAILURE; - } - if (indx && NS_SUCCEEDED(parent->ChildAt(--indx,*getter_AddRefs(cSibling))) && cSibling) - { - // prev node is siblings "deep right" child - *ioNextNode = GetDeepLastChild(cSibling); - return NS_OK; - } - - // else it's the parent - *ioNextNode = parent; + return NS_ERROR_NOT_IMPLEMENTED; } else // post-order - */ { nsCOMPtr cN = *ioNextNode; nsCOMPtr cLastChild; @@ -790,8 +752,6 @@ nsresult nsGeneratedContentIterator::First() if (!mFirst) return NS_ERROR_FAILURE; mIsDone = PR_FALSE; - if (mFirst == mCurNode) - return NS_OK; mCurNode = mFirst; mGenIter = mFirstIter; if (mGenIter)//set directionback to before... @@ -805,10 +765,8 @@ nsresult nsGeneratedContentIterator::Last() if (!mLast) return NS_ERROR_FAILURE; mIsDone = PR_FALSE; - if (mLast == mCurNode) - return NS_OK; + mGenIter = mLastIter; mCurNode = mLast; - mGenIter = 0; return NS_OK; } @@ -940,7 +898,6 @@ protected: // no copy's or assigns FIX ME nsGeneratedSubtreeIterator(const nsGeneratedSubtreeIterator&); nsGeneratedSubtreeIterator& operator=(const nsGeneratedSubtreeIterator&); - nsCOMPtr mPresShell; nsCOMPtr mRange; }; @@ -1079,15 +1036,26 @@ nsresult nsGeneratedSubtreeIterator::Init(nsIDOMRange* aRange) return NS_OK; } } - - firstCandidate = GetDeepFirstChild(firstCandidate); - + if (mGenIter) + { + mFirstIter = mGenIter; + mFirstIterType = mIterType; + } + if (!mFirstIter) + { + firstCandidate = GetDeepFirstChild(firstCandidate); + if (mGenIter) + { + mFirstIter = mGenIter; + mFirstIterType = mIterType; + } + } // confirm that this first possible contained node // is indeed contained. Else we have a range that // does not fully contain any node. - PRBool nodeBefore, nodeAfter; - if (NS_FAILED(CompareNodeToRange(firstCandidate, aRange, &nodeBefore, &nodeAfter))) + PRBool nodeBefore(PR_FALSE), nodeAfter(PR_FALSE); + if (!mFirstIter && NS_FAILED(CompareNodeToRange(firstCandidate, aRange, &nodeBefore, &nodeAfter))) return NS_ERROR_FAILURE; if (nodeBefore || nodeAfter) { @@ -1098,8 +1066,15 @@ nsresult nsGeneratedSubtreeIterator::Init(nsIDOMRange* aRange) // cool, we have the first node in the range. Now we walk // up it's ancestors to find the most senior that is still // in the range. That's the real first node. - if (NS_FAILED(GetTopAncestorInRange(firstCandidate, &mFirst))) + if (NS_SUCCEEDED(GetTopAncestorInRange(firstCandidate, &mFirst))) + { + mFirstIter = 0;//ancestor has one no + mGenIter = 0; + } + else if (!mFirstIter) //something bad happened and its not generated content iterators fault return NS_ERROR_FAILURE; + else + mFirst = firstCandidate;//setting last candidate to parent of generated content this is ok @@ -1143,15 +1118,29 @@ nsresult nsGeneratedSubtreeIterator::Init(nsIDOMRange* aRange) return NS_OK; } } - - lastCandidate = GetDeepLastChild(lastCandidate); + if (mGenIter) + { + mLastIter = mGenIter; + mLastIterType = mIterType; + } + if (!mLastIter)//dont ever set last candidate to a generated node! + { + lastCandidate = GetDeepLastChild(lastCandidate); + if (mGenIter) + { + mLastIter = mGenIter; + mLastIterType = mIterType; + } + } // confirm that this first possible contained node // is indeed contained. Else we have a range that // does not fully contain any node. - if (NS_FAILED(CompareNodeToRange(lastCandidate, aRange, &nodeBefore, &nodeAfter))) + if (!mLastIter && NS_FAILED(CompareNodeToRange(lastCandidate, aRange, &nodeBefore, &nodeAfter))) return NS_ERROR_FAILURE; + + if (nodeBefore || nodeAfter) { MakeEmpty(); @@ -1161,11 +1150,19 @@ nsresult nsGeneratedSubtreeIterator::Init(nsIDOMRange* aRange) // cool, we have the last node in the range. Now we walk // up it's ancestors to find the most senior that is still // in the range. That's the real first node. - if (NS_FAILED(GetTopAncestorInRange(lastCandidate, &mLast))) + if (NS_SUCCEEDED(GetTopAncestorInRange(lastCandidate, &mLast))) + { + mLastIter = 0;//ancestor has one no + mGenIter = 0; + } + else if (!mLastIter) //something bad happened and its not generated content iterators fault return NS_ERROR_FAILURE; + else + mLast = lastCandidate;//setting last candidate to parent of generated content this is ok mCurNode = mFirst; - + mGenIter = mFirstIter; + mIterType = mFirstIterType ; return NS_OK; } @@ -1178,40 +1175,53 @@ nsresult nsGeneratedSubtreeIterator::Next() { if (mIsDone) return NS_OK; - if (!mCurNode) - return NS_OK; - if (mCurNode == mLast) + nsCOMPtr curnode; + nsCOMPtr nextNode; + if (mGenIter) { - mIsDone = PR_TRUE; - return NS_OK; + if (mGenIter->IsDone()) + { + mGenIter = 0; + if (mIterType == nsIPresShell::After || NS_FAILED(mCurNode->ChildAt(0,*getter_AddRefs(nextNode)))) + { + if (NS_FAILED(GetNextSibling(mCurNode, &nextNode))) + return NS_OK; + } + } + else + return mGenIter->Next(); + } + else + { + if (mCurNode == mLast) + { + mIsDone = PR_TRUE; + return NS_OK; + } + if (NS_FAILED(GetNextSibling(mCurNode, &nextNode))) + return NS_OK; } - nsCOMPtr nextNode; - if (NS_FAILED(GetNextSibling(mCurNode, &nextNode))) - return NS_OK; - nextNode = GetDeepFirstChild(nextNode); - return GetTopAncestorInRange(nextNode, &mCurNode); + + + if (!mGenIter) + nextNode = GetDeepFirstChild(nextNode); + if (NS_SUCCEEDED(GetTopAncestorInRange(nextNode, &mCurNode))) + { + mGenIter = 0; + } + else if (!mGenIter) //something bad happened and its not generated content iterators fault + return NS_ERROR_FAILURE; + else + mCurNode = nextNode;//setting last candidate to parent of generated content this is ok + return NS_OK; } nsresult nsGeneratedSubtreeIterator::Prev() { - if (mIsDone) - return NS_OK; - if (!mCurNode) - return NS_OK; - if (mCurNode == mFirst) - { - mIsDone = PR_TRUE; - return NS_OK; - } - - nsCOMPtr prevNode; - prevNode = GetDeepFirstChild(mCurNode); - if (NS_FAILED(PrevNode(&prevNode))) - return NS_OK; - prevNode = GetDeepLastChild(prevNode); - return GetTopAncestorInRange(prevNode, &mCurNode); +//notimplemented + return NS_ERROR_NOT_IMPLEMENTED; } nsresult nsGeneratedSubtreeIterator::PositionAt(nsIContent* aCurNode) diff --git a/mozilla/layout/base/src/nsSelection.cpp b/mozilla/layout/base/src/nsSelection.cpp index 00738fc0340..9ef2ad73f15 100644 --- a/mozilla/layout/base/src/nsSelection.cpp +++ b/mozilla/layout/base/src/nsSelection.cpp @@ -69,6 +69,7 @@ //static NS_DEFINE_IID(kCContentIteratorCID, NS_CONTENTITERATOR_CID); static NS_DEFINE_IID(kCGenContentIteratorCID, NS_GENERATEDCONTENTITERATOR_CID); +static NS_DEFINE_IID(kCGenSubtreeIteratorCID, NS_GENERATEDSUBTREEITERATOR_CID); static NS_DEFINE_IID(kCSubtreeIteratorCID, NS_SUBTREEITERATOR_CID); //PROTOTYPES @@ -2968,7 +2969,7 @@ nsDOMSelection::selectFrames(nsIPresContext* aPresContext, nsCOMPtr genericiter = do_QueryInterface(aInnerIter); if (genericiter && aPresShell) { - genericiter->Init(aPresShell,aContent); + result = genericiter->Init(aPresShell,aContent); } else result = aInnerIter->Init(aContent); @@ -3016,7 +3017,7 @@ nsDOMSelection::selectFrames(nsIPresContext* aPresContext, nsIDOMRange *aRange, return NS_ERROR_NULL_POINTER; nsCOMPtr iter; nsCOMPtr inneriter; - nsresult result = nsComponentManager::CreateInstance(kCSubtreeIteratorCID, nsnull, + nsresult result = nsComponentManager::CreateInstance(kCGenSubtreeIteratorCID, nsnull, NS_GET_IID(nsIContentIterator), getter_AddRefs(iter)); if (NS_FAILED(result)) @@ -3027,11 +3028,16 @@ nsDOMSelection::selectFrames(nsIPresContext* aPresContext, nsIDOMRange *aRange, if ((NS_SUCCEEDED(result)) && iter && inneriter) { - iter->Init(aRange); nsCOMPtr presShell; result = aPresContext->GetShell(getter_AddRefs(presShell)); if (NS_FAILED(result) && presShell) presShell = 0; + nsCOMPtr genericiter = do_QueryInterface(iter); + if (genericiter && presShell) + result = genericiter->Init(presShell,aRange); + else + result = iter->Init(aRange); + // loop through the content iterator for each content node // for each text node: // get the frame for the content, and from it the style context diff --git a/mozilla/layout/generic/nsSelection.cpp b/mozilla/layout/generic/nsSelection.cpp index 00738fc0340..9ef2ad73f15 100644 --- a/mozilla/layout/generic/nsSelection.cpp +++ b/mozilla/layout/generic/nsSelection.cpp @@ -69,6 +69,7 @@ //static NS_DEFINE_IID(kCContentIteratorCID, NS_CONTENTITERATOR_CID); static NS_DEFINE_IID(kCGenContentIteratorCID, NS_GENERATEDCONTENTITERATOR_CID); +static NS_DEFINE_IID(kCGenSubtreeIteratorCID, NS_GENERATEDSUBTREEITERATOR_CID); static NS_DEFINE_IID(kCSubtreeIteratorCID, NS_SUBTREEITERATOR_CID); //PROTOTYPES @@ -2968,7 +2969,7 @@ nsDOMSelection::selectFrames(nsIPresContext* aPresContext, nsCOMPtr genericiter = do_QueryInterface(aInnerIter); if (genericiter && aPresShell) { - genericiter->Init(aPresShell,aContent); + result = genericiter->Init(aPresShell,aContent); } else result = aInnerIter->Init(aContent); @@ -3016,7 +3017,7 @@ nsDOMSelection::selectFrames(nsIPresContext* aPresContext, nsIDOMRange *aRange, return NS_ERROR_NULL_POINTER; nsCOMPtr iter; nsCOMPtr inneriter; - nsresult result = nsComponentManager::CreateInstance(kCSubtreeIteratorCID, nsnull, + nsresult result = nsComponentManager::CreateInstance(kCGenSubtreeIteratorCID, nsnull, NS_GET_IID(nsIContentIterator), getter_AddRefs(iter)); if (NS_FAILED(result)) @@ -3027,11 +3028,16 @@ nsDOMSelection::selectFrames(nsIPresContext* aPresContext, nsIDOMRange *aRange, if ((NS_SUCCEEDED(result)) && iter && inneriter) { - iter->Init(aRange); nsCOMPtr presShell; result = aPresContext->GetShell(getter_AddRefs(presShell)); if (NS_FAILED(result) && presShell) presShell = 0; + nsCOMPtr genericiter = do_QueryInterface(iter); + if (genericiter && presShell) + result = genericiter->Init(presShell,aRange); + else + result = iter->Init(aRange); + // loop through the content iterator for each content node // for each text node: // get the frame for the content, and from it the style context diff --git a/mozilla/layout/generic/nsTextFrame.cpp b/mozilla/layout/generic/nsTextFrame.cpp index 016b6498e58..24492a481d3 100644 --- a/mozilla/layout/generic/nsTextFrame.cpp +++ b/mozilla/layout/generic/nsTextFrame.cpp @@ -683,6 +683,8 @@ protected: PRUnichar* aBuffer, PRInt32 aLength, nscoord* aWidthResult, PRBool aGetWidth/* true=get width false = return length up to aWidthResult size*/); + nsresult GetContentAndOffsetsForSelection(nsIPresContext* aPresContext,nsIContent **aContent, PRInt32 *aOffset, PRInt32 *aLength); + }; class nsContinuingTextFrame : public nsTextFrame { @@ -1553,6 +1555,70 @@ nsTextFrame::PaintTextDecorations(nsIRenderingContext& aRenderingContext, } } + + +nsresult +nsTextFrame::GetContentAndOffsetsForSelection(nsIPresContext *aPresContext, nsIContent **aContent, PRInt32 *aOffset, PRInt32 *aLength) +{ + if (!aContent || !aOffset || !aLength) + return NS_ERROR_NULL_POINTER; + //ARE WE GENERATED?? + *aContent = nsnull; + *aOffset = mContentOffset; + *aLength = mContentLength; + nsIFrame *parent; + nsresult rv = GetParent(&parent); + if (NS_SUCCEEDED(rv) && parent) + { + nsFrameState parentFrameState; + + parent->GetFrameState(&parentFrameState); + if ((parentFrameState & NS_FRAME_GENERATED_CONTENT) != 0)//parent is generated so so are we. + { + //we COULD check the previous sibling but I dont think that is reliable + rv = parent->GetContent(aContent); + if (NS_FAILED(rv) || !*aContent) + return rv?rv:NS_ERROR_FAILURE; + + //ARE WE A BEFORE FRAME? if not then we assume we are an after frame. this may be bad later + nsIFrame *grandParent; + nsIFrame *firstParent; + rv = parent->GetParent(&grandParent); + if (NS_SUCCEEDED(rv) && grandParent) + { + rv = grandParent->FirstChild(aPresContext,nsnull, &firstParent); + if (NS_SUCCEEDED(rv) && firstParent) + { + *aLength = 0; + if (firstParent == parent) //then our parent is the first child of granddad. use BEFORE + { + *aOffset = 0; + } + else + { + PRInt32 numChildren; + if (NS_SUCCEEDED(rv = (*aContent)->ChildCount(numChildren))) + *aOffset = numChildren; + else + return rv; + } + } + else + return rv; + } + } + } + //END GENERATED BLOCK + if (!*aContent) + { + *aContent = mContent; + NS_IF_ADDREF(*aContent); + } + + return NS_OK; +} + + void nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -1609,7 +1675,10 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext, rv = shell->GetFrameSelection(getter_AddRefs(frameSelection)); if (NS_SUCCEEDED(rv) && frameSelection){ nsCOMPtr content; - rv = GetContent(getter_AddRefs(content)); + PRInt32 offset; + PRInt32 length; + + rv = GetContentAndOffsetsForSelection(aPresContext,getter_AddRefs(content),&offset,&length); if (NS_SUCCEEDED(rv) && content){ rv = frameSelection->LookUpSelection(content, mContentOffset, mContentLength , &details, PR_FALSE); @@ -2069,7 +2138,10 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext, rv = shell->GetFrameSelection(getter_AddRefs(frameSelection)); if (NS_SUCCEEDED(rv) && frameSelection){ nsCOMPtr content; - rv = GetContent(getter_AddRefs(content)); + PRInt32 offset; + PRInt32 length; + + rv = GetContentAndOffsetsForSelection(aPresContext,getter_AddRefs(content),&offset,&length); if (NS_SUCCEEDED(rv)){ rv = frameSelection->LookUpSelection(content, mContentOffset, mContentLength , &details, PR_FALSE); @@ -2217,7 +2289,10 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext, rv = shell->GetFrameSelection(getter_AddRefs(frameSelection)); if (NS_SUCCEEDED(rv) && frameSelection){ nsCOMPtr content; - rv = GetContent(getter_AddRefs(content)); + PRInt32 offset; + PRInt32 length; + + rv = GetContentAndOffsetsForSelection(aPresContext, getter_AddRefs(content),&offset,&length); if (NS_SUCCEEDED(rv)){ rv = frameSelection->LookUpSelection(content, mContentOffset, mContentLength , &details, PR_FALSE); @@ -2625,10 +2700,13 @@ nsTextFrame::SetSelected(nsIPresContext* aPresContext, rv = shell->GetFrameSelection(getter_AddRefs(frameSelection)); if (NS_SUCCEEDED(rv) && frameSelection){ nsCOMPtr content; - rv = GetContent(getter_AddRefs(content)); + PRInt32 offset; + PRInt32 length; + + rv = GetContentAndOffsetsForSelection(aPresContext, getter_AddRefs(content),&offset,&length); if (NS_SUCCEEDED(rv) && content){ - rv = frameSelection->LookUpSelection(content, mContentOffset, - mContentLength , &details, PR_TRUE); + rv = frameSelection->LookUpSelection(content, offset, + length , &details, PR_TRUE); // PR_TRUE last param used here! we need to see if we are still selected. so no shortcut } @@ -2671,18 +2749,6 @@ nsTextFrame::SetSelected(nsIPresContext* aPresContext, if (NS_FAILED(result)) break; } -#if 0 - else //we need to talk to siblings as well as flow - { - result = GetNextSibling(&frame); - while (NS_SUCCEEDED(result) && frame){ - frame->SetSelected(aRange,aSelected,eSpreadDown); - result = frame->GetNextSibling(&frame); - if (NS_FAILED(result)) - break; - } - } -#endif } return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsTextFrame.cpp b/mozilla/layout/html/base/src/nsTextFrame.cpp index 016b6498e58..24492a481d3 100644 --- a/mozilla/layout/html/base/src/nsTextFrame.cpp +++ b/mozilla/layout/html/base/src/nsTextFrame.cpp @@ -683,6 +683,8 @@ protected: PRUnichar* aBuffer, PRInt32 aLength, nscoord* aWidthResult, PRBool aGetWidth/* true=get width false = return length up to aWidthResult size*/); + nsresult GetContentAndOffsetsForSelection(nsIPresContext* aPresContext,nsIContent **aContent, PRInt32 *aOffset, PRInt32 *aLength); + }; class nsContinuingTextFrame : public nsTextFrame { @@ -1553,6 +1555,70 @@ nsTextFrame::PaintTextDecorations(nsIRenderingContext& aRenderingContext, } } + + +nsresult +nsTextFrame::GetContentAndOffsetsForSelection(nsIPresContext *aPresContext, nsIContent **aContent, PRInt32 *aOffset, PRInt32 *aLength) +{ + if (!aContent || !aOffset || !aLength) + return NS_ERROR_NULL_POINTER; + //ARE WE GENERATED?? + *aContent = nsnull; + *aOffset = mContentOffset; + *aLength = mContentLength; + nsIFrame *parent; + nsresult rv = GetParent(&parent); + if (NS_SUCCEEDED(rv) && parent) + { + nsFrameState parentFrameState; + + parent->GetFrameState(&parentFrameState); + if ((parentFrameState & NS_FRAME_GENERATED_CONTENT) != 0)//parent is generated so so are we. + { + //we COULD check the previous sibling but I dont think that is reliable + rv = parent->GetContent(aContent); + if (NS_FAILED(rv) || !*aContent) + return rv?rv:NS_ERROR_FAILURE; + + //ARE WE A BEFORE FRAME? if not then we assume we are an after frame. this may be bad later + nsIFrame *grandParent; + nsIFrame *firstParent; + rv = parent->GetParent(&grandParent); + if (NS_SUCCEEDED(rv) && grandParent) + { + rv = grandParent->FirstChild(aPresContext,nsnull, &firstParent); + if (NS_SUCCEEDED(rv) && firstParent) + { + *aLength = 0; + if (firstParent == parent) //then our parent is the first child of granddad. use BEFORE + { + *aOffset = 0; + } + else + { + PRInt32 numChildren; + if (NS_SUCCEEDED(rv = (*aContent)->ChildCount(numChildren))) + *aOffset = numChildren; + else + return rv; + } + } + else + return rv; + } + } + } + //END GENERATED BLOCK + if (!*aContent) + { + *aContent = mContent; + NS_IF_ADDREF(*aContent); + } + + return NS_OK; +} + + void nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -1609,7 +1675,10 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext, rv = shell->GetFrameSelection(getter_AddRefs(frameSelection)); if (NS_SUCCEEDED(rv) && frameSelection){ nsCOMPtr content; - rv = GetContent(getter_AddRefs(content)); + PRInt32 offset; + PRInt32 length; + + rv = GetContentAndOffsetsForSelection(aPresContext,getter_AddRefs(content),&offset,&length); if (NS_SUCCEEDED(rv) && content){ rv = frameSelection->LookUpSelection(content, mContentOffset, mContentLength , &details, PR_FALSE); @@ -2069,7 +2138,10 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext, rv = shell->GetFrameSelection(getter_AddRefs(frameSelection)); if (NS_SUCCEEDED(rv) && frameSelection){ nsCOMPtr content; - rv = GetContent(getter_AddRefs(content)); + PRInt32 offset; + PRInt32 length; + + rv = GetContentAndOffsetsForSelection(aPresContext,getter_AddRefs(content),&offset,&length); if (NS_SUCCEEDED(rv)){ rv = frameSelection->LookUpSelection(content, mContentOffset, mContentLength , &details, PR_FALSE); @@ -2217,7 +2289,10 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext, rv = shell->GetFrameSelection(getter_AddRefs(frameSelection)); if (NS_SUCCEEDED(rv) && frameSelection){ nsCOMPtr content; - rv = GetContent(getter_AddRefs(content)); + PRInt32 offset; + PRInt32 length; + + rv = GetContentAndOffsetsForSelection(aPresContext, getter_AddRefs(content),&offset,&length); if (NS_SUCCEEDED(rv)){ rv = frameSelection->LookUpSelection(content, mContentOffset, mContentLength , &details, PR_FALSE); @@ -2625,10 +2700,13 @@ nsTextFrame::SetSelected(nsIPresContext* aPresContext, rv = shell->GetFrameSelection(getter_AddRefs(frameSelection)); if (NS_SUCCEEDED(rv) && frameSelection){ nsCOMPtr content; - rv = GetContent(getter_AddRefs(content)); + PRInt32 offset; + PRInt32 length; + + rv = GetContentAndOffsetsForSelection(aPresContext, getter_AddRefs(content),&offset,&length); if (NS_SUCCEEDED(rv) && content){ - rv = frameSelection->LookUpSelection(content, mContentOffset, - mContentLength , &details, PR_TRUE); + rv = frameSelection->LookUpSelection(content, offset, + length , &details, PR_TRUE); // PR_TRUE last param used here! we need to see if we are still selected. so no shortcut } @@ -2671,18 +2749,6 @@ nsTextFrame::SetSelected(nsIPresContext* aPresContext, if (NS_FAILED(result)) break; } -#if 0 - else //we need to talk to siblings as well as flow - { - result = GetNextSibling(&frame); - while (NS_SUCCEEDED(result) && frame){ - frame->SetSelected(aRange,aSelected,eSpreadDown); - result = frame->GetNextSibling(&frame); - if (NS_FAILED(result)) - break; - } - } -#endif } return NS_OK; }