This commit is contained in:
hyatt%netscape.com 2000-06-14 04:50:20 +00:00
Родитель c23c45c768
Коммит 47ecc64920
11 изменённых файлов: 34 добавлений и 659 удалений

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

@ -279,8 +279,12 @@ nsXULTreeElement::SelectItemRange(nsIDOMXULElement* aStartItem, nsIDOMXULElement
// so we can determine if this is a forward or backward
// selection
GetRowIndexOf(startItem, &startIndex);
GetRowIndexOf(aEndItem, &endIndex);
nsCOMPtr<nsIBoxObject> boxObject;
mOuter->GetBoxObject(getter_AddRefs(boxObject));
nsCOMPtr<nsITreeBoxObject> treebox = do_QueryInterface(boxObject);
treebox->GetIndexOfItem(startItem, &startIndex);
treebox->GetIndexOfItem(aEndItem, &endIndex);
PRBool didSwap = (endIndex < startIndex);
nsCOMPtr<nsIDOMElement> currentItem;
@ -293,10 +297,6 @@ nsXULTreeElement::SelectItemRange(nsIDOMXULElement* aStartItem, nsIDOMXULElement
} else
currentItem = do_QueryInterface(startItem);
nsCOMPtr<nsIBoxObject> boxObject;
mOuter->GetBoxObject(getter_AddRefs(boxObject));
nsCOMPtr<nsITreeBoxObject> treebox = do_QueryInterface(boxObject);
nsAutoString trueString; trueString.AssignWithConversion("true", 4);
nsCOMPtr<nsIContent> content;
nsCOMPtr<nsIAtom> tag;
@ -405,219 +405,6 @@ nsXULTreeElement::FireOnSelectHandler()
}
// get the rowindex of the given element
// this has two special optimizations:
// - if you're looking for the row of a <treeitem>, it will actually
// find the index of the NEXT row
// - if you're looking for a <treeitem>, <treerow>, or a <treechildren>
// it won't descend into <treerow>s
nsresult
nsXULTreeElement::GetRowIndexOf(nsIDOMXULElement *aElement, PRInt32 *aReturn)
{
NS_ENSURE_ARG_POINTER(aElement);
NS_ENSURE_ARG_POINTER(aReturn);
nsresult rv;
nsCOMPtr<nsIContent> elementContent = do_QueryInterface(aElement, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIContent> treeContent =
do_QueryInterface((nsIXULTreeContent*)this,&rv);
if (NS_FAILED(rv)) return rv;
*aReturn = 0;
nsCOMPtr<nsIAtom> elementTag;
elementContent->GetTag(*getter_AddRefs(elementTag));
// if looking for a treeitem, get the first row instead
if (elementTag.get() == kTreeItemAtom) {
// search through immediate children for the first row
PRInt32 childCount;
elementContent->ChildCount(childCount);
PRInt32 i;
for (i=0; i< childCount; i++) {
nsCOMPtr<nsIContent> childContent;
elementContent->ChildAt(i, *getter_AddRefs(childContent));
nsCOMPtr<nsIAtom> childTag;
childContent->GetTag(*getter_AddRefs(childTag));
// found it! fix elementContent and update tag
if (childTag.get() == kTreeRowAtom) {
elementContent = childContent;
elementTag = childTag;
break;
}
}
}
// if we're looking for a treeitem, treerow, or treechildren
// there's no need to descend into cells
PRBool descendIntoRows = PR_TRUE;
if (elementTag.get() == kTreeRowAtom ||
elementTag.get() == kTreeChildrenAtom ||
elementTag.get() == kTreeItemAtom)
descendIntoRows = PR_FALSE;
// now begin with the first <treechildren> child of this node
PRInt32 i;
PRInt32 treeChildCount;
nsCOMPtr<nsIContent> treeChildren;
treeContent->ChildCount(treeChildCount);
for (i=0; i<treeChildCount; i++) {
treeChildren = null_nsCOMPtr();
treeContent->ChildAt(i, *getter_AddRefs(treeChildren));
nsCOMPtr<nsIAtom> tag;
treeChildren->GetTag(*getter_AddRefs(tag));
if (tag.get() == kTreeChildrenAtom)
break;
}
if (treeChildren)
return IndexOfContent(treeChildren, elementContent,
descendIntoRows, PR_TRUE /* aParentIsOpen */,
aReturn);
NS_WARNING("EnsureContentVisible: tree has no <treechildren>");
return NS_ERROR_FAILURE;
}
nsresult
nsXULTreeElement::EnsureElementIsVisible(nsIDOMXULElement *aElement)
{
if (!aElement) return NS_OK;
nsresult rv;
PRInt32 indexOfContent;
rv = GetRowIndexOf(aElement, &indexOfContent);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIContent> content = do_QueryInterface(mOuter);
nsCOMPtr<nsIDocument> document;
content->GetDocument(*getter_AddRefs(document));
// If there's no document (e.g., a selection is occuring in a
// 'orphaned' node), then there ain't a whole lot to do here!
if (! document) {
NS_WARNING("Trying to EnsureElementIsVisible on orphaned element!");
return NS_OK;
}
// now call EnsureElementIsVisible on all the frames
PRInt32 count = document->GetNumberOfShells();
for (PRInt32 i = 0; i < count; i++) {
nsCOMPtr<nsIPresShell> shell = getter_AddRefs(document->GetShellAt(i));
if (!shell)
continue;
nsIFrame *outerFrame;
shell->GetPrimaryFrameFor(content, &outerFrame);
if (outerFrame) {
nsCOMPtr<nsIPresContext> presContext;
shell->GetPresContext(getter_AddRefs(presContext));
// need to look at the outer frame's children to find the nsTreeFrame
nsIFrame *childFrame=nsnull;
outerFrame->FirstChild(presContext, nsnull, &childFrame);
// now iterate through the children
while (childFrame) {
nsITreeFrame *treeFrame = nsnull;
rv = childFrame->QueryInterface(NS_GET_IID(nsITreeFrame),
(void **)&treeFrame);
if (NS_SUCCEEDED(rv) && treeFrame) {
treeFrame->EnsureRowIsVisible(indexOfContent);
}
nsIFrame *nextFrame;
childFrame->GetNextSibling(&nextFrame);
childFrame=nextFrame;
}
}
}
return NS_OK;
}
// helper routine for GetRowIndexOf()
// walks the DOM to get the zero-based row index of the current content
// note that aContent can be any element, this will get the index of the
// element's parent
nsresult
nsXULTreeElement::IndexOfContent(nsIContent* aRoot,
nsIContent* aContent, // invariant
PRBool aDescendIntoRows, // invariant
PRBool aParentIsOpen,
PRInt32 *aResult)
{
PRInt32 childCount=0;
aRoot->ChildCount(childCount);
nsresult rv;
PRInt32 childIndex;
for (childIndex=0; childIndex<childCount; childIndex++) {
nsCOMPtr<nsIContent> child;
aRoot->ChildAt(childIndex, *getter_AddRefs(child));
nsCOMPtr<nsIAtom> childTag;
child->GetTag(*getter_AddRefs(childTag));
// is this it?
if (child.get() == aContent)
return NS_OK;
// we hit a treerow, count it
if (childTag.get() == kTreeRowAtom)
(*aResult)++;
// now recurse. This gets tricky, depending on our tag:
// first set up some default state for the recursion
PRBool parentIsOpen = aParentIsOpen;
PRBool descend = PR_TRUE;
// don't descend into closed children
if (childTag.get() == kTreeChildrenAtom && !parentIsOpen)
descend = PR_FALSE;
// speed optimization - descend into rows only when told
else if (childTag.get() == kTreeRowAtom && !aDescendIntoRows)
descend = PR_FALSE;
// descend as normally, but remember that the parent is closed!
else if (childTag.get() == kTreeItemAtom) {
nsAutoString isOpen;
rv = child->GetAttribute(kNameSpaceID_None, kOpenAtom, isOpen);
if (!isOpen.EqualsWithConversion("true"))
parentIsOpen=PR_FALSE;
}
// now that we've analyzed the tags, recurse
if (descend) {
rv = IndexOfContent(child, aContent,
aDescendIntoRows, parentIsOpen, aResult);
if (NS_SUCCEEDED(rv))
return NS_OK;
}
}
// not found
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsXULTreeElement::GetCurrentItem(nsIDOMXULElement** aResult)
{

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

@ -18,7 +18,4 @@ interface XULTreeElement : XULElement {
void selectAll();
void invertSelection();
void ensureElementIsVisible(in XULElement element);
long getRowIndexOf(in XULElement element);
};

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

@ -59,10 +59,6 @@ public:
NS_IMETHOD SelectAll()=0;
NS_IMETHOD InvertSelection()=0;
NS_IMETHOD EnsureElementIsVisible(nsIDOMXULElement* aElement)=0;
NS_IMETHOD GetRowIndexOf(nsIDOMXULElement* aElement, PRInt32* aReturn)=0;
};
@ -77,8 +73,6 @@ public:
NS_IMETHOD SelectItemRange(nsIDOMXULElement* aStartItem, nsIDOMXULElement* aEndItem); \
NS_IMETHOD SelectAll(); \
NS_IMETHOD InvertSelection(); \
NS_IMETHOD EnsureElementIsVisible(nsIDOMXULElement* aElement); \
NS_IMETHOD GetRowIndexOf(nsIDOMXULElement* aElement, PRInt32* aReturn); \
@ -93,8 +87,6 @@ public:
NS_IMETHOD SelectItemRange(nsIDOMXULElement* aStartItem, nsIDOMXULElement* aEndItem) { return _to SelectItemRange(aStartItem, aEndItem); } \
NS_IMETHOD SelectAll() { return _to SelectAll(); } \
NS_IMETHOD InvertSelection() { return _to InvertSelection(); } \
NS_IMETHOD EnsureElementIsVisible(nsIDOMXULElement* aElement) { return _to EnsureElementIsVisible(aElement); } \
NS_IMETHOD GetRowIndexOf(nsIDOMXULElement* aElement, PRInt32* aReturn) { return _to GetRowIndexOf(aElement, aReturn); } \
extern "C" NS_DOM nsresult NS_InitXULTreeElementClass(nsIScriptContext *aContext, void **aPrototype);

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

@ -526,101 +526,6 @@ XULTreeElementInvertSelection(JSContext *cx, JSObject *obj, uintN argc, jsval *a
}
//
// Native method EnsureElementIsVisible
//
PR_STATIC_CALLBACK(JSBool)
XULTreeElementEnsureElementIsVisible(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULTreeElement *nativeThis = (nsIDOMXULTreeElement*)nsJSUtils::nsGetNativeThis(cx, obj);
nsresult result = NS_OK;
nsCOMPtr<nsIDOMXULElement> b0;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
{
*rval = JSVAL_NULL;
nsIScriptSecurityManager *secMan = nsJSUtils::nsGetSecurityManager(cx, obj);
if (!secMan)
return PR_FALSE;
result = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULTREEELEMENT_ENSUREELEMENTISVISIBLE, PR_FALSE);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
if (argc < 1) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_TOO_FEW_PARAMETERS_ERR);
}
if (JS_FALSE == nsJSUtils::nsConvertJSValToObject((nsISupports **)(void**)getter_AddRefs(b0),
kIXULElementIID,
NS_ConvertASCIItoUCS2("XULElement"),
cx,
argv[0])) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_NOT_OBJECT_ERR);
}
result = nativeThis->EnsureElementIsVisible(b0);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
*rval = JSVAL_VOID;
}
return JS_TRUE;
}
//
// Native method GetRowIndexOf
//
PR_STATIC_CALLBACK(JSBool)
XULTreeElementGetRowIndexOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULTreeElement *nativeThis = (nsIDOMXULTreeElement*)nsJSUtils::nsGetNativeThis(cx, obj);
nsresult result = NS_OK;
PRInt32 nativeRet;
nsCOMPtr<nsIDOMXULElement> b0;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
{
*rval = JSVAL_NULL;
nsIScriptSecurityManager *secMan = nsJSUtils::nsGetSecurityManager(cx, obj);
if (!secMan)
return PR_FALSE;
result = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULTREEELEMENT_GETROWINDEXOF, PR_FALSE);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
if (argc < 1) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_TOO_FEW_PARAMETERS_ERR);
}
if (JS_FALSE == nsJSUtils::nsConvertJSValToObject((nsISupports **)(void**)getter_AddRefs(b0),
kIXULElementIID,
NS_ConvertASCIItoUCS2("XULElement"),
cx,
argv[0])) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_NOT_OBJECT_ERR);
}
result = nativeThis->GetRowIndexOf(b0, &nativeRet);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
*rval = INT_TO_JSVAL(nativeRet);
}
return JS_TRUE;
}
/***********************************************************************/
//
// class for XULTreeElement
@ -665,8 +570,6 @@ static JSFunctionSpec XULTreeElementMethods[] =
{"selectItemRange", XULTreeElementSelectItemRange, 2},
{"selectAll", XULTreeElementSelectAll, 0},
{"invertSelection", XULTreeElementInvertSelection, 0},
{"ensureElementIsVisible", XULTreeElementEnsureElementIsVisible, 1},
{"getRowIndexOf", XULTreeElementGetRowIndexOf, 1},
{0}
};

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

