moving nsFrameTraversal.* nsFrameList.* to layout/base also adding selection from keyboard.

This commit is contained in:
mjudge%netscape.com 1999-02-19 00:21:22 +00:00
Родитель a963ec4802
Коммит 8f129330d2
20 изменённых файлов: 1608 добавлений и 9 удалений

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

@ -0,0 +1,287 @@
#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 nsIEnumerator
{
public:
NS_DECL_ISUPPORTS
virtual nsresult First();
virtual nsresult Last();
virtual nsresult Next()=0;
virtual nsresult Prev()=0;
virtual nsresult CurrentItem(nsISupports **aItem);
virtual nsresult 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 :
virtual nsresult Next();
virtual nsresult Prev();
};
/************IMPLEMENTATIONS**************/
nsresult
NS_NewFrameTraversal(nsIEnumerator **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 = (nsIEnumerator *)trav;
NS_ADDREF(trav);
}
break;
#if 0
case EXTENSIVE:{
nsExtensiveTraversal *trav = new nsExtensiveTraversal(aStart);
if (!trav)
return NS_ERROR_NOMEMORY;
*aEnumerator = (nsIEnumerator *)trav;
NS_ADDREF(trav);
}
break;
case FASTEST:{
nsFastestTraversal *trav = new nsFastestTraversal(aStart);
if (!trav)
return NS_ERROR_NOMEMORY;
*aEnumerator = (nsIEnumerator *)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();
}
nsresult
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*)(nsIEnumerator*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
nsresult
nsFrameIterator::CurrentItem(nsISupports **aItem)
{
if (!aItem)
return NS_ERROR_NULL_POINTER;
*aItem = mCurrent;
return NS_OK;
}
nsresult
nsFrameIterator::IsDone()//what does this mean??off edge? yes
{
if (mOffEdge != 0)
return NS_OK;
return NS_COMFALSE;
}
nsresult
nsFrameIterator::First()
{
mCurrent = mStart;
return NS_OK;
}
nsresult
nsFrameIterator::Last()
{
return NS_ERROR_FAILURE;
}
/*********LEAFITERATOR**********/
nsLeafIterator::nsLeafIterator(nsIFrame *aStart)
{
setStart(aStart);
setCurrent(aStart);
setLast(aStart);
}
nsresult
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 nsnull;
}
nsresult
nsLeafIterator::Prev()
{
//recursive-oid method to get prev frame
nsIFrame *result;
nsIFrame *parent = getCurrent();
if (!parent)
return NS_ERROR_FAILURE;
parent = getLast();
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 (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 nsnull;
}

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

@ -0,0 +1,11 @@
#ifndef NSFRAMETRAVERSAL_H
#define NSFRAMETRAVERSAL_H
#include "nsIEnumerator.h"
#include "nsIFrame.h"
enum nsTraversalType{LEAF, EXTENSIVE, FASTEST};
nsresult NS_NewFrameTraversal(nsIEnumerator **aEnumerator, nsTraversalType aType, nsIFrame *aStart);
#endif //NSFRAMETRAVERSAL_H

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

@ -21,6 +21,8 @@ nsIPresContext.h
nsIPresShell.h
nsIReflowCommand.h
nsISpaceManager.h
nsFrameList.h
nsFrameTraversal.h
nsLayoutAtoms.h
nsStyleCoord.h
nsStyleStruct.h

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

@ -54,6 +54,8 @@ EXPORTS = \
nsIStyleSheet.h \
nsITextContent.h \
nsLayoutAtoms.h \
nsFrameList.h \
nsFrameTraversal.h \
nsStyleConsts.h \
nsStyleCoord.h \
nsStyleStruct.h \

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

@ -46,6 +46,8 @@ EXPORTS = \
nsIStyleSet.h \
nsIStyleSheet.h \
nsITextContent.h \
nsFrameList.h \
nsFrameTraversal.h \
nsLayoutAtoms.h \
nsStyleConsts.h \
nsStyleCoord.h \

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

@ -0,0 +1,135 @@
/* -*- 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 "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#ifndef nsFrameList_h___
#define nsFrameList_h___
#include "nsIFrame.h"
/**
* A class for managing a singly linked list of frames. Frames are
* linked together through their next-sibling pointer.
*/
class nsFrameList {
public:
nsFrameList() {
mFirstChild = nsnull;
}
nsFrameList(nsIFrame* aHead) {
mFirstChild = aHead;
}
~nsFrameList() {
}
void DeleteFrames(nsIPresContext& aPresContext);
void SetFrames(nsIFrame* aFrameList) {
mFirstChild = aFrameList;
}
void AppendFrames(nsIFrame* aParent, nsIFrame* aFrameList);
void AppendFrames(nsIFrame* aParent, nsFrameList& aFrameList) {
AppendFrames(aParent, aFrameList.mFirstChild);
aFrameList.mFirstChild = nsnull;
}
void AppendFrame(nsIFrame* aParent, nsIFrame* aFrame);
// Take aFrame out of the frame list. This also disconnects aFrame
// from the sibling list. This will return PR_FALSE if aFrame is
// nsnull or if aFrame is not in the list.
PRBool RemoveFrame(nsIFrame* aFrame);
// Remove the first child from the list. The caller is assumed to be
// holding a reference to the first child. This call is equivalent
// in behavior to calling RemoveFrame(FirstChild()).
PRBool RemoveFirstChild();
// Take aFrame out of the frame list and then delete it. This also
// disconnects aFrame from the sibling list. This will return
// PR_FALSE if aFrame is nsnull or if aFrame is not in the list.
PRBool DeleteFrame(nsIPresContext& aPresContext, nsIFrame* aFrame);
void InsertFrame(nsIFrame* aParent,
nsIFrame* aPrevSibling,
nsIFrame* aNewFrame);
void InsertFrames(nsIFrame* aParent,
nsIFrame* aPrevSibling,
nsIFrame* aFrameList);
void InsertFrames(nsIFrame* aParent, nsIFrame* aPrevSibling,
nsFrameList& aFrameList) {
InsertFrames(aParent, aPrevSibling, aFrameList.FirstChild());
aFrameList.mFirstChild = nsnull;
}
PRBool ReplaceFrame(nsIFrame* aParent,
nsIFrame* aOldFrame,
nsIFrame* aNewFrame);
PRBool ReplaceAndDeleteFrame(nsIPresContext& aPresContext,
nsIFrame* aParent,
nsIFrame* aOldFrame,
nsIFrame* aNewFrame);
PRBool Split(nsIFrame* aAfterFrame, nsIFrame** aNextFrameResult);
nsIFrame* PullFrame(nsIFrame* aParent,
nsIFrame* aLastChild,
nsFrameList& aFromList);
void Join(nsIFrame* aParent, nsFrameList& aList) {
AppendFrames(aParent, aList.mFirstChild);
aList.mFirstChild = nsnull;
}
nsIFrame* FirstChild() const {
return mFirstChild;
}
nsIFrame* LastChild() const;
nsIFrame* FrameAt(PRInt32 aIndex) const;
PRBool IsEmpty() const {
return nsnull == mFirstChild;
}
PRBool NotEmpty() const {
return nsnull != mFirstChild;
}
PRBool ContainsFrame(const nsIFrame* aFrame) const;
PRInt32 GetLength() const;
nsIFrame* GetPrevSiblingFor(nsIFrame* aFrame) const;
void VerifyParent(nsIFrame* aParent) const;
void List(FILE* out) const;
protected:
nsIFrame* mFirstChild;
};
#endif /* nsFrameList_h___ */

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

@ -0,0 +1,11 @@
#ifndef NSFRAMETRAVERSAL_H
#define NSFRAMETRAVERSAL_H
#include "nsIEnumerator.h"
#include "nsIFrame.h"
enum nsTraversalType{LEAF, EXTENSIVE, FASTEST};
nsresult NS_NewFrameTraversal(nsIEnumerator **aEnumerator, nsTraversalType aType, nsIFrame *aStart);
#endif //NSFRAMETRAVERSAL_H

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

@ -38,6 +38,8 @@ CPPSRCS = \
nsDOMAttribute.cpp \
nsDOMAttributeMap.cpp \
nsFrameImageLoader.cpp \
nsFrameList.cpp \
nsFrameTraversal.cpp \
nsFrameUtil.cpp \
nsGalleyContext.cpp \
nsNameSpaceManager.cpp \

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

@ -35,6 +35,8 @@ CPPSRCS = \
nsDOMAttribute.cpp \
nsDOMAttributeMap.cpp \
nsFrameImageLoader.cpp \
nsFrameList.cpp \
nsFrameTraversal.cpp \
nsFrameUtil.cpp \
nsGalleyContext.cpp \
nsNameSpaceManager.cpp \
@ -70,6 +72,8 @@ CPP_OBJS= \
.\$(OBJDIR)\nsDOMAttribute.obj \
.\$(OBJDIR)\nsDOMAttributeMap.obj \
.\$(OBJDIR)\nsFrameImageLoader.obj \
.\$(OBJDIR)\nsFrameList.obj \
.\$(OBJDIR)\nsFrameTraversal.obj \
.\$(OBJDIR)\nsFrameUtil.obj \
.\$(OBJDIR)\nsGalleyContext.obj \
.\$(OBJDIR)\nsNameSpaceManager.obj \

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

@ -0,0 +1,361 @@
/* -*- 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 "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsFrameList.h"
#include "nsFrame.h"
void
nsFrameList::DeleteFrames(nsIPresContext& aPresContext)
{
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
nsIFrame* next;
frame->GetNextSibling(&next);
frame->DeleteFrame(aPresContext);
mFirstChild = frame = next;
}
}
void
nsFrameList::AppendFrames(nsIFrame* aParent, nsIFrame* aFrameList)
{
NS_PRECONDITION(nsnull != aFrameList, "null ptr");
if (nsnull != aFrameList) {
nsIFrame* lastChild = LastChild();
if (nsnull == lastChild) {
mFirstChild = aFrameList;
}
else {
lastChild->SetNextSibling(aFrameList);
}
if (nsnull != aParent) {
nsIFrame* frame = aFrameList;
while (nsnull != frame) {
frame->SetParent(aParent);
frame->GetNextSibling(&frame);
}
}
}
}
void
nsFrameList::AppendFrame(nsIFrame* aParent, nsIFrame* aFrame)
{
NS_PRECONDITION(nsnull != aFrame, "null ptr");
if (nsnull != aFrame) {
nsIFrame* lastChild = LastChild();
if (nsnull == lastChild) {
mFirstChild = aFrame;
}
else {
lastChild->SetNextSibling(aFrame);
}
if (nsnull != aParent) {
aFrame->SetParent(aParent);
}
}
}
PRBool
nsFrameList::RemoveFrame(nsIFrame* aFrame)
{
NS_PRECONDITION(nsnull != aFrame, "null ptr");
if (nsnull != aFrame) {
nsIFrame* nextFrame;
aFrame->GetNextSibling(&nextFrame);
aFrame->SetNextSibling(nsnull);
if (aFrame == mFirstChild) {
mFirstChild = nextFrame;
return PR_TRUE;
}
else {
nsIFrame* prevSibling = GetPrevSiblingFor(aFrame);
if (nsnull != prevSibling) {
prevSibling->SetNextSibling(nextFrame);
return PR_TRUE;
}
}
}
return PR_FALSE;
}
PRBool
nsFrameList::RemoveFirstChild()
{
if (nsnull != mFirstChild) {
nsIFrame* nextFrame;
mFirstChild->GetNextSibling(&nextFrame);
mFirstChild->SetNextSibling(nsnull);
mFirstChild = nextFrame;
return PR_TRUE;
}
return PR_FALSE;
}
PRBool
nsFrameList::DeleteFrame(nsIPresContext& aPresContext, nsIFrame* aFrame)
{
NS_PRECONDITION(nsnull != aFrame, "null ptr");
if (RemoveFrame(aFrame)) {
aFrame->DeleteFrame(aPresContext);
return PR_TRUE;
}
return PR_FALSE;
}
void
nsFrameList::InsertFrame(nsIFrame* aParent,
nsIFrame* aPrevSibling,
nsIFrame* aNewFrame)
{
NS_PRECONDITION(nsnull != aNewFrame, "null ptr");
if (nsnull != aNewFrame) {
if (nsnull == aPrevSibling) {
aNewFrame->SetNextSibling(mFirstChild);
mFirstChild = aNewFrame;
}
else {
nsIFrame* nextFrame;
aPrevSibling->GetNextSibling(&nextFrame);
aPrevSibling->SetNextSibling(aNewFrame);
aNewFrame->SetNextSibling(nextFrame);
}
if (nsnull != aParent) {
aNewFrame->SetParent(aParent);
}
}
}
void
nsFrameList::InsertFrames(nsIFrame* aParent,
nsIFrame* aPrevSibling,
nsIFrame* aFrameList)
{
NS_PRECONDITION(nsnull != aFrameList, "null ptr");
if (nsnull != aFrameList) {
if (nsnull != aParent) {
nsIFrame* frame = aFrameList;
while (nsnull != frame) {
frame->SetParent(aParent);
frame->GetNextSibling(&frame);
}
}
nsFrameList tmp(aFrameList);
nsIFrame* lastNewFrame = tmp.LastChild();
if (nsnull == aPrevSibling) {
lastNewFrame->SetNextSibling(mFirstChild);
mFirstChild = aFrameList;
}
else {
nsIFrame* nextFrame;
aPrevSibling->GetNextSibling(&nextFrame);
aPrevSibling->SetNextSibling(aFrameList);
lastNewFrame->SetNextSibling(nextFrame);
}
}
}
PRBool
nsFrameList::ReplaceFrame(nsIFrame* aParent,
nsIFrame* aOldFrame,
nsIFrame* aNewFrame)
{
NS_PRECONDITION(nsnull != aOldFrame, "null ptr");
NS_PRECONDITION(nsnull != aNewFrame, "null ptr");
if ((nsnull != aOldFrame) && (nsnull != aNewFrame)) {
nsIFrame* nextFrame;
aOldFrame->GetNextSibling(&nextFrame);
if (aOldFrame == mFirstChild) {
mFirstChild = aNewFrame;
aNewFrame->SetNextSibling(nextFrame);
}
else {
nsIFrame* prevSibling = GetPrevSiblingFor(aOldFrame);
if (nsnull != prevSibling) {
prevSibling->SetNextSibling(aNewFrame);
aNewFrame->SetNextSibling(nextFrame);
}
}
if (nsnull != aParent) {
aNewFrame->SetParent(aParent);
}
return PR_TRUE;
}
return PR_FALSE;
}
PRBool
nsFrameList::ReplaceAndDeleteFrame(nsIPresContext& aPresContext,
nsIFrame* aParent,
nsIFrame* aOldFrame,
nsIFrame* aNewFrame)
{
NS_PRECONDITION(nsnull != aOldFrame, "null ptr");
NS_PRECONDITION(nsnull != aNewFrame, "null ptr");
if (ReplaceFrame(aParent, aOldFrame, aNewFrame)) {
aNewFrame->DeleteFrame(aPresContext);
return PR_TRUE;
}
return PR_FALSE;
}
PRBool
nsFrameList::Split(nsIFrame* aAfterFrame, nsIFrame** aNextFrameResult)
{
NS_PRECONDITION(nsnull != aAfterFrame, "null ptr");
NS_PRECONDITION(nsnull != aNextFrameResult, "null ptr");
NS_ASSERTION(ContainsFrame(aAfterFrame), "split after unknown frame");
if ((nsnull != aNextFrameResult) && (nsnull != aAfterFrame)) {
nsIFrame* nextFrame;
aAfterFrame->GetNextSibling(&nextFrame);
aAfterFrame->SetNextSibling(nsnull);
*aNextFrameResult = nextFrame;
return PR_TRUE;
}
return PR_FALSE;
}
nsIFrame*
nsFrameList::PullFrame(nsIFrame* aParent,
nsIFrame* aLastChild,
nsFrameList& aFromList)
{
NS_PRECONDITION(nsnull != aParent, "null ptr");
nsIFrame* pulledFrame = nsnull;
if (nsnull != aParent) {
pulledFrame = aFromList.FirstChild();
if (nsnull != pulledFrame) {
// Take frame off old list
aFromList.RemoveFirstChild();
// Put it on the end of this list
if (nsnull == aLastChild) {
NS_ASSERTION(nsnull == mFirstChild, "bad aLastChild");
mFirstChild = pulledFrame;
}
else {
aLastChild->SetNextSibling(pulledFrame);
}
pulledFrame->SetParent(aParent);
}
}
return pulledFrame;
}
nsIFrame*
nsFrameList::LastChild() const
{
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
nsIFrame* next;
frame->GetNextSibling(&next);
if (nsnull == next) {
break;
}
frame = next;
}
return frame;
}
nsIFrame*
nsFrameList::FrameAt(PRInt32 aIndex) const
{
NS_PRECONDITION(aIndex >= 0, "invalid arg");
if (aIndex < 0) return nsnull;
nsIFrame* frame = mFirstChild;
while ((aIndex-- > 0) && (nsnull != frame)) {
frame->GetNextSibling(&frame);
}
return frame;
}
PRBool
nsFrameList::ContainsFrame(const nsIFrame* aFrame) const
{
NS_PRECONDITION(nsnull != aFrame, "null ptr");
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
if (frame == aFrame) {
return PR_TRUE;
}
frame->GetNextSibling(&frame);
}
return PR_FALSE;
}
PRInt32
nsFrameList::GetLength() const
{
PRInt32 count = 0;
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
count++;
frame->GetNextSibling(&frame);
}
return count;
}
nsIFrame*
nsFrameList::GetPrevSiblingFor(nsIFrame* aFrame) const
{
NS_PRECONDITION(nsnull != aFrame, "null ptr");
if (aFrame == mFirstChild) {
return nsnull;
}
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
nsIFrame* next;
frame->GetNextSibling(&next);
if (next == aFrame) {
break;
}
frame = next;
}
return frame;
}
void
nsFrameList::VerifyParent(nsIFrame* aParent) const
{
#ifdef NS_DEBUG
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
nsIFrame* parent;
frame->GetParent(&parent);
NS_ASSERTION(parent == aParent, "bad parent");
frame->GetNextSibling(&frame);
}
#endif
}
void
nsFrameList::List(FILE* out) const
{
fputs("<\n", out);
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
frame->List(out, 1);
// nsFrame::ListTag(out, frame);
// fputs(" ", out);
frame->GetNextSibling(&frame);
}
fputs("\n", out);
}

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

@ -0,0 +1,287 @@
#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 nsIEnumerator
{
public:
NS_DECL_ISUPPORTS
virtual nsresult First();
virtual nsresult Last();
virtual nsresult Next()=0;
virtual nsresult Prev()=0;
virtual nsresult CurrentItem(nsISupports **aItem);
virtual nsresult 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 :
virtual nsresult Next();
virtual nsresult Prev();
};
/************IMPLEMENTATIONS**************/
nsresult
NS_NewFrameTraversal(nsIEnumerator **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 = (nsIEnumerator *)trav;
NS_ADDREF(trav);
}
break;
#if 0
case EXTENSIVE:{
nsExtensiveTraversal *trav = new nsExtensiveTraversal(aStart);
if (!trav)
return NS_ERROR_NOMEMORY;
*aEnumerator = (nsIEnumerator *)trav;
NS_ADDREF(trav);
}
break;
case FASTEST:{
nsFastestTraversal *trav = new nsFastestTraversal(aStart);
if (!trav)
return NS_ERROR_NOMEMORY;
*aEnumerator = (nsIEnumerator *)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();
}
nsresult
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*)(nsIEnumerator*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
nsresult
nsFrameIterator::CurrentItem(nsISupports **aItem)
{
if (!aItem)
return NS_ERROR_NULL_POINTER;
*aItem = mCurrent;
return NS_OK;
}
nsresult
nsFrameIterator::IsDone()//what does this mean??off edge? yes
{
if (mOffEdge != 0)
return NS_OK;
return NS_COMFALSE;
}
nsresult
nsFrameIterator::First()
{
mCurrent = mStart;
return NS_OK;
}
nsresult
nsFrameIterator::Last()
{
return NS_ERROR_FAILURE;
}
/*********LEAFITERATOR**********/
nsLeafIterator::nsLeafIterator(nsIFrame *aStart)
{
setStart(aStart);
setCurrent(aStart);
setLast(aStart);
}
nsresult
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 nsnull;
}
nsresult
nsLeafIterator::Prev()
{
//recursive-oid method to get prev frame
nsIFrame *result;
nsIFrame *parent = getCurrent();
if (!parent)
return NS_ERROR_FAILURE;
parent = getLast();
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 (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 nsnull;
}

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

@ -539,7 +539,7 @@ nsRangeList::HandleKeyEvent(nsIFocusTracker *aTracker, nsGUIEvent *aGuiEvent, ns
PRInt32 contentoffset;
//check to make sure the frame REALLY has the focus point.
if (NS_SUCCEEDED(aFrame->GetSelected(&selected,&beginoffset,&endoffset, &contentoffset))){
if (domnode != mFocusNode || (contentoffset + beginoffset) != mFocusOffset) //not really the insertion frame
if (domnode != mFocusNode || (contentoffset + endoffset) != mFocusOffset) //not really the insertion frame
return NS_ERROR_FAILURE;
}
@ -552,15 +552,18 @@ nsRangeList::HandleKeyEvent(nsIFocusTracker *aTracker, nsGUIEvent *aGuiEvent, ns
//we need to look for the previous PAINTED location to move the cursor to.
printf("debug vk left\n");
if (NS_SUCCEEDED(aFrame->PeekOffset(eSelectCharacter, eDirPrevious, endoffset, &resultFrame, &frameOffset, &contentOffset)) && resultFrame){
return TakeFocus(aTracker, resultFrame, frameOffset, contentOffset, PR_FALSE);
return TakeFocus(aTracker, resultFrame, frameOffset, contentOffset, keyEvent->isShift);
}
break;
case nsIDOMEvent::VK_RIGHT :
//we need to look for the next PAINTED location to move the cursor to.
printf("debug vk right\n");
if (NS_SUCCEEDED(aFrame->PeekOffset(eSelectCharacter, eDirNext, endoffset, &resultFrame, &frameOffset, &contentOffset)) && resultFrame){
return TakeFocus(aTracker, resultFrame, frameOffset, contentOffset, PR_FALSE);
return TakeFocus(aTracker, resultFrame, frameOffset, contentOffset, keyEvent->isShift);
}
case nsIDOMEvent::VK_UP :
printf("debug vk up\n");
break;
default :break;
}
}

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

@ -0,0 +1,361 @@
/* -*- 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 "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsFrameList.h"
#include "nsFrame.h"
void
nsFrameList::DeleteFrames(nsIPresContext& aPresContext)
{
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
nsIFrame* next;
frame->GetNextSibling(&next);
frame->DeleteFrame(aPresContext);
mFirstChild = frame = next;
}
}
void
nsFrameList::AppendFrames(nsIFrame* aParent, nsIFrame* aFrameList)
{
NS_PRECONDITION(nsnull != aFrameList, "null ptr");
if (nsnull != aFrameList) {
nsIFrame* lastChild = LastChild();
if (nsnull == lastChild) {
mFirstChild = aFrameList;
}
else {
lastChild->SetNextSibling(aFrameList);
}
if (nsnull != aParent) {
nsIFrame* frame = aFrameList;
while (nsnull != frame) {
frame->SetParent(aParent);
frame->GetNextSibling(&frame);
}
}
}
}
void
nsFrameList::AppendFrame(nsIFrame* aParent, nsIFrame* aFrame)
{
NS_PRECONDITION(nsnull != aFrame, "null ptr");
if (nsnull != aFrame) {
nsIFrame* lastChild = LastChild();
if (nsnull == lastChild) {
mFirstChild = aFrame;
}
else {
lastChild->SetNextSibling(aFrame);
}
if (nsnull != aParent) {
aFrame->SetParent(aParent);
}
}
}
PRBool
nsFrameList::RemoveFrame(nsIFrame* aFrame)
{
NS_PRECONDITION(nsnull != aFrame, "null ptr");
if (nsnull != aFrame) {
nsIFrame* nextFrame;
aFrame->GetNextSibling(&nextFrame);
aFrame->SetNextSibling(nsnull);
if (aFrame == mFirstChild) {
mFirstChild = nextFrame;
return PR_TRUE;
}
else {
nsIFrame* prevSibling = GetPrevSiblingFor(aFrame);
if (nsnull != prevSibling) {
prevSibling->SetNextSibling(nextFrame);
return PR_TRUE;
}
}
}
return PR_FALSE;
}
PRBool
nsFrameList::RemoveFirstChild()
{
if (nsnull != mFirstChild) {
nsIFrame* nextFrame;
mFirstChild->GetNextSibling(&nextFrame);
mFirstChild->SetNextSibling(nsnull);
mFirstChild = nextFrame;
return PR_TRUE;
}
return PR_FALSE;
}
PRBool
nsFrameList::DeleteFrame(nsIPresContext& aPresContext, nsIFrame* aFrame)
{
NS_PRECONDITION(nsnull != aFrame, "null ptr");
if (RemoveFrame(aFrame)) {
aFrame->DeleteFrame(aPresContext);
return PR_TRUE;
}
return PR_FALSE;
}
void
nsFrameList::InsertFrame(nsIFrame* aParent,
nsIFrame* aPrevSibling,
nsIFrame* aNewFrame)
{
NS_PRECONDITION(nsnull != aNewFrame, "null ptr");
if (nsnull != aNewFrame) {
if (nsnull == aPrevSibling) {
aNewFrame->SetNextSibling(mFirstChild);
mFirstChild = aNewFrame;
}
else {
nsIFrame* nextFrame;
aPrevSibling->GetNextSibling(&nextFrame);
aPrevSibling->SetNextSibling(aNewFrame);
aNewFrame->SetNextSibling(nextFrame);
}
if (nsnull != aParent) {
aNewFrame->SetParent(aParent);
}
}
}
void
nsFrameList::InsertFrames(nsIFrame* aParent,
nsIFrame* aPrevSibling,
nsIFrame* aFrameList)
{
NS_PRECONDITION(nsnull != aFrameList, "null ptr");
if (nsnull != aFrameList) {
if (nsnull != aParent) {
nsIFrame* frame = aFrameList;
while (nsnull != frame) {
frame->SetParent(aParent);
frame->GetNextSibling(&frame);
}
}
nsFrameList tmp(aFrameList);
nsIFrame* lastNewFrame = tmp.LastChild();
if (nsnull == aPrevSibling) {
lastNewFrame->SetNextSibling(mFirstChild);
mFirstChild = aFrameList;
}
else {
nsIFrame* nextFrame;
aPrevSibling->GetNextSibling(&nextFrame);
aPrevSibling->SetNextSibling(aFrameList);
lastNewFrame->SetNextSibling(nextFrame);
}
}
}
PRBool
nsFrameList::ReplaceFrame(nsIFrame* aParent,
nsIFrame* aOldFrame,
nsIFrame* aNewFrame)
{
NS_PRECONDITION(nsnull != aOldFrame, "null ptr");
NS_PRECONDITION(nsnull != aNewFrame, "null ptr");
if ((nsnull != aOldFrame) && (nsnull != aNewFrame)) {
nsIFrame* nextFrame;
aOldFrame->GetNextSibling(&nextFrame);
if (aOldFrame == mFirstChild) {
mFirstChild = aNewFrame;
aNewFrame->SetNextSibling(nextFrame);
}
else {
nsIFrame* prevSibling = GetPrevSiblingFor(aOldFrame);
if (nsnull != prevSibling) {
prevSibling->SetNextSibling(aNewFrame);
aNewFrame->SetNextSibling(nextFrame);
}
}
if (nsnull != aParent) {
aNewFrame->SetParent(aParent);
}
return PR_TRUE;
}
return PR_FALSE;
}
PRBool
nsFrameList::ReplaceAndDeleteFrame(nsIPresContext& aPresContext,
nsIFrame* aParent,
nsIFrame* aOldFrame,
nsIFrame* aNewFrame)
{
NS_PRECONDITION(nsnull != aOldFrame, "null ptr");
NS_PRECONDITION(nsnull != aNewFrame, "null ptr");
if (ReplaceFrame(aParent, aOldFrame, aNewFrame)) {
aNewFrame->DeleteFrame(aPresContext);
return PR_TRUE;
}
return PR_FALSE;
}
PRBool
nsFrameList::Split(nsIFrame* aAfterFrame, nsIFrame** aNextFrameResult)
{
NS_PRECONDITION(nsnull != aAfterFrame, "null ptr");
NS_PRECONDITION(nsnull != aNextFrameResult, "null ptr");
NS_ASSERTION(ContainsFrame(aAfterFrame), "split after unknown frame");
if ((nsnull != aNextFrameResult) && (nsnull != aAfterFrame)) {
nsIFrame* nextFrame;
aAfterFrame->GetNextSibling(&nextFrame);
aAfterFrame->SetNextSibling(nsnull);
*aNextFrameResult = nextFrame;
return PR_TRUE;
}
return PR_FALSE;
}
nsIFrame*
nsFrameList::PullFrame(nsIFrame* aParent,
nsIFrame* aLastChild,
nsFrameList& aFromList)
{
NS_PRECONDITION(nsnull != aParent, "null ptr");
nsIFrame* pulledFrame = nsnull;
if (nsnull != aParent) {
pulledFrame = aFromList.FirstChild();
if (nsnull != pulledFrame) {
// Take frame off old list
aFromList.RemoveFirstChild();
// Put it on the end of this list
if (nsnull == aLastChild) {
NS_ASSERTION(nsnull == mFirstChild, "bad aLastChild");
mFirstChild = pulledFrame;
}
else {
aLastChild->SetNextSibling(pulledFrame);
}
pulledFrame->SetParent(aParent);
}
}
return pulledFrame;
}
nsIFrame*
nsFrameList::LastChild() const
{
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
nsIFrame* next;
frame->GetNextSibling(&next);
if (nsnull == next) {
break;
}
frame = next;
}
return frame;
}
nsIFrame*
nsFrameList::FrameAt(PRInt32 aIndex) const
{
NS_PRECONDITION(aIndex >= 0, "invalid arg");
if (aIndex < 0) return nsnull;
nsIFrame* frame = mFirstChild;
while ((aIndex-- > 0) && (nsnull != frame)) {
frame->GetNextSibling(&frame);
}
return frame;
}
PRBool
nsFrameList::ContainsFrame(const nsIFrame* aFrame) const
{
NS_PRECONDITION(nsnull != aFrame, "null ptr");
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
if (frame == aFrame) {
return PR_TRUE;
}
frame->GetNextSibling(&frame);
}
return PR_FALSE;
}
PRInt32
nsFrameList::GetLength() const
{
PRInt32 count = 0;
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
count++;
frame->GetNextSibling(&frame);
}
return count;
}
nsIFrame*
nsFrameList::GetPrevSiblingFor(nsIFrame* aFrame) const
{
NS_PRECONDITION(nsnull != aFrame, "null ptr");
if (aFrame == mFirstChild) {
return nsnull;
}
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
nsIFrame* next;
frame->GetNextSibling(&next);
if (next == aFrame) {
break;
}
frame = next;
}
return frame;
}
void
nsFrameList::VerifyParent(nsIFrame* aParent) const
{
#ifdef NS_DEBUG
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
nsIFrame* parent;
frame->GetParent(&parent);
NS_ASSERTION(parent == aParent, "bad parent");
frame->GetNextSibling(&frame);
}
#endif
}
void
nsFrameList::List(FILE* out) const
{
fputs("<\n", out);
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
frame->List(out, 1);
// nsFrame::ListTag(out, frame);
// fputs(" ", out);
frame->GetNextSibling(&frame);
}
fputs("\n", out);
}

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

@ -0,0 +1,135 @@
/* -*- 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 "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#ifndef nsFrameList_h___
#define nsFrameList_h___
#include "nsIFrame.h"
/**
* A class for managing a singly linked list of frames. Frames are
* linked together through their next-sibling pointer.
*/
class nsFrameList {
public:
nsFrameList() {
mFirstChild = nsnull;
}
nsFrameList(nsIFrame* aHead) {
mFirstChild = aHead;
}
~nsFrameList() {
}
void DeleteFrames(nsIPresContext& aPresContext);
void SetFrames(nsIFrame* aFrameList) {
mFirstChild = aFrameList;
}
void AppendFrames(nsIFrame* aParent, nsIFrame* aFrameList);
void AppendFrames(nsIFrame* aParent, nsFrameList& aFrameList) {
AppendFrames(aParent, aFrameList.mFirstChild);
aFrameList.mFirstChild = nsnull;
}
void AppendFrame(nsIFrame* aParent, nsIFrame* aFrame);
// Take aFrame out of the frame list. This also disconnects aFrame
// from the sibling list. This will return PR_FALSE if aFrame is
// nsnull or if aFrame is not in the list.
PRBool RemoveFrame(nsIFrame* aFrame);
// Remove the first child from the list. The caller is assumed to be
// holding a reference to the first child. This call is equivalent
// in behavior to calling RemoveFrame(FirstChild()).
PRBool RemoveFirstChild();
// Take aFrame out of the frame list and then delete it. This also
// disconnects aFrame from the sibling list. This will return
// PR_FALSE if aFrame is nsnull or if aFrame is not in the list.
PRBool DeleteFrame(nsIPresContext& aPresContext, nsIFrame* aFrame);
void InsertFrame(nsIFrame* aParent,
nsIFrame* aPrevSibling,
nsIFrame* aNewFrame);
void InsertFrames(nsIFrame* aParent,
nsIFrame* aPrevSibling,
nsIFrame* aFrameList);
void InsertFrames(nsIFrame* aParent, nsIFrame* aPrevSibling,
nsFrameList& aFrameList) {
InsertFrames(aParent, aPrevSibling, aFrameList.FirstChild());
aFrameList.mFirstChild = nsnull;
}
PRBool ReplaceFrame(nsIFrame* aParent,
nsIFrame* aOldFrame,
nsIFrame* aNewFrame);
PRBool ReplaceAndDeleteFrame(nsIPresContext& aPresContext,
nsIFrame* aParent,
nsIFrame* aOldFrame,
nsIFrame* aNewFrame);
PRBool Split(nsIFrame* aAfterFrame, nsIFrame** aNextFrameResult);
nsIFrame* PullFrame(nsIFrame* aParent,
nsIFrame* aLastChild,
nsFrameList& aFromList);
void Join(nsIFrame* aParent, nsFrameList& aList) {
AppendFrames(aParent, aList.mFirstChild);
aList.mFirstChild = nsnull;
}
nsIFrame* FirstChild() const {
return mFirstChild;
}
nsIFrame* LastChild() const;
nsIFrame* FrameAt(PRInt32 aIndex) const;
PRBool IsEmpty() const {
return nsnull == mFirstChild;
}
PRBool NotEmpty() const {
return nsnull != mFirstChild;
}
PRBool ContainsFrame(const nsIFrame* aFrame) const;
PRInt32 GetLength() const;
nsIFrame* GetPrevSiblingFor(nsIFrame* aFrame) const;
void VerifyParent(nsIFrame* aParent) const;
void List(FILE* out) const;
protected:
nsIFrame* mFirstChild;
};
#endif /* nsFrameList_h___ */

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

@ -34,8 +34,6 @@ CPPSRCS= \
nsBulletFrame.cpp \
nsContainerFrame.cpp \
nsFrame.cpp \
nsFrameList.cpp \
nsFrameTraversal.cpp \
nsGlobalVariables.cpp \
nsHRFrame.cpp \
nsHTMLAtoms.cpp \
@ -74,8 +72,6 @@ CPP_OBJS= \
.\$(OBJDIR)\nsBulletFrame.obj \
.\$(OBJDIR)\nsContainerFrame.obj \
.\$(OBJDIR)\nsFrame.obj \
.\$(OBJDIR)\nsFrameList.obj \
.\$(OBJDIR)\nsFrameTraversal.obj \
.\$(OBJDIR)\nsGlobalVariables.obj \
.\$(OBJDIR)\nsHRFrame.obj \
.\$(OBJDIR)\nsHTMLAtoms.obj \

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

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

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

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

Двоичные данные
layout/macbuild/layout.mcp

Двоичный файл не отображается.