diff --git a/accessible/src/html/nsHyperTextAccessible.cpp b/accessible/src/html/nsHyperTextAccessible.cpp
index 3e00ebe8e727..a82158be650c 100644
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -1685,7 +1685,7 @@ PRInt32 nsHyperTextAccessible::GetCaretLineNumber()
NS_ENSURE_TRUE(caretFrame, -1);
PRInt32 lineNumber = 1;
- nsAutoLineIterator lineIterForCaret;
+ nsCOMPtr lineIterForCaret;
nsCOMPtr hyperTextContent = do_QueryInterface(mDOMNode);
while (caretFrame) {
if (hyperTextContent == caretFrame->GetContent()) {
@@ -1698,10 +1698,11 @@ PRInt32 nsHyperTextAccessible::GetCaretLineNumber()
// Add lines for the sibling frames before the caret
nsIFrame *sibling = parentFrame->GetFirstChild(nsnull);
while (sibling && sibling != caretFrame) {
- nsAutoLineIterator lineIterForSibling = sibling->GetLineIterator();
+ nsCOMPtr lineIterForSibling = do_QueryInterface(sibling);
if (lineIterForSibling) {
+ PRInt32 addLines;
// For the frames before that grab all the lines
- PRInt32 addLines = lineIterForSibling->GetNumLines();
+ lineIterForSibling->GetNumLines(&addLines);
lineNumber += addLines;
}
sibling = sibling->GetNextSibling();
@@ -1709,10 +1710,11 @@ PRInt32 nsHyperTextAccessible::GetCaretLineNumber()
// Get the line number relative to the container with lines
if (!lineIterForCaret) { // Add the caret line just once
- lineIterForCaret = parentFrame->GetLineIterator();
+ lineIterForCaret = do_QueryInterface(parentFrame);
if (lineIterForCaret) {
// Ancestor of caret
- PRInt32 addLines = lineIterForCaret->FindLineContaining(caretFrame);
+ PRInt32 addLines;
+ lineIterForCaret->FindLineContaining(caretFrame, &addLines);
lineNumber += addLines;
}
}
diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp
index 3d79680d9f2a..921bafd49ab0 100644
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -3801,9 +3801,11 @@ UnionRectForClosestScrolledView(nsIFrame* aFrame,
f &&
frameType == nsGkAtoms::blockFrame) {
// find the line containing aFrame and increase the top of |offset|.
- nsAutoLineIterator lines = f->GetLineIterator();
+ nsCOMPtr lines(do_QueryInterface(f));
+
if (lines) {
- PRInt32 index = lines->FindLineContaining(prevFrame);
+ PRInt32 index = -1;
+ lines->FindLineContaining(prevFrame, &index);
if (index >= 0) {
nsIFrame *trash1;
PRInt32 trash2;
diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp
index 170d9118e4f4..10f2df7b75fa 100644
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -315,22 +315,6 @@ nsBlockFrame::Destroy()
nsBlockFrameSuper::Destroy();
}
-/* virtual */ nsILineIterator*
-nsBlockFrame::GetLineIterator()
-{
- nsLineIterator* it = new nsLineIterator;
- if (!it)
- return nsnull;
-
- const nsStyleVisibility* visibility = GetStyleVisibility();
- nsresult rv = it->Init(mLines, visibility->mDirection == NS_STYLE_DIRECTION_RTL);
- if (NS_FAILED(rv)) {
- delete it;
- return nsnull;
- }
- return it;
-}
-
NS_IMETHODIMP
nsBlockFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
@@ -340,6 +324,26 @@ nsBlockFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
*aInstancePtr = static_cast(static_cast(this));
return NS_OK;
}
+ if (aIID.Equals(NS_GET_IID(nsILineIterator)) ||
+ aIID.Equals(NS_GET_IID(nsILineIteratorNavigator))) {
+ nsLineIterator* it = new nsLineIterator;
+ if (!it) {
+ *aInstancePtr = nsnull;
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ NS_ADDREF(it); // reference passed to caller
+ const nsStyleVisibility* visibility = GetStyleVisibility();
+ nsresult rv = it->Init(mLines,
+ visibility->mDirection == NS_STYLE_DIRECTION_RTL);
+ if (NS_FAILED(rv)) {
+ *aInstancePtr = nsnull;
+ NS_RELEASE(it);
+ return rv;
+ }
+ *aInstancePtr = static_cast(it);
+ return NS_OK;
+ }
+
return nsBlockFrameSuper::QueryInterface(aIID, aInstancePtr);
}
diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h
index 30587207e675..0d2507a20a4f 100644
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -74,6 +74,7 @@ class nsBlockInFlowLineIterator;
class nsBulletFrame;
class nsLineBox;
class nsFirstLineFrame;
+class nsILineIterator;
class nsIntervalSet;
/**
* Child list name indices
@@ -597,8 +598,6 @@ protected:
//----------------------------------------
- virtual nsILineIterator* GetLineIterator();
-
public:
nsLineList* GetOverflowLines() const;
protected:
diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp
index b7c6cdf76c8c..635b1cd56614 100644
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -4558,8 +4558,6 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
PRInt8 aOutSideLimit
)
{
- nsresult result;
-
//magic numbers aLineStart will be -1 for end of block 0 will be start of block
if (!aBlockFrame || !aPos)
return NS_ERROR_NULL_POINTER;
@@ -4568,11 +4566,14 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
aPos->mResultContent = nsnull;
aPos->mAttachForward = (aPos->mDirection == eDirNext);
- nsAutoLineIterator it = aBlockFrame->GetLineIterator();
- if (!it)
- return NS_ERROR_FAILURE;
+ nsresult result;
+ nsCOMPtr it;
+ result = aBlockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it));
+ if (NS_FAILED(result) || !it)
+ return result;
PRInt32 searchingLine = aLineStart;
- PRInt32 countLines = it->GetNumLines();
+ PRInt32 countLines;
+ result = it->GetNumLines(&countLines);
if (aOutSideLimit > 0) //start at end
searchingLine = countLines;
else if (aOutSideLimit <0)//start at beginning
@@ -4640,9 +4641,10 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
if (NS_SUCCEEDED(result) && resultFrame)
{
+ nsCOMPtr newIt;
//check to see if this is ANOTHER blockframe inside the other one if so then call into its lines
- nsAutoLineIterator newIt = resultFrame->GetLineIterator();
- if (newIt)
+ result = resultFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(newIt));
+ if (NS_SUCCEEDED(result) && newIt)
{
aPos->mResultFrame = resultFrame;
return NS_OK;
@@ -5085,16 +5087,15 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
}
case eSelectLine :
{
- nsAutoLineIterator iter;
+ nsCOMPtr iter;
nsIFrame *blockFrame = this;
while (NS_FAILED(result)){
PRInt32 thisLine = nsFrame::GetLineNumber(blockFrame, aPos->mScrollViewStop, &blockFrame);
if (thisLine < 0)
return NS_ERROR_FAILURE;
- iter = blockFrame->GetLineIterator();
- NS_ASSERTION(iter, "GetLineNumber() succeeded but no block frame?");
- result = NS_OK;
+ result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(iter));
+ NS_ASSERTION(NS_SUCCEEDED(result) && iter, "GetLineNumber() succeeded but no block frame?");
int edgeCase = 0;//no edge case. this should look at thisLine
@@ -5138,23 +5139,20 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
//got the table frame now
while(frame) //ok time to drill down to find iterator
{
- iter = frame->GetLineIterator();
- if (iter)
+ result = frame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),
+ getter_AddRefs(iter));
+ if (NS_SUCCEEDED(result))
{
aPos->mResultFrame = frame;
searchTableBool = PR_TRUE;
- result = NS_OK;
break; //while(frame)
}
- result = NS_ERROR_FAILURE;
frame = frame->GetFirstChild(nsnull);
}
}
-
- if (!searchTableBool) {
- iter = aPos->mResultFrame->GetLineIterator();
- result = iter ? NS_OK : NS_ERROR_FAILURE;
- }
+ if (!searchTableBool)
+ result = aPos->mResultFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),
+ getter_AddRefs(iter));
if (NS_SUCCEEDED(result) && iter)//we've struck another block element!
{
doneLooping = PR_FALSE;
@@ -5184,13 +5182,14 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
case eSelectBeginLine:
case eSelectEndLine:
{
+ nsCOMPtr it;
// Adjusted so that the caret can't get confused when content changes
nsIFrame* blockFrame = AdjustFrameForSelectionStyles(this);
PRInt32 thisLine = nsFrame::GetLineNumber(blockFrame, aPos->mScrollViewStop, &blockFrame);
if (thisLine < 0)
return NS_ERROR_FAILURE;
- nsAutoLineIterator it = blockFrame->GetLineIterator();
- NS_ASSERTION(it, "GetLineNumber() succeeded but no block frame?");
+ result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it));
+ NS_ASSERTION(NS_SUCCEEDED(result) && it, "GetLineNumber() succeeded but no block frame?");
PRInt32 lineFrameCount;
nsIFrame *firstFrame;
@@ -5201,7 +5200,8 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
#ifdef IBMBIDI
if (aPos->mVisual && PresContext()->BidiEnabled()) {
- PRBool lineIsRTL = it->GetDirection();
+ PRBool lineIsRTL;
+ it->GetDirection(&lineIsRTL);
PRBool isReordered;
nsIFrame *lastFrame;
result = it->CheckLineOrder(thisLine, &isReordered, &firstFrame, &lastFrame);
@@ -5357,7 +5357,7 @@ nsFrame::GetLineNumber(nsIFrame *aFrame, PRBool aLockScroll, nsIFrame** aContain
nsIFrame *blockFrame = aFrame;
nsIFrame *thisBlock;
PRInt32 thisLine;
- nsAutoLineIterator it;
+ nsCOMPtr it;
nsresult result = NS_ERROR_FAILURE;
while (NS_FAILED(result) && blockFrame)
{
@@ -5378,7 +5378,7 @@ nsFrame::GetLineNumber(nsIFrame *aFrame, PRBool aLockScroll, nsIFrame** aContain
if (blockFrame) {
if (aLockScroll && blockFrame->GetType() == nsGkAtoms::scrollFrame)
return -1;
- it = blockFrame->GetLineIterator();
+ result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it));
}
}
if (!blockFrame || !it)
@@ -5386,16 +5386,17 @@ nsFrame::GetLineNumber(nsIFrame *aFrame, PRBool aLockScroll, nsIFrame** aContain
if (aContainingBlock)
*aContainingBlock = blockFrame;
- return it->FindLineContaining(thisBlock);
+ result = it->FindLineContaining(thisBlock, &thisLine);
+ if (NS_FAILED(result))
+ return -1;
+ return thisLine;
}
nsresult
nsIFrame::GetFrameFromDirection(nsDirection aDirection, PRBool aVisual,
PRBool aJumpLines, PRBool aScrollViewStop,
nsIFrame** aOutFrame, PRInt32* aOutOffset, PRBool* aOutJumpedLine)
-{
- nsresult result;
-
+{
if (!aOutFrame || !aOutOffset || !aOutJumpedLine)
return NS_ERROR_NULL_POINTER;
@@ -5409,20 +5410,21 @@ nsIFrame::GetFrameFromDirection(nsDirection aDirection, PRBool aVisual,
nsIFrame *traversedFrame = this;
while (!selectable) {
nsIFrame *blockFrame;
+ nsCOMPtr it;
PRInt32 thisLine = nsFrame::GetLineNumber(traversedFrame, aScrollViewStop, &blockFrame);
if (thisLine < 0)
return NS_ERROR_FAILURE;
-
- nsAutoLineIterator it = blockFrame->GetLineIterator();
- NS_ASSERTION(it, "GetLineNumber() succeeded but no block frame?");
+ nsresult result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it));
+ NS_ASSERTION(NS_SUCCEEDED(result) && it, "GetLineNumber() succeeded but no block frame?");
PRBool atLineEdge;
nsIFrame *firstFrame;
nsIFrame *lastFrame;
#ifdef IBMBIDI
if (aVisual && presContext->BidiEnabled()) {
- PRBool lineIsRTL = it->GetDirection();
+ PRBool lineIsRTL;
+ it->GetDirection(&lineIsRTL);
PRBool isReordered;
result = it->CheckLineOrder(thisLine, &isReordered, &firstFrame, &lastFrame);
nsIFrame** framePtr = aDirection == eDirPrevious ? &firstFrame : &lastFrame;
@@ -6210,7 +6212,7 @@ nsFrame::RefreshSizeCache(nsBoxLayoutState& aState)
metrics->mBlockMinSize.height = 0;
// ok we need the max ascent of the items on the line. So to do this
// ask the block for its line iterator. Get the max ascent.
- nsAutoLineIterator lines = GetLineIterator();
+ nsCOMPtr lines = do_QueryInterface(static_cast(this));
if (lines)
{
metrics->mBlockMinSize.height = 0;
@@ -6253,12 +6255,6 @@ nsFrame::RefreshSizeCache(nsBoxLayoutState& aState)
return rv;
}
-/* virtual */ nsILineIterator*
-nsFrame::GetLineIterator()
-{
- return nsnull;
-}
-
nsSize
nsFrame::GetPrefSize(nsBoxLayoutState& aState)
{
diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h
index 334ddd0f1b9a..cf557c570c6c 100644
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -621,8 +621,6 @@ private:
NS_IMETHODIMP RefreshSizeCache(nsBoxLayoutState& aState);
- virtual nsILineIterator* GetLineIterator();
-
protected:
NS_IMETHOD_(nsrefcnt) AddRef(void);
NS_IMETHOD_(nsrefcnt) Release(void);
diff --git a/layout/generic/nsFrameList.cpp b/layout/generic/nsFrameList.cpp
index 4c230850c1fa..9556f30ce52e 100644
--- a/layout/generic/nsFrameList.cpp
+++ b/layout/generic/nsFrameList.cpp
@@ -427,6 +427,8 @@ nsFrameList::List(FILE* out) const
nsIFrame*
nsFrameList::GetPrevVisualFor(nsIFrame* aFrame) const
{
+ nsCOMPtr iter;
+
if (!mFirstChild)
return nsnull;
@@ -437,8 +439,8 @@ nsFrameList::GetPrevVisualFor(nsIFrame* aFrame) const
nsBidiLevel baseLevel = nsBidiPresUtils::GetFrameBaseLevel(mFirstChild);
nsBidiPresUtils* bidiUtils = mFirstChild->PresContext()->GetBidiUtils();
- nsAutoLineIterator iter = parent->GetLineIterator();
- if (!iter) {
+ nsresult result = parent->QueryInterface(NS_GET_IID(nsILineIterator), getter_AddRefs(iter));
+ if (NS_FAILED(result) || !iter) {
// Parent is not a block Frame
if (parent->GetType() == nsGkAtoms::lineFrame) {
// Line frames are not bidi-splittable, so need to consider bidi reordering
@@ -463,11 +465,11 @@ nsFrameList::GetPrevVisualFor(nsIFrame* aFrame) const
PRInt32 thisLine;
if (aFrame) {
- thisLine = iter->FindLineContaining(aFrame);
- if (thisLine < 0)
+ result = iter->FindLineContaining(aFrame, &thisLine);
+ if (NS_FAILED(result) || thisLine < 0)
return nsnull;
} else {
- thisLine = iter->GetNumLines();
+ iter->GetNumLines(&thisLine);
}
nsIFrame* frame = nsnull;
@@ -502,6 +504,8 @@ nsFrameList::GetPrevVisualFor(nsIFrame* aFrame) const
nsIFrame*
nsFrameList::GetNextVisualFor(nsIFrame* aFrame) const
{
+ nsCOMPtr iter;
+
if (!mFirstChild)
return nsnull;
@@ -512,8 +516,8 @@ nsFrameList::GetNextVisualFor(nsIFrame* aFrame) const
nsBidiLevel baseLevel = nsBidiPresUtils::GetFrameBaseLevel(mFirstChild);
nsBidiPresUtils* bidiUtils = mFirstChild->PresContext()->GetBidiUtils();
- nsAutoLineIterator iter = parent->GetLineIterator();
- if (!iter) {
+ nsresult result = parent->QueryInterface(NS_GET_IID(nsILineIterator), getter_AddRefs(iter));
+ if (NS_FAILED(result) || !iter) {
// Parent is not a block Frame
if (parent->GetType() == nsGkAtoms::lineFrame) {
// Line frames are not bidi-splittable, so need to consider bidi reordering
@@ -538,8 +542,8 @@ nsFrameList::GetNextVisualFor(nsIFrame* aFrame) const
PRInt32 thisLine;
if (aFrame) {
- thisLine = iter->FindLineContaining(aFrame);
- if (thisLine < 0)
+ result = iter->FindLineContaining(aFrame, &thisLine);
+ if (NS_FAILED(result) || thisLine < 0)
return nsnull;
} else {
thisLine = -1;
@@ -561,7 +565,8 @@ nsFrameList::GetNextVisualFor(nsIFrame* aFrame) const
}
}
- PRInt32 numLines = iter->GetNumLines();
+ PRInt32 numLines;
+ iter->GetNumLines(&numLines);
if (!frame && thisLine < numLines - 1) {
// Get the first frame of the next line
iter->GetLine(thisLine + 1, &firstFrameOnLine, &numFramesOnLine, lineBounds, &lineFlags);
diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h
index feb01085c7b3..8bdf1735c0ef 100644
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -85,7 +85,6 @@ class nsIDOMRange;
class nsISelectionController;
class nsBoxLayoutState;
class nsIBoxLayout;
-class nsILineIterator;
#ifdef ACCESSIBILITY
class nsIAccessible;
#endif
@@ -2225,14 +2224,6 @@ NS_PTR_TO_INT32(frame->GetProperty(nsGkAtoms::embeddingLevel))
const nsRect& aOldOverflowRect,
const nsSize& aNewDesiredSize);
- /**
- * Get a line iterator for this frame, if supported.
- *
- * @return nsnull if no line iterator is supported.
- * @note dispose the line iterator using nsILineIterator::DisposeLineIterator
- */
- virtual nsILineIterator* GetLineIterator() = 0;
-
protected:
// Members
nsRect mRect;
diff --git a/layout/generic/nsILineIterator.h b/layout/generic/nsILineIterator.h
index 54803262141e..391343011fca 100644
--- a/layout/generic/nsILineIterator.h
+++ b/layout/generic/nsILineIterator.h
@@ -37,11 +37,26 @@
#ifndef nsILineIterator_h___
#define nsILineIterator_h___
-#include "nscore.h"
-#include "nsCoord.h"
+#include "nsISupports.h"
-class nsIFrame;
-struct nsRect;
+/* a6cf90ff-15b3-11d2-932e-00805f8add32 */
+#define NS_ILINE_ITERATOR_IID \
+ { 0xa6cf90ff, 0x15b3, 0x11d2,{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
+
+/* {80AA3D7A-E0BF-4e18-8A82-2110397D7BC4}*/
+#define NS_ILINE_ITERATOR_NAV_IID \
+ { 0x80aa3d7a, 0xe0bf, 0x4e18,{0x8a, 0x82, 0x21, 0x10, 0x39, 0x7d, 0x7b, 0xc4}}
+
+// Line iterator API.
+//
+// Lines are numbered from 0 to N, where 0 is the top line and N is
+// the bottom line.
+//
+// NOTE: while you can get this interface by doing a slezy hacky
+// QueryInterface on block frames, it isn't like a normal com
+// interface: it's not reflexive (you can't query back to the block
+// frame) and unlike other frames, it *IS* reference counted so don't
+// forget to NS_RELEASE it when you are done with it!
// Line Flags (see GetLine below)
@@ -52,36 +67,17 @@ struct nsRect;
// This bit is set when the line ends in some sort of break.
#define NS_LINE_FLAG_ENDS_IN_BREAK 0x4
-/**
- * Line iterator API.
- *
- * Lines are numbered from 0 to N, where 0 is the top line and N is
- * the bottom line.
- *
- * Obtain this interface from frames via nsIFrame::GetLineIterator.
- * When you are finished using the iterator, call DisposeLineIterator()
- * to destroy the iterator if appropriate.
- */
-class nsILineIterator
-{
-protected:
- ~nsILineIterator() { }
-
+class nsILineIterator : public nsISupports {
public:
- virtual void DisposeLineIterator() = 0;
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_ILINE_ITERATOR_IID)
- /**
- * The number of lines in the block
- */
- virtual PRInt32 GetNumLines() = 0;
+ // Return the number of lines in the block.
+ NS_IMETHOD GetNumLines(PRInt32* aResult) = 0;
- /**
- * The prevailing direction of lines.
- *
- * @return PR_TRUE if the CSS direction property for the block is
- * "rtl", otherwise PR_FALSE
- */
- virtual PRBool GetDirection() = 0;
+ // Return the prevailing direction for the line. aIsRightToLeft will
+ // be set to PR_TRUE if the CSS direction property for the block is
+ // "rtl", otherwise aIsRightToLeft will be set to PR_FALSE.
+ NS_IMETHOD GetDirection(PRBool* aIsRightToLeft) = 0;
// Return structural information about a line. aFirstFrameOnLine is
// the first frame on the line and aNumFramesOnLine is the number of
@@ -102,20 +98,19 @@ public:
nsRect& aLineBounds,
PRUint32* aLineFlags) = 0;
- /**
- * Given a frame that's a child of the block, find which line its on
- * and return that line index. Returns -1 if the frame cannot be found.
- */
- virtual PRInt32 FindLineContaining(nsIFrame* aFrame) = 0;
+ // Given a frame that's a child of the block, find which line its on
+ // and return that line index into aIndexResult. aIndexResult will
+ // be set to -1 if the frame cannot be found.
+ NS_IMETHOD FindLineContaining(nsIFrame* aFrame,
+ PRInt32* aLineNumberResult) = 0;
- /**
- * Given a Y coordinate relative to the block that provided this
- * line iterator, return the line that contains the Y
- * coordinate. Returns -1 in aLineNumberResult if the Y coordinate
- * is above the first line. Returns N (where N is the number of
- * lines) if the Y coordinate is below the last line.
- */
- virtual PRInt32 FindLineAt(nscoord aY) = 0;
+ // Given a Y coordinate relative to the block that provided this
+ // line iterator, find the line that contains the Y
+ // coordinate. Returns -1 in aLineNumberResult if the Y coordinate
+ // is above the first line. Returns N (where N is the number of
+ // lines) if the Y coordinate is below the last line.
+ NS_IMETHOD FindLineAt(nscoord aY,
+ PRInt32* aLineNumberResult) = 0;
// Given a line number and an X coordinate, find the frame on the
// line that is nearest to the X coordinate. The
@@ -141,30 +136,15 @@ public:
#endif
};
-class nsAutoLineIterator
-{
+NS_DEFINE_STATIC_IID_ACCESSOR(nsILineIterator, NS_ILINE_ITERATOR_IID)
+
+//special line iterator for keyboard navigation
+class nsILineIteratorNavigator : public nsILineIterator {
public:
- nsAutoLineIterator() : mRawPtr(nsnull) { }
- nsAutoLineIterator(nsILineIterator *i) : mRawPtr(i) { }
-
- ~nsAutoLineIterator() {
- if (mRawPtr)
- mRawPtr->DisposeLineIterator();
- }
-
- operator nsILineIterator*() { return mRawPtr; }
- nsILineIterator* operator->() { return mRawPtr; }
-
- nsILineIterator* operator=(nsILineIterator* i) {
- if (mRawPtr)
- mRawPtr->DisposeLineIterator();
-
- mRawPtr = i;
- return i;
- }
-
-private:
- nsILineIterator* mRawPtr;
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_ILINE_ITERATOR_NAV_IID)
};
+NS_DEFINE_STATIC_IID_ACCESSOR(nsILineIteratorNavigator,
+ NS_ILINE_ITERATOR_NAV_IID)
+
#endif /* nsILineIterator_h___ */
diff --git a/layout/generic/nsLineBox.cpp b/layout/generic/nsLineBox.cpp
index 566a50a5b6d0..047598dcf3f2 100644
--- a/layout/generic/nsLineBox.cpp
+++ b/layout/generic/nsLineBox.cpp
@@ -543,11 +543,7 @@ nsLineIterator::~nsLineIterator()
}
}
-/* virtual */ void
-nsLineIterator::DisposeLineIterator()
-{
- delete this;
-}
+NS_IMPL_ISUPPORTS2(nsLineIterator, nsILineIterator, nsILineIteratorNavigator)
nsresult
nsLineIterator::Init(nsLineList& aLines, PRBool aRightToLeft)
@@ -582,16 +578,26 @@ nsLineIterator::Init(nsLineList& aLines, PRBool aRightToLeft)
return NS_OK;
}
-PRInt32
-nsLineIterator::GetNumLines()
+NS_IMETHODIMP
+nsLineIterator::GetNumLines(PRInt32* aResult)
{
- return mNumLines;
+ NS_PRECONDITION(aResult, "null OUT ptr");
+ if (!aResult) {
+ return NS_ERROR_NULL_POINTER;
+ }
+ *aResult = mNumLines;
+ return NS_OK;
}
-PRBool
-nsLineIterator::GetDirection()
+NS_IMETHODIMP
+nsLineIterator::GetDirection(PRBool* aIsRightToLeft)
{
- return mRightToLeft;
+ NS_PRECONDITION(aIsRightToLeft, "null OUT ptr");
+ if (!aIsRightToLeft) {
+ return NS_ERROR_NULL_POINTER;
+ }
+ *aIsRightToLeft = mRightToLeft;
+ return NS_OK;
}
NS_IMETHODIMP
@@ -629,35 +635,42 @@ nsLineIterator::GetLine(PRInt32 aLineNumber,
return NS_OK;
}
-PRInt32
-nsLineIterator::FindLineContaining(nsIFrame* aFrame)
+NS_IMETHODIMP
+nsLineIterator::FindLineContaining(nsIFrame* aFrame,
+ PRInt32* aLineNumberResult)
{
nsLineBox* line = mLines[0];
PRInt32 lineNumber = 0;
while (lineNumber != mNumLines) {
if (line->Contains(aFrame)) {
- return lineNumber;
+ *aLineNumberResult = lineNumber;
+ return NS_OK;
}
line = mLines[++lineNumber];
}
- return -1;
+ *aLineNumberResult = -1;
+ return NS_OK;
}
-/* virtual */ PRInt32
-nsLineIterator::FindLineAt(nscoord aY)
+NS_IMETHODIMP
+nsLineIterator::FindLineAt(nscoord aY,
+ PRInt32* aLineNumberResult)
{
nsLineBox* line = mLines[0];
if (!line || (aY < line->mBounds.y)) {
- return -1;
+ *aLineNumberResult = -1;
+ return NS_OK;
}
PRInt32 lineNumber = 0;
while (lineNumber != mNumLines) {
if ((aY >= line->mBounds.y) && (aY < line->mBounds.YMost())) {
- return lineNumber;
+ *aLineNumberResult = lineNumber;
+ return NS_OK;
}
line = mLines[++lineNumber];
}
- return mNumLines;
+ *aLineNumberResult = mNumLines;
+ return NS_OK;
}
#ifdef IBMBIDI
diff --git a/layout/generic/nsLineBox.h b/layout/generic/nsLineBox.h
index fb1230b2841c..0ed5fb5c7306 100644
--- a/layout/generic/nsLineBox.h
+++ b/layout/generic/nsLineBox.h
@@ -1508,23 +1508,24 @@ nsLineList_const_reverse_iterator::operator=(const nsLineList_const_reverse_iter
//----------------------------------------------------------------------
-class NS_FINAL_CLASS nsLineIterator : public nsILineIterator
-{
+class nsLineIterator : public nsILineIteratorNavigator {
public:
nsLineIterator();
- ~nsLineIterator();
+ virtual ~nsLineIterator();
- virtual void DisposeLineIterator();
+ NS_DECL_ISUPPORTS
- virtual PRInt32 GetNumLines();
- virtual PRBool GetDirection();
+ NS_IMETHOD GetNumLines(PRInt32* aResult);
+ NS_IMETHOD GetDirection(PRBool* aIsRightToLeft);
NS_IMETHOD GetLine(PRInt32 aLineNumber,
nsIFrame** aFirstFrameOnLine,
PRInt32* aNumFramesOnLine,
nsRect& aLineBounds,
PRUint32* aLineFlags);
- virtual PRInt32 FindLineContaining(nsIFrame* aFrame);
- virtual PRInt32 FindLineAt(nscoord aY);
+ NS_IMETHOD FindLineContaining(nsIFrame* aFrame,
+ PRInt32* aLineNumberResult);
+ NS_IMETHOD FindLineAt(nscoord aY,
+ PRInt32* aLineNumberResult);
NS_IMETHOD FindFrameAt(PRInt32 aLineNumber,
nscoord aX,
nsIFrame** aFrameFound,
@@ -1540,7 +1541,15 @@ public:
#endif
nsresult Init(nsLineList& aLines, PRBool aRightToLeft);
-private:
+protected:
+ PRInt32 NumLines() const {
+ return mNumLines;
+ }
+
+ nsLineBox* CurrentLine() {
+ return mLines[mIndex];
+ }
+
nsLineBox* PrevLine() {
if (0 == mIndex) {
return nsnull;
diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp
index 2108a6373153..69f9abd9b206 100644
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -64,6 +64,17 @@ nsTableRowGroupFrame::~nsTableRowGroupFrame()
{
}
+/* ----------- nsTableRowGroupFrame ---------- */
+nsrefcnt nsTableRowGroupFrame::AddRef(void)
+{
+ return 1;//implementation of nsLineIterator
+}
+
+nsrefcnt nsTableRowGroupFrame::Release(void)
+{
+ return 1;//implementation of nsLineIterator
+}
+
NS_IMETHODIMP
nsTableRowGroupFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
@@ -74,6 +85,14 @@ nsTableRowGroupFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
*aInstancePtr = (void*)this;
return NS_OK;
}
+ if (aIID.Equals(NS_GET_IID(nsILineIteratorNavigator))) {
+ *aInstancePtr = static_cast(this);
+ return NS_OK;
+ }
+ if (aIID.Equals(NS_GET_IID(nsILineIterator))) {
+ *aInstancePtr = static_cast(this);
+ return NS_OK;
+ }
return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr);
}
@@ -1634,18 +1653,23 @@ void nsTableRowGroupFrame::SetContinuousBCBorderWidth(PRUint8 aForSide,
}
//nsILineIterator methods
-PRInt32
-nsTableRowGroupFrame::GetNumLines()
+NS_IMETHODIMP
+nsTableRowGroupFrame::GetNumLines(PRInt32* aResult)
{
- return GetRowCount();
+ NS_ENSURE_ARG_POINTER(aResult);
+ *aResult = GetRowCount();
+ return NS_OK;
}
-PRBool
-nsTableRowGroupFrame::GetDirection()
+NS_IMETHODIMP
+nsTableRowGroupFrame::GetDirection(PRBool* aIsRightToLeft)
{
+ NS_ENSURE_ARG_POINTER(aIsRightToLeft);
+ // rtl is table wide @see nsTableIterator
nsTableFrame* table = nsTableFrame::GetTableFrame(this);
- return (NS_STYLE_DIRECTION_RTL ==
- table->GetStyleVisibility()->mDirection);
+ *aIsRightToLeft = (NS_STYLE_DIRECTION_RTL ==
+ table->GetStyleVisibility()->mDirection);
+ return NS_OK;
}
NS_IMETHODIMP
@@ -1690,25 +1714,28 @@ nsTableRowGroupFrame::GetLine(PRInt32 aLineNumber,
return NS_ERROR_FAILURE;
}
-PRInt32
-nsTableRowGroupFrame::FindLineContaining(nsIFrame* aFrame)
+NS_IMETHODIMP
+nsTableRowGroupFrame::FindLineContaining(nsIFrame* aFrame,
+ PRInt32* aLineNumberResult)
{
NS_ENSURE_ARG_POINTER(aFrame);
+ NS_ENSURE_ARG_POINTER(aLineNumberResult);
NS_ASSERTION((aFrame->GetType() == nsGkAtoms::tableRowFrame),
"RowGroup contains a frame that is not a row");
nsTableRowFrame* rowFrame = (nsTableRowFrame*)aFrame;
- return rowFrame->GetRowIndex() - GetStartRowIndex();
+ *aLineNumberResult = rowFrame->GetRowIndex() - GetStartRowIndex();
+
+ return NS_OK;
}
-PRInt32
-nsTableRowGroupFrame::FindLineAt(nscoord aY)
+NS_IMETHODIMP
+nsTableRowGroupFrame::FindLineAt(nscoord aY,
+ PRInt32* aLineNumberResult)
{
- NS_NOTREACHED("Not implemented");
return NS_ERROR_NOT_IMPLEMENTED;
}
-
#ifdef IBMBIDI
NS_IMETHODIMP
nsTableRowGroupFrame::CheckLineOrder(PRInt32 aLine,
diff --git a/layout/tables/nsTableRowGroupFrame.h b/layout/tables/nsTableRowGroupFrame.h
index 5319bf2e11a0..b35298814970 100644
--- a/layout/tables/nsTableRowGroupFrame.h
+++ b/layout/tables/nsTableRowGroupFrame.h
@@ -96,12 +96,11 @@ struct nsRowGroupReflowState {
* @see nsTableFrame
* @see nsTableRowFrame
*/
-class nsTableRowGroupFrame
- : public nsHTMLContainerFrame
- , public nsILineIterator
+class nsTableRowGroupFrame : public nsHTMLContainerFrame, public nsILineIteratorNavigator
{
public:
- NS_IMETHOD QueryInterface(const nsIID &aIID, void **aInstancePtr);
+ // nsISupports
+ NS_DECL_ISUPPORTS_INHERITED
/** instantiate a new instance of nsTableRowFrame.
* @param aPresShell the pres shell for this frame
@@ -228,8 +227,6 @@ public:
// nsILineIterator methods
public:
- virtual void DisposeLineIterator() { }
-
// The table row is the equivalent to a line in block layout.
// The nsILineIterator assumes that a line resides in a block, this role is
// fullfilled by the row group. Rows in table are counted relative to the
@@ -238,14 +235,14 @@ public:
// row index of the first row in the row group.
/** Get the number of rows in a row group
- * @return the number of lines in a row group
+ * @param aResult - pointer that holds the number of lines in a row group
*/
- virtual PRInt32 GetNumLines();
+ NS_IMETHOD GetNumLines(PRInt32* aResult);
/** @see nsILineIterator.h GetDirection
- * @return true if the table is rtl
+ * @param aIsRightToLeft - true if the table is rtl
*/
- virtual PRBool GetDirection();
+ NS_IMETHOD GetDirection(PRBool* aIsRightToLeft);
/** Return structural information about a line.
* @param aLineNumber - the index of the row relative to the row group
@@ -267,15 +264,16 @@ public:
/** Given a frame that's a child of the rowgroup, find which line its on.
* @param aFrame - frame, should be a row
- * @return row index relative to the row group if this a row
- * frame. -1 if the frame cannot be found.
+ * @param aIndexResult - row index relative to the row group if this a row
+ * frame. aIndexResult will be set to -1 if the frame
+ * cannot be found.
*/
- virtual PRInt32 FindLineContaining(nsIFrame* aFrame);
+ NS_IMETHOD FindLineContaining(nsIFrame* aFrame, PRInt32* aLineNumberResult);
/** not implemented
* the function is also not called in our tree
*/
- virtual PRInt32 FindLineAt(nscoord aY);
+ NS_IMETHOD FindLineAt(nscoord aY, PRInt32* aLineNumberResult);
/** Find the orginating cell frame on a row that is the nearest to the
* coordinate X.
@@ -375,8 +373,6 @@ public:
GetStyleDisplay()->mOverflowY == NS_STYLE_OVERFLOW_CLIP;
}
- virtual nsILineIterator* GetLineIterator() { return this; }
-
protected:
nsTableRowGroupFrame(nsStyleContext* aContext);