@ -33,7 +33,7 @@
#include "nsIPresContext.h"
#include "nsIFrame.h"
//#define XULTREE
#define XULTREE
// XXX Hack
#include "nsTreeOuterFrame.h"

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

@ -35,6 +35,8 @@
#define TICK_FACTOR 50
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
//
// NS_NewXULTreeOuterGroupFrame
//
@ -323,8 +325,17 @@ nsXULTreeOuterGroupFrame::InternalPositionChanged(PRBool aUp, PRInt32 aDelta)
// as a hint to figure out how to build the frames.
// Remove the scrollbar first.
// get the starting row index and row count
mFrameConstructor->RemoveMappingsForFrameSubtree(mPresContext, this, nsnull);
nsIBox* currBox;
GetChildBox(&currBox);
while (currBox) {
nsIBox* nextBox;
currBox->GetNextBox(&nextBox);
nsIFrame* frame;
currBox->QueryInterface(kIFrameIID, (void**)&frame);
mFrameConstructor->RemoveMappingsForFrameSubtree(mPresContext, frame, nsnull);
currBox = nextBox;
}
nsBoxLayoutState state(mPresContext);
mFirstChild = mLastChild = nsnull;
mFrames.DestroyFrames(mPresContext);

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

@ -18,7 +18,4 @@ interface XULTreeElement : XULElement {
void selectAll();
void invertSelection();
void ensureElementIsVisible(in XULElement element);
long getRowIndexOf(in XULElement element);
};

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

