зеркало из https://github.com/mozilla/gecko-dev.git
Added generated content iterator
This commit is contained in:
Родитель
7dd37e5b9c
Коммит
d82789f57c
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче