зеркало из https://github.com/mozilla/pjs.git
30511. r=ben
This commit is contained in:
Родитель
c23c45c768
Коммит
47ecc64920
|
@ -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>
|
||||
|
|
Загрузка…
Ссылка в новой задаче