@ -59,10 +59,6 @@ public:
NS_IMETHOD SelectAll()=0;
NS_IMETHOD InvertSelection()=0;
NS_IMETHOD EnsureElementIsVisible(nsIDOMXULElement* aElement)=0;
NS_IMETHOD GetRowIndexOf(nsIDOMXULElement* aElement, PRInt32* aReturn)=0;
};
@ -77,8 +73,6 @@ public:
NS_IMETHOD SelectItemRange(nsIDOMXULElement* aStartItem, nsIDOMXULElement* aEndItem); \
NS_IMETHOD SelectAll(); \
NS_IMETHOD InvertSelection(); \
NS_IMETHOD EnsureElementIsVisible(nsIDOMXULElement* aElement); \
NS_IMETHOD GetRowIndexOf(nsIDOMXULElement* aElement, PRInt32* aReturn); \
@ -93,8 +87,6 @@ public:
NS_IMETHOD SelectItemRange(nsIDOMXULElement* aStartItem, nsIDOMXULElement* aEndItem) { return _to SelectItemRange(aStartItem, aEndItem); } \
NS_IMETHOD SelectAll() { return _to SelectAll(); } \
NS_IMETHOD InvertSelection() { return _to InvertSelection(); } \
NS_IMETHOD EnsureElementIsVisible(nsIDOMXULElement* aElement) { return _to EnsureElementIsVisible(aElement); } \
NS_IMETHOD GetRowIndexOf(nsIDOMXULElement* aElement, PRInt32* aReturn) { return _to GetRowIndexOf(aElement, aReturn); } \
extern "C" NS_DOM nsresult NS_InitXULTreeElementClass(nsIScriptContext *aContext, void **aPrototype);

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

