зеркало из https://github.com/mozilla/gecko-dev.git
337 строки
7.2 KiB
C++
337 строки
7.2 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
* Reserved.
|
|
*/
|
|
#include "nsFrameTraversal.h"
|
|
#include "nsFrameList.h"
|
|
|
|
|
|
static NS_DEFINE_IID(kIEnumeratorIID, NS_IENUMERATOR_IID);
|
|
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
|
|
|
|
class nsFrameIterator: public nsIBidirectionalEnumerator
|
|
{
|
|
public:
|
|
NS_DECL_ISUPPORTS
|
|
|
|
NS_IMETHOD First();
|
|
|
|
NS_IMETHOD Last();
|
|
|
|
NS_IMETHOD Next()=0;
|
|
|
|
NS_IMETHOD Prev()=0;
|
|
|
|
NS_IMETHOD CurrentItem(nsISupports **aItem);
|
|
|
|
NS_IMETHOD IsDone();//what does this mean??off edge? yes
|
|
|
|
nsFrameIterator();
|
|
protected:
|
|
void setCurrent(nsIFrame *aFrame){mCurrent = aFrame;}
|
|
nsIFrame *getCurrent(){return mCurrent;}
|
|
void setStart(nsIFrame *aFrame){mStart = aFrame;}
|
|
nsIFrame *getStart(){return mStart;}
|
|
nsIFrame *getLast(){return mLast;}
|
|
void setLast(nsIFrame *aFrame){mLast = aFrame;}
|
|
PRInt8 getOffEdge(){return mOffEdge;}
|
|
void setOffEdge(PRInt8 aOffEdge){mOffEdge = aOffEdge;}
|
|
private:
|
|
nsIFrame *mStart;
|
|
nsIFrame *mCurrent;
|
|
nsIFrame *mLast; //the last one that was in current;
|
|
PRInt8 mOffEdge; //0= no -1 to far prev, 1 to far next;
|
|
};
|
|
|
|
|
|
/*
|
|
class nsFastFrameIterator: public nsFrameIterator
|
|
{
|
|
nsFastFrameIterator(nsIFrame *start);
|
|
private :
|
|
|
|
virtual nsresult Next();
|
|
|
|
virtual nsresult Prev();
|
|
|
|
}
|
|
*/
|
|
|
|
class nsLeafIterator: public nsFrameIterator
|
|
{
|
|
public:
|
|
nsLeafIterator(nsIFrame *start);
|
|
private :
|
|
|
|
NS_IMETHOD Next();
|
|
|
|
NS_IMETHOD Prev();
|
|
|
|
};
|
|
|
|
/************IMPLEMENTATIONS**************/
|
|
|
|
nsresult
|
|
NS_NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator, nsTraversalType aType, nsIFrame *aStart)
|
|
{
|
|
if (!aEnumerator || !aStart)
|
|
return NS_ERROR_NULL_POINTER;
|
|
switch(aType)
|
|
{
|
|
case LEAF: {
|
|
nsLeafIterator *trav = new nsLeafIterator(aStart);
|
|
if (!trav)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
*aEnumerator = NS_STATIC_CAST(nsIBidirectionalEnumerator*, trav);
|
|
NS_ADDREF(trav);
|
|
}
|
|
break;
|
|
#if 0
|
|
case EXTENSIVE:{
|
|
nsExtensiveTraversal *trav = new nsExtensiveTraversal(aStart);
|
|
if (!trav)
|
|
return NS_ERROR_NOMEMORY;
|
|
*aEnumerator = NS_STATIC_CAST(nsIBidirectionalEnumerator*, trav);
|
|
NS_ADDREF(trav);
|
|
}
|
|
break;
|
|
case FASTEST:{
|
|
nsFastestTraversal *trav = new nsFastestTraversal(aStart);
|
|
if (!trav)
|
|
return NS_ERROR_NOMEMORY;
|
|
*aEnumerator = NS_STATIC_CAST(nsIBidirectionalEnumerator*, trav);
|
|
NS_ADDREF(trav);
|
|
}
|
|
#endif
|
|
default:
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
break;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
|
|
/*********nsFrameIterator************/
|
|
NS_IMPL_ADDREF(nsFrameIterator)
|
|
|
|
NS_IMPL_RELEASE(nsFrameIterator)
|
|
|
|
|
|
|
|
nsFrameIterator::nsFrameIterator()
|
|
{
|
|
mOffEdge = 0;
|
|
mLast = nsnull;
|
|
mCurrent = nsnull;
|
|
mStart = nsnull;
|
|
NS_INIT_REFCNT();
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsFrameIterator::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|
{
|
|
if (NULL == aInstancePtr) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
if (aIID.Equals(kISupportsIID)) {
|
|
*aInstancePtr = (void *)(nsISupports *)this;
|
|
NS_ADDREF_THIS();
|
|
return NS_OK;
|
|
}
|
|
if (aIID.Equals(kIEnumeratorIID)) {
|
|
*aInstancePtr = (void*)NS_STATIC_CAST(nsIEnumerator*, this);
|
|
NS_ADDREF_THIS();
|
|
return NS_OK;
|
|
}
|
|
return NS_NOINTERFACE;
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsFrameIterator::CurrentItem(nsISupports **aItem)
|
|
{
|
|
if (!aItem)
|
|
return NS_ERROR_NULL_POINTER;
|
|
*aItem = mCurrent;
|
|
if (mOffEdge)
|
|
return NS_COMFALSE;
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsFrameIterator::IsDone()//what does this mean??off edge? yes
|
|
{
|
|
if (mOffEdge != 0)
|
|
return NS_OK;
|
|
return NS_COMFALSE;
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsFrameIterator::First()
|
|
{
|
|
mCurrent = mStart;
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsFrameIterator::Last()
|
|
{
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
|
|
|
|
/*********LEAFITERATOR**********/
|
|
|
|
|
|
nsLeafIterator::nsLeafIterator(nsIFrame *aStart)
|
|
{
|
|
setStart(aStart);
|
|
setCurrent(aStart);
|
|
setLast(aStart);
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsLeafIterator::Next()
|
|
{
|
|
//recursive-oid method to get next frame
|
|
nsIFrame *result;
|
|
nsIFrame *parent = getCurrent();
|
|
if (!parent)
|
|
parent = getLast();
|
|
while(NS_SUCCEEDED(parent->FirstChild(nsnull,&result)) && result)
|
|
{
|
|
parent = result;
|
|
}
|
|
if (parent != getCurrent())
|
|
{
|
|
result = parent;
|
|
}
|
|
else {
|
|
while(parent){
|
|
if (NS_SUCCEEDED(parent->GetNextSibling(&result)) && result){
|
|
parent = result;
|
|
while(NS_SUCCEEDED(parent->FirstChild(nsnull,&result)) && result)
|
|
{
|
|
parent = result;
|
|
}
|
|
result = parent;
|
|
break;
|
|
}
|
|
else
|
|
if (NS_FAILED(parent->GetParent(&result)) || !result){
|
|
result = nsnull;
|
|
break;
|
|
}
|
|
else
|
|
parent = result;
|
|
}
|
|
}
|
|
setCurrent(result);
|
|
if (!result)
|
|
setOffEdge(1);
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsLeafIterator::Prev()
|
|
{
|
|
//recursive-oid method to get prev frame
|
|
nsIFrame *result;
|
|
nsIFrame *parent = getCurrent();
|
|
if (!parent)
|
|
parent = getLast();
|
|
while(parent){
|
|
nsIFrame *grandParent;
|
|
if (NS_SUCCEEDED(parent->GetParent(&grandParent)) && grandParent &&
|
|
NS_SUCCEEDED(grandParent->FirstChild(nsnull,&result))){
|
|
nsFrameList list(result);
|
|
if (result = list.GetPrevSiblingFor(parent)){
|
|
parent = result;
|
|
while(NS_SUCCEEDED(parent->FirstChild(nsnull,&result)) && result){
|
|
parent = result;
|
|
while(NS_SUCCEEDED(parent->GetNextSibling(&result)) && result){
|
|
parent = result;
|
|
}
|
|
}
|
|
result = parent;
|
|
break;
|
|
}
|
|
else if (NS_FAILED(parent->GetParent(&result)) || !result){
|
|
result = nsnull;
|
|
break;
|
|
}
|
|
else
|
|
parent = result;
|
|
}
|
|
else{
|
|
setLast(parent);
|
|
result = nsnull;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/* while(parent){
|
|
nsIFrame *grandParent;
|
|
if (NS_SUCCEEDED(parent->GetParent(&grandParent)) && grandParent){
|
|
nsIFrame * grandFchild;
|
|
if (NS_SUCCEEDED(grandParent->FirstChild(nsnull,&grandFchild)) && grandFchild){
|
|
nsFrameList list(grandFchild);
|
|
if (nsnull != (result = list.GetPrevSiblingFor(parent)) ){
|
|
parent = result;
|
|
while(NS_SUCCEEDED(parent->FirstChild(nsnull,&result)) && result){
|
|
parent = result;
|
|
while(NS_SUCCEEDED(parent->GetNextSibling(&result)) && result){
|
|
parent = result;
|
|
}
|
|
}
|
|
result = parent;
|
|
break;
|
|
}
|
|
else
|
|
if (NS_FAILED(parent->GetParent(&result)) || !result){
|
|
result = nsnull;
|
|
break;
|
|
}
|
|
else
|
|
parent = result;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
setCurrent(result);
|
|
if (!result)
|
|
setOffEdge(-1);
|
|
return NS_OK;
|
|
}
|