Added generated content iterator

This commit is contained in:
troy%netscape.com 2000-03-23 21:05:23 +00:00
Родитель 7dd37e5b9c
Коммит d82789f57c
2 изменённых файлов: 558 добавлений и 4 удалений

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

@ -652,13 +652,290 @@ GetChildListNameFor(nsIPresContext* aPresContext,
*aListName = listName;
}
class GeneratedContentIterator : public nsIContentIterator
{
public:
GeneratedContentIterator(nsIPresContext* aPresContext, nsIFrame* aFrame);
virtual ~GeneratedContentIterator();
// nsISupports
NS_DECL_ISUPPORTS
// nsIContentIterator
NS_IMETHOD Init(nsIContent* aRoot);
NS_IMETHOD Init(nsIDOMRange* aRange);
NS_IMETHOD First();
NS_IMETHOD Last();
NS_IMETHOD Next();
NS_IMETHOD Prev();
NS_IMETHOD CurrentNode(nsIContent **aNode);
NS_IMETHOD IsDone();
NS_IMETHOD PositionAt(nsIContent* aCurNode);
NS_IMETHOD MakePre();
NS_IMETHOD MakePost();
private:
nsCOMPtr<nsIPresContext> mPresContext;
nsIFrame* mParentFrame;
nsIFrame* mCurrentChild;
PRBool mIsDone;
};
GeneratedContentIterator::GeneratedContentIterator(nsIPresContext* aPresContext,
nsIFrame* aFrame)
: mPresContext(aPresContext), mParentFrame(aFrame), mIsDone(PR_FALSE)
{
NS_INIT_REFCNT();
First();
}
NS_IMPL_ISUPPORTS(GeneratedContentIterator, NS_GET_IID(nsIContentIterator));
GeneratedContentIterator::~GeneratedContentIterator()
{
}
NS_IMETHODIMP
GeneratedContentIterator::Init(nsIContent* aRoot)
{
return NS_ERROR_ALREADY_INITIALIZED;
}
NS_IMETHODIMP
GeneratedContentIterator::Init(nsIDOMRange* aRange)
{
return NS_ERROR_ALREADY_INITIALIZED;
}
NS_IMETHODIMP
GeneratedContentIterator::First()
{
// Get the first child frame and make it the current node
mParentFrame->FirstChild(mPresContext, nsnull, &mCurrentChild);
if (!mCurrentChild) {
return NS_ERROR_FAILURE;
}
mIsDone = PR_FALSE;
return NS_OK;
}
static nsIFrame*
GetNextChildFrame(nsIPresContext* aPresContext, nsIFrame* aFrame)
{
NS_PRECONDITION(aFrame, "null pointer");
// Get the last-in-flow
while (PR_TRUE) {
nsIFrame* nextInFlow;
aFrame->GetNextInFlow(&nextInFlow);
if (nextInFlow) {
aFrame = nextInFlow;
} else {
break;
}
}
// Get its next sibling
nsIFrame* nextSibling;
aFrame->GetNextSibling(&nextSibling);
// If there's no next sibling, then check if the parent frame
// has a next-in-flow and look there
if (!nextSibling) {
nsIFrame* parent;
aFrame->GetParent(&parent);
parent->GetNextInFlow(&parent);
if (parent) {
parent->FirstChild(aPresContext, nsnull, &nextSibling);
}
}
return nextSibling;
}
NS_IMETHODIMP
GeneratedContentIterator::Last()
{
nsIFrame* nextChild;
// Starting with the first child walk and find the last child
mCurrentChild = nsnull;
mParentFrame->FirstChild(mPresContext, nsnull, &nextChild);
while (nextChild) {
mCurrentChild = nextChild;
nextChild = ::GetNextChildFrame(mPresContext, nextChild);
}
if (!mCurrentChild) {
return NS_ERROR_FAILURE;
}
mIsDone = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
GeneratedContentIterator::Next()
{
nsIFrame* nextChild = ::GetNextChildFrame(mPresContext, mCurrentChild);
if (nextChild) {
// Advance to the next child
mCurrentChild = nextChild;
// If we're at the end then the collection is at the end
mIsDone = (nsnull == ::GetNextChildFrame(mPresContext, mCurrentChild));
return NS_OK;
}
return NS_ERROR_FAILURE;
}
static nsIFrame*
GetPrevChildFrame(nsIPresContext* aPresContext, nsIFrame* aFrame)
{
NS_PRECONDITION(aFrame, "null pointer");
// Get its previous sibling. Because we have a singly linked list we
// need to search from the first child
nsIFrame* parent;
nsIFrame* firstChild;
nsIFrame* prevSibling;
aFrame->GetParent(&parent);
parent->FirstChild(aPresContext, nsnull, &firstChild);
NS_ASSERTION(firstChild, "parent has no first child");
nsFrameList frameList(firstChild);
prevSibling = frameList.GetPrevSiblingFor(aFrame);
// If there's no previous sibling, then check if the parent frame
// has a prev-in-flow and look there
if (!prevSibling) {
parent->GetPrevInFlow(&parent);
if (parent) {
parent->FirstChild(aPresContext, nsnull, &firstChild);
frameList.SetFrames(firstChild);
prevSibling = frameList.LastChild();
}
}
// Get the first-in-flow
while (PR_TRUE) {
nsIFrame* prevInFlow;
prevSibling->GetPrevInFlow(&prevInFlow);
if (prevInFlow) {
prevSibling = prevInFlow;
} else {
break;
}
}
return prevSibling;
}
NS_IMETHODIMP
GeneratedContentIterator::Prev()
{
nsIFrame* prevChild = ::GetPrevChildFrame(mPresContext, mCurrentChild);
if (prevChild) {
// Make the previous child the current child
mCurrentChild = prevChild;
// If we're at the beginning then the collection is at the end
mIsDone = (nsnull == ::GetPrevChildFrame(mPresContext, mCurrentChild));
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
GeneratedContentIterator::CurrentNode(nsIContent **aNode)
{
if (mCurrentChild) {
mCurrentChild->GetContent(aNode);
return NS_OK;
} else {
*aNode = nsnull;
return NS_ERROR_FAILURE;
}
}
NS_IMETHODIMP
GeneratedContentIterator::IsDone()
{
return mIsDone ? NS_OK : NS_ENUMERATOR_FALSE;
}
NS_IMETHODIMP
GeneratedContentIterator::PositionAt(nsIContent* aCurNode)
{
nsIFrame* child;
// Starting with the first child frame search for the child frame
// with the matching content object
mParentFrame->FirstChild(mPresContext, nsnull, &child);
while (child) {
nsCOMPtr<nsIContent> content;
child->GetContent(getter_AddRefs(content));
if (content.get() == aCurNode) {
break;
}
child = ::GetNextChildFrame(mPresContext, child);
}
if (child) {
// Make it the current child
mCurrentChild = child;
mIsDone = PR_FALSE;
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
GeneratedContentIterator::MakePre()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
GeneratedContentIterator::MakePost()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
NS_NewGeneratedContentIterator(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIContentIterator** aIterator)
{
*aIterator = nsnull;
return NS_ERROR_NOT_IMPLEMENTED;
NS_ENSURE_ARG_POINTER(aIterator);
if (!aIterator) {
return NS_ERROR_NULL_POINTER;
}
// Make sure the frame corresponds to generated content
#ifdef DEBUG
nsFrameState frameState;
aFrame->GetFrameState(&frameState);
NS_ASSERTION(frameState & NS_FRAME_GENERATED_CONTENT, "unexpected frame");
#endif
GeneratedContentIterator* it = new GeneratedContentIterator(aPresContext, aFrame);
if (!it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(NS_GET_IID(nsIContentIterator), (void **)aIterator);
}
nsresult

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

@ -652,13 +652,290 @@ GetChildListNameFor(nsIPresContext* aPresContext,
*aListName = listName;
}
class GeneratedContentIterator : public nsIContentIterator
{
public:
GeneratedContentIterator(nsIPresContext* aPresContext, nsIFrame* aFrame);
virtual ~GeneratedContentIterator();
// nsISupports
NS_DECL_ISUPPORTS
// nsIContentIterator
NS_IMETHOD Init(nsIContent* aRoot);
NS_IMETHOD Init(nsIDOMRange* aRange);
NS_IMETHOD First();
NS_IMETHOD Last();
NS_IMETHOD Next();
NS_IMETHOD Prev();
NS_IMETHOD CurrentNode(nsIContent **aNode);
NS_IMETHOD IsDone();
NS_IMETHOD PositionAt(nsIContent* aCurNode);
NS_IMETHOD MakePre();
NS_IMETHOD MakePost();
private:
nsCOMPtr<nsIPresContext> mPresContext;
nsIFrame* mParentFrame;
nsIFrame* mCurrentChild;
PRBool mIsDone;
};
GeneratedContentIterator::GeneratedContentIterator(nsIPresContext* aPresContext,
nsIFrame* aFrame)
: mPresContext(aPresContext), mParentFrame(aFrame), mIsDone(PR_FALSE)
{
NS_INIT_REFCNT();
First();
}
NS_IMPL_ISUPPORTS(GeneratedContentIterator, NS_GET_IID(nsIContentIterator));
GeneratedContentIterator::~GeneratedContentIterator()
{
}
NS_IMETHODIMP
GeneratedContentIterator::Init(nsIContent* aRoot)
{
return NS_ERROR_ALREADY_INITIALIZED;
}
NS_IMETHODIMP
GeneratedContentIterator::Init(nsIDOMRange* aRange)
{
return NS_ERROR_ALREADY_INITIALIZED;
}
NS_IMETHODIMP
GeneratedContentIterator::First()
{
// Get the first child frame and make it the current node
mParentFrame->FirstChild(mPresContext, nsnull, &mCurrentChild);
if (!mCurrentChild) {
return NS_ERROR_FAILURE;
}
mIsDone = PR_FALSE;
return NS_OK;
}
static nsIFrame*
GetNextChildFrame(nsIPresContext* aPresContext, nsIFrame* aFrame)
{
NS_PRECONDITION(aFrame, "null pointer");
// Get the last-in-flow
while (PR_TRUE) {
nsIFrame* nextInFlow;
aFrame->GetNextInFlow(&nextInFlow);
if (nextInFlow) {
aFrame = nextInFlow;
} else {
break;
}
}
// Get its next sibling
nsIFrame* nextSibling;
aFrame->GetNextSibling(&nextSibling);
// If there's no next sibling, then check if the parent frame
// has a next-in-flow and look there
if (!nextSibling) {
nsIFrame* parent;
aFrame->GetParent(&parent);
parent->GetNextInFlow(&parent);
if (parent) {
parent->FirstChild(aPresContext, nsnull, &nextSibling);
}
}
return nextSibling;
}
NS_IMETHODIMP
GeneratedContentIterator::Last()
{
nsIFrame* nextChild;
// Starting with the first child walk and find the last child
mCurrentChild = nsnull;
mParentFrame->FirstChild(mPresContext, nsnull, &nextChild);
while (nextChild) {
mCurrentChild = nextChild;
nextChild = ::GetNextChildFrame(mPresContext, nextChild);
}
if (!mCurrentChild) {
return NS_ERROR_FAILURE;
}
mIsDone = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
GeneratedContentIterator::Next()
{
nsIFrame* nextChild = ::GetNextChildFrame(mPresContext, mCurrentChild);
if (nextChild) {
// Advance to the next child
mCurrentChild = nextChild;
// If we're at the end then the collection is at the end
mIsDone = (nsnull == ::GetNextChildFrame(mPresContext, mCurrentChild));
return NS_OK;
}
return NS_ERROR_FAILURE;
}
static nsIFrame*
GetPrevChildFrame(nsIPresContext* aPresContext, nsIFrame* aFrame)
{
NS_PRECONDITION(aFrame, "null pointer");
// Get its previous sibling. Because we have a singly linked list we
// need to search from the first child
nsIFrame* parent;
nsIFrame* firstChild;
nsIFrame* prevSibling;
aFrame->GetParent(&parent);
parent->FirstChild(aPresContext, nsnull, &firstChild);
NS_ASSERTION(firstChild, "parent has no first child");
nsFrameList frameList(firstChild);
prevSibling = frameList.GetPrevSiblingFor(aFrame);
// If there's no previous sibling, then check if the parent frame
// has a prev-in-flow and look there
if (!prevSibling) {
parent->GetPrevInFlow(&parent);
if (parent) {
parent->FirstChild(aPresContext, nsnull, &firstChild);
frameList.SetFrames(firstChild);
prevSibling = frameList.LastChild();
}
}
// Get the first-in-flow
while (PR_TRUE) {
nsIFrame* prevInFlow;
prevSibling->GetPrevInFlow(&prevInFlow);
if (prevInFlow) {
prevSibling = prevInFlow;
} else {
break;
}
}
return prevSibling;
}
NS_IMETHODIMP
GeneratedContentIterator::Prev()
{
nsIFrame* prevChild = ::GetPrevChildFrame(mPresContext, mCurrentChild);
if (prevChild) {
// Make the previous child the current child
mCurrentChild = prevChild;
// If we're at the beginning then the collection is at the end
mIsDone = (nsnull == ::GetPrevChildFrame(mPresContext, mCurrentChild));
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
GeneratedContentIterator::CurrentNode(nsIContent **aNode)
{
if (mCurrentChild) {
mCurrentChild->GetContent(aNode);
return NS_OK;
} else {
*aNode = nsnull;
return NS_ERROR_FAILURE;
}
}
NS_IMETHODIMP
GeneratedContentIterator::IsDone()
{
return mIsDone ? NS_OK : NS_ENUMERATOR_FALSE;
}
NS_IMETHODIMP
GeneratedContentIterator::PositionAt(nsIContent* aCurNode)
{
nsIFrame* child;
// Starting with the first child frame search for the child frame
// with the matching content object
mParentFrame->FirstChild(mPresContext, nsnull, &child);
while (child) {
nsCOMPtr<nsIContent> content;
child->GetContent(getter_AddRefs(content));
if (content.get() == aCurNode) {
break;
}
child = ::GetNextChildFrame(mPresContext, child);
}
if (child) {
// Make it the current child
mCurrentChild = child;
mIsDone = PR_FALSE;
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
GeneratedContentIterator::MakePre()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
GeneratedContentIterator::MakePost()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
NS_NewGeneratedContentIterator(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIContentIterator** aIterator)
{
*aIterator = nsnull;
return NS_ERROR_NOT_IMPLEMENTED;
NS_ENSURE_ARG_POINTER(aIterator);
if (!aIterator) {
return NS_ERROR_NULL_POINTER;
}
// Make sure the frame corresponds to generated content
#ifdef DEBUG
nsFrameState frameState;
aFrame->GetFrameState(&frameState);
NS_ASSERTION(frameState & NS_FRAME_GENERATED_CONTENT, "unexpected frame");
#endif
GeneratedContentIterator* it = new GeneratedContentIterator(aPresContext, aFrame);
if (!it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(NS_GET_IID(nsIContentIterator), (void **)aIterator);
}
nsresult