@ -526,101 +526,6 @@ XULTreeElementInvertSelection(JSContext *cx, JSObject *obj, uintN argc, jsval *a
}
//
// Native method EnsureElementIsVisible
//
PR_STATIC_CALLBACK(JSBool)
XULTreeElementEnsureElementIsVisible(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULTreeElement *nativeThis = (nsIDOMXULTreeElement*)nsJSUtils::nsGetNativeThis(cx, obj);
nsresult result = NS_OK;
nsCOMPtr<nsIDOMXULElement> b0;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
{
*rval = JSVAL_NULL;
nsIScriptSecurityManager *secMan = nsJSUtils::nsGetSecurityManager(cx, obj);
if (!secMan)
return PR_FALSE;
result = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULTREEELEMENT_ENSUREELEMENTISVISIBLE, PR_FALSE);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
if (argc < 1) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_TOO_FEW_PARAMETERS_ERR);
}
if (JS_FALSE == nsJSUtils::nsConvertJSValToObject((nsISupports **)(void**)getter_AddRefs(b0),
kIXULElementIID,
NS_ConvertASCIItoUCS2("XULElement"),
cx,
argv[0])) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_NOT_OBJECT_ERR);
}
result = nativeThis->EnsureElementIsVisible(b0);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
*rval = JSVAL_VOID;
}
return JS_TRUE;
}
//
// Native method GetRowIndexOf
//
PR_STATIC_CALLBACK(JSBool)
XULTreeElementGetRowIndexOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULTreeElement *nativeThis = (nsIDOMXULTreeElement*)nsJSUtils::nsGetNativeThis(cx, obj);
nsresult result = NS_OK;
PRInt32 nativeRet;
nsCOMPtr<nsIDOMXULElement> b0;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
{
*rval = JSVAL_NULL;
nsIScriptSecurityManager *secMan = nsJSUtils::nsGetSecurityManager(cx, obj);
if (!secMan)
return PR_FALSE;
result = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULTREEELEMENT_GETROWINDEXOF, PR_FALSE);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
if (argc < 1) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_TOO_FEW_PARAMETERS_ERR);
}
if (JS_FALSE == nsJSUtils::nsConvertJSValToObject((nsISupports **)(void**)getter_AddRefs(b0),
kIXULElementIID,
NS_ConvertASCIItoUCS2("XULElement"),
cx,
argv[0])) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_NOT_OBJECT_ERR);
}
result = nativeThis->GetRowIndexOf(b0, &nativeRet);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
*rval = INT_TO_JSVAL(nativeRet);
}
return JS_TRUE;
}
/***********************************************************************/
//
// class for XULTreeElement
@ -665,8 +570,6 @@ static JSFunctionSpec XULTreeElementMethods[] =
{"selectItemRange", XULTreeElementSelectItemRange, 2},
{"selectAll", XULTreeElementSelectAll, 0},
{"invertSelection", XULTreeElementInvertSelection, 0},
{"ensureElementIsVisible", XULTreeElementEnsureElementIsVisible, 1},
{"getRowIndexOf", XULTreeElementGetRowIndexOf, 1},
{0}
};

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

@ -279,8 +279,12 @@ nsXULTreeElement::SelectItemRange(nsIDOMXULElement* aStartItem, nsIDOMXULElement
// so we can determine if this is a forward or backward
// selection
GetRowIndexOf(startItem, &startIndex);
GetRowIndexOf(aEndItem, &endIndex);
nsCOMPtr<nsIBoxObject> boxObject;
mOuter->GetBoxObject(getter_AddRefs(boxObject));
nsCOMPtr<nsITreeBoxObject> treebox = do_QueryInterface(boxObject);
treebox->GetIndexOfItem(startItem, &startIndex);
treebox->GetIndexOfItem(aEndItem, &endIndex);
PRBool didSwap = (endIndex < startIndex);
nsCOMPtr<nsIDOMElement> currentItem;
@ -293,10 +297,6 @@ nsXULTreeElement::SelectItemRange(nsIDOMXULElement* aStartItem, nsIDOMXULElement
} else
currentItem = do_QueryInterface(startItem);
nsCOMPtr<nsIBoxObject> boxObject;
mOuter->GetBoxObject(getter_AddRefs(boxObject));
nsCOMPtr<nsITreeBoxObject> treebox = do_QueryInterface(boxObject);
nsAutoString trueString; trueString.AssignWithConversion("true", 4);
nsCOMPtr<nsIContent> content;
nsCOMPtr<nsIAtom> tag;
@ -405,219 +405,6 @@ nsXULTreeElement::FireOnSelectHandler()
}
// get the rowindex of the given element
// this has two special optimizations:
// - if you're looking for the row of a <treeitem>, it will actually
// find the index of the NEXT row
// - if you're looking for a <treeitem>, <treerow>, or a <treechildren>
// it won't descend into <treerow>s
nsresult
nsXULTreeElement::GetRowIndexOf(nsIDOMXULElement *aElement, PRInt32 *aReturn)
{
NS_ENSURE_ARG_POINTER(aElement);
NS_ENSURE_ARG_POINTER(aReturn);
nsresult rv;
nsCOMPtr<nsIContent> elementContent = do_QueryInterface(aElement, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIContent> treeContent =
do_QueryInterface((nsIXULTreeContent*)this,&rv);
if (NS_FAILED(rv)) return rv;
*aReturn = 0;
nsCOMPtr<nsIAtom> elementTag;
elementContent->GetTag(*getter_AddRefs(elementTag));
// if looking for a treeitem, get the first row instead
if (elementTag.get() == kTreeItemAtom) {
// search through immediate children for the first row
PRInt32 childCount;
elementContent->ChildCount(childCount);
PRInt32 i;
for (i=0; i< childCount; i++) {
nsCOMPtr<nsIContent> childContent;
elementContent->ChildAt(i, *getter_AddRefs(childContent));
nsCOMPtr<nsIAtom> childTag;
childContent->GetTag(*getter_AddRefs(childTag));
// found it! fix elementContent and update tag
if (childTag.get() == kTreeRowAtom) {
elementContent = childContent;
elementTag = childTag;
break;
}
}
}
// if we're looking for a treeitem, treerow, or treechildren
// there's no need to descend into cells
PRBool descendIntoRows = PR_TRUE;
if (elementTag.get() == kTreeRowAtom ||
elementTag.get() == kTreeChildrenAtom ||
elementTag.get() == kTreeItemAtom)
descendIntoRows = PR_FALSE;
// now begin with the first <treechildren> child of this node
PRInt32 i;
PRInt32 treeChildCount;
nsCOMPtr<nsIContent> treeChildren;
treeContent->ChildCount(treeChildCount);
for (i=0; i<treeChildCount; i++) {
treeChildren = null_nsCOMPtr();
treeContent->ChildAt(i, *getter_AddRefs(treeChildren));
nsCOMPtr<nsIAtom> tag;
treeChildren->GetTag(*getter_AddRefs(tag));
if (tag.get() == kTreeChildrenAtom)
break;
}
if (treeChildren)
return IndexOfContent(treeChildren, elementContent,
descendIntoRows, PR_TRUE /* aParentIsOpen */,
aReturn);
NS_WARNING("EnsureContentVisible: tree has no <treechildren>");
return NS_ERROR_FAILURE;
}
nsresult
nsXULTreeElement::EnsureElementIsVisible(nsIDOMXULElement *aElement)
{
if (!aElement) return NS_OK;
nsresult rv;
PRInt32 indexOfContent;
rv = GetRowIndexOf(aElement, &indexOfContent);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIContent> content = do_QueryInterface(mOuter);
nsCOMPtr<nsIDocument> document;
content->GetDocument(*getter_AddRefs(document));
// If there's no document (e.g., a selection is occuring in a
// 'orphaned' node), then there ain't a whole lot to do here!
if (! document) {
NS_WARNING("Trying to EnsureElementIsVisible on orphaned element!");
return NS_OK;
}
// now call EnsureElementIsVisible on all the frames
PRInt32 count = document->GetNumberOfShells();
for (PRInt32 i = 0; i < count; i++) {
nsCOMPtr<nsIPresShell> shell = getter_AddRefs(document->GetShellAt(i));
if (!shell)
continue;
nsIFrame *outerFrame;
shell->GetPrimaryFrameFor(content, &outerFrame);
if (outerFrame) {
nsCOMPtr<nsIPresContext> presContext;
shell->GetPresContext(getter_AddRefs(presContext));
// need to look at the outer frame's children to find the nsTreeFrame
nsIFrame *childFrame=nsnull;
outerFrame->FirstChild(presContext, nsnull, &childFrame);
// now iterate through the children
while (childFrame) {
nsITreeFrame *treeFrame = nsnull;
rv = childFrame->QueryInterface(NS_GET_IID(nsITreeFrame),
(void **)&treeFrame);
if (NS_SUCCEEDED(rv) && treeFrame) {
treeFrame->EnsureRowIsVisible(indexOfContent);
}
nsIFrame *nextFrame;
childFrame->GetNextSibling(&nextFrame);
childFrame=nextFrame;
}
}
}
return NS_OK;
}
// helper routine for GetRowIndexOf()
// walks the DOM to get the zero-based row index of the current content
// note that aContent can be any element, this will get the index of the
// element's parent
nsresult
nsXULTreeElement::IndexOfContent(nsIContent* aRoot,
nsIContent* aContent, // invariant
PRBool aDescendIntoRows, // invariant
PRBool aParentIsOpen,
PRInt32 *aResult)
{
PRInt32 childCount=0;
aRoot->ChildCount(childCount);
nsresult rv;
PRInt32 childIndex;
for (childIndex=0; childIndex<childCount; childIndex++) {
nsCOMPtr<nsIContent> child;
aRoot->ChildAt(childIndex, *getter_AddRefs(child));
nsCOMPtr<nsIAtom> childTag;
child->GetTag(*getter_AddRefs(childTag));
// is this it?
if (child.get() == aContent)
return NS_OK;
// we hit a treerow, count it
if (childTag.get() == kTreeRowAtom)
(*aResult)++;
// now recurse. This gets tricky, depending on our tag:
// first set up some default state for the recursion
PRBool parentIsOpen = aParentIsOpen;
PRBool descend = PR_TRUE;
// don't descend into closed children
if (childTag.get() == kTreeChildrenAtom && !parentIsOpen)
descend = PR_FALSE;
// speed optimization - descend into rows only when told
else if (childTag.get() == kTreeRowAtom && !aDescendIntoRows)
descend = PR_FALSE;
// descend as normally, but remember that the parent is closed!
else if (childTag.get() == kTreeItemAtom) {
nsAutoString isOpen;
rv = child->GetAttribute(kNameSpaceID_None, kOpenAtom, isOpen);
if (!isOpen.EqualsWithConversion("true"))
parentIsOpen=PR_FALSE;
}
// now that we've analyzed the tags, recurse
if (descend) {
rv = IndexOfContent(child, aContent,
aDescendIntoRows, parentIsOpen, aResult);
if (NS_SUCCEEDED(rv))
return NS_OK;
}
}
// not found
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsXULTreeElement::GetCurrentItem(nsIDOMXULElement** aResult)
{

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

@ -6,12 +6,12 @@
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="tree">
<!-- <content>
<content>
<children/>
<xul:treerows>
<children includes="treehead,treechildren"/>
</xul:treerows>
</content> -->
</content>
<interface>
<property name="treeBoxObject"
onget="return this.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject);"
@ -48,6 +48,12 @@
return this.treeBoxObject.ensureIndexIsVisible(index);
</body>
</method>
<method name="ensureElementIsVisible">
<argument name="element"/>
<body>
return this.ensureIndexIsVisible(this.treeBoxObject.getIndexOfItem(element));
</body>
</method>
<method name="scrollToIndex">
<argument name="index"/>
<body>