add new method to ensure that tree content is visible: go through all the presentation shells, and call EnsureRowIsVisible for each tree.
also expose a method to get the visible row for a tree - I needed it anyway, figured I might as well expose it from JS. other half of fix for #12895 r=bryner git-svn-id: svn://10.0.0.236/trunk@56942 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
a83dec26e2
commit
3ac59169d3
@ -34,9 +34,14 @@
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsITreeFrame.h"
|
||||
#include "nsString.h"
|
||||
|
||||
nsIAtom* nsXULTreeElement::kSelectedAtom;
|
||||
nsIAtom* nsXULTreeElement::kOpenAtom;
|
||||
nsIAtom* nsXULTreeElement::kTreeRowAtom;
|
||||
nsIAtom* nsXULTreeElement::kTreeItemAtom;
|
||||
int nsXULTreeElement::gRefCnt = 0;
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsXULTreeElement, nsXULAggregateElement);
|
||||
@ -69,6 +74,9 @@ nsXULTreeElement::nsXULTreeElement(nsIDOMXULElement* aOuter)
|
||||
{
|
||||
if (gRefCnt++ == 0) {
|
||||
kSelectedAtom = NS_NewAtom("selected");
|
||||
kOpenAtom = NS_NewAtom("open");
|
||||
kTreeRowAtom = NS_NewAtom("treerow");
|
||||
kTreeItemAtom = NS_NewAtom("treeitem");
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
@ -382,3 +390,125 @@ nsXULTreeElement::FireOnSelectHandler()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
return IndexOfContent(treeContent, elementContent, aReturn);
|
||||
}
|
||||
|
||||
|
||||
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 = document->GetShellAt(i);
|
||||
if (!shell)
|
||||
continue;
|
||||
|
||||
nsIFrame *frame;
|
||||
shell->GetPrimaryFrameFor(content, &frame);
|
||||
|
||||
if (frame) {
|
||||
nsITreeFrame *treeFrame = nsnull;
|
||||
rv = frame->QueryInterface(NS_GET_IID(nsITreeFrame),
|
||||
(void **)&treeFrame);
|
||||
if (NS_SUCCEEDED(rv) && treeFrame) {
|
||||
treeFrame->EnsureRowIsVisible(indexOfContent);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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,
|
||||
PRInt32 *aResult)
|
||||
{
|
||||
// number of rows that are direct children of aRoot
|
||||
// on success, add this to aResult
|
||||
PRInt32 rows=0;
|
||||
|
||||
PRInt32 childCount=0;
|
||||
aRoot->ChildCount(childCount);
|
||||
|
||||
PRInt32 childIndex;
|
||||
for (childIndex=0; childIndex<childCount; childIndex++) {
|
||||
nsCOMPtr<nsIContent> child;
|
||||
aContent->ChildAt(childIndex, *getter_AddRefs(child));
|
||||
|
||||
nsCOMPtr<nsIAtom> childTag;
|
||||
child->GetTag(*getter_AddRefs(childTag));
|
||||
|
||||
// we hit a treerow, count it
|
||||
if (childTag.get() == kTreeRowAtom)
|
||||
rows++;
|
||||
|
||||
// is this it?
|
||||
if (child.get() == aContent) {
|
||||
*aResult += rows;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// check children only if open="true"
|
||||
if (childTag.get() == kTreeItemAtom) {
|
||||
nsAutoString isOpen;
|
||||
child->GetAttribute(kNameSpaceID_None, kOpenAtom, isOpen);
|
||||
|
||||
if (isOpen == "true" &&
|
||||
NS_SUCCEEDED(IndexOfContent(child, aContent, aResult))) {
|
||||
|
||||
*aResult += rows;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// not found
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
@ -60,6 +60,9 @@ public:
|
||||
NS_IMETHOD FireOnSelectHandler();
|
||||
|
||||
static nsIAtom* kSelectedAtom;
|
||||
static nsIAtom* kOpenAtom;
|
||||
static nsIAtom* kTreeRowAtom;
|
||||
static nsIAtom* kTreeItemAtom;
|
||||
static int gRefCnt;
|
||||
|
||||
protected:
|
||||
@ -70,7 +73,9 @@ protected:
|
||||
void RemoveItemFromSelectionInternal(nsIDOMXULElement* aTreeItem);
|
||||
void AddCellToSelectionInternal(nsIDOMXULElement* aTreeCell);
|
||||
void RemoveCellFromSelectionInternal(nsIDOMXULElement* aTreeCell);
|
||||
|
||||
|
||||
static nsresult IndexOfContent(nsIContent *aRoot, nsIContent *aContent,
|
||||
PRInt32* aResult);
|
||||
protected:
|
||||
nsRDFDOMNodeList* mSelectedItems;
|
||||
nsRDFDOMNodeList* mSelectedCells;
|
||||
|
||||
@ -24,4 +24,7 @@ interface XULTreeElement : XULElement {
|
||||
|
||||
void selectAll();
|
||||
void invertSelection();
|
||||
|
||||
void ensureElementIsVisible(in XULElement element);
|
||||
long getRowIndexOf(in XULElement element);
|
||||
};
|
||||
|
||||
@ -905,6 +905,8 @@ enum nsDOMProp {
|
||||
NS_DOM_PROP_XULTREEELEMENT_SELECTITEMRANGE,
|
||||
NS_DOM_PROP_XULTREEELEMENT_TOGGLECELLSELECTION,
|
||||
NS_DOM_PROP_XULTREEELEMENT_TOGGLEITEMSELECTION,
|
||||
NS_DOM_PROP_XULTREEELEMENT_ENSUREELEMENTISVISIBLE,
|
||||
NS_DOM_PROP_XULTREEELEMENT_GETROWINDEXOF,
|
||||
NS_DOM_PROP_MAX
|
||||
};
|
||||
|
||||
|
||||
@ -71,6 +71,10 @@ public:
|
||||
NS_IMETHOD SelectAll()=0;
|
||||
|
||||
NS_IMETHOD InvertSelection()=0;
|
||||
|
||||
NS_IMETHOD EnsureElementIsVisible(nsIDOMXULElement* aElement)=0;
|
||||
|
||||
NS_IMETHOD GetRowIndexOf(nsIDOMXULElement* aElement, PRInt32* aReturn)=0;
|
||||
};
|
||||
|
||||
|
||||
@ -91,6 +95,8 @@ public:
|
||||
NS_IMETHOD SelectCellRange(nsIDOMXULElement* aStartItem, nsIDOMXULElement* aEndItem); \
|
||||
NS_IMETHOD SelectAll(); \
|
||||
NS_IMETHOD InvertSelection(); \
|
||||
NS_IMETHOD EnsureElementIsVisible(nsIDOMXULElement* aElement); \
|
||||
NS_IMETHOD GetRowIndexOf(nsIDOMXULElement* aElement, PRInt32* aReturn); \
|
||||
|
||||
|
||||
|
||||
@ -111,6 +117,8 @@ public:
|
||||
NS_IMETHOD SelectCellRange(nsIDOMXULElement* aStartItem, nsIDOMXULElement* aEndItem) { return _to SelectCellRange(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);
|
||||
|
||||
@ -942,6 +942,119 @@ 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;
|
||||
|
||||
{
|
||||
PRBool ok;
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
|
||||
NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECMAN_ERR);
|
||||
}
|
||||
secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULTREEELEMENT_ENSUREELEMENTISVISIBLE, PR_FALSE, &ok);
|
||||
if (!ok) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECURITY_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
"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;
|
||||
|
||||
{
|
||||
PRBool ok;
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
|
||||
NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECMAN_ERR);
|
||||
}
|
||||
secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULTREEELEMENT_GETROWINDEXOF, PR_FALSE, &ok);
|
||||
if (!ok) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECURITY_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
"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
|
||||
@ -990,6 +1103,8 @@ static JSFunctionSpec XULTreeElementMethods[] =
|
||||
{"selectCellRange", XULTreeElementSelectCellRange, 2},
|
||||
{"selectAll", XULTreeElementSelectAll, 0},
|
||||
{"invertSelection", XULTreeElementInvertSelection, 0},
|
||||
{"ensureElementIsVisible", XULTreeElementEnsureElementIsVisible, 1},
|
||||
{"getRowIndexOf", XULTreeElementGetRowIndexOf, 1},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
||||
@ -24,4 +24,7 @@ interface XULTreeElement : XULElement {
|
||||
|
||||
void selectAll();
|
||||
void invertSelection();
|
||||
|
||||
void ensureElementIsVisible(in XULElement element);
|
||||
long getRowIndexOf(in XULElement element);
|
||||
};
|
||||
|
||||
@ -71,6 +71,10 @@ public:
|
||||
NS_IMETHOD SelectAll()=0;
|
||||
|
||||
NS_IMETHOD InvertSelection()=0;
|
||||
|
||||
NS_IMETHOD EnsureElementIsVisible(nsIDOMXULElement* aElement)=0;
|
||||
|
||||
NS_IMETHOD GetRowIndexOf(nsIDOMXULElement* aElement, PRInt32* aReturn)=0;
|
||||
};
|
||||
|
||||
|
||||
@ -91,6 +95,8 @@ public:
|
||||
NS_IMETHOD SelectCellRange(nsIDOMXULElement* aStartItem, nsIDOMXULElement* aEndItem); \
|
||||
NS_IMETHOD SelectAll(); \
|
||||
NS_IMETHOD InvertSelection(); \
|
||||
NS_IMETHOD EnsureElementIsVisible(nsIDOMXULElement* aElement); \
|
||||
NS_IMETHOD GetRowIndexOf(nsIDOMXULElement* aElement, PRInt32* aReturn); \
|
||||
|
||||
|
||||
|
||||
@ -111,6 +117,8 @@ public:
|
||||
NS_IMETHOD SelectCellRange(nsIDOMXULElement* aStartItem, nsIDOMXULElement* aEndItem) { return _to SelectCellRange(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);
|
||||
|
||||
@ -942,6 +942,119 @@ 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;
|
||||
|
||||
{
|
||||
PRBool ok;
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
|
||||
NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECMAN_ERR);
|
||||
}
|
||||
secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULTREEELEMENT_ENSUREELEMENTISVISIBLE, PR_FALSE, &ok);
|
||||
if (!ok) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECURITY_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
"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;
|
||||
|
||||
{
|
||||
PRBool ok;
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
|
||||
NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECMAN_ERR);
|
||||
}
|
||||
secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULTREEELEMENT_GETROWINDEXOF, PR_FALSE, &ok);
|
||||
if (!ok) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECURITY_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
"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
|
||||
@ -990,6 +1103,8 @@ static JSFunctionSpec XULTreeElementMethods[] =
|
||||
{"selectCellRange", XULTreeElementSelectCellRange, 2},
|
||||
{"selectAll", XULTreeElementSelectAll, 0},
|
||||
{"invertSelection", XULTreeElementInvertSelection, 0},
|
||||
{"ensureElementIsVisible", XULTreeElementEnsureElementIsVisible, 1},
|
||||
{"getRowIndexOf", XULTreeElementGetRowIndexOf, 1},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
||||
@ -34,9 +34,14 @@
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsITreeFrame.h"
|
||||
#include "nsString.h"
|
||||
|
||||
nsIAtom* nsXULTreeElement::kSelectedAtom;
|
||||
nsIAtom* nsXULTreeElement::kOpenAtom;
|
||||
nsIAtom* nsXULTreeElement::kTreeRowAtom;
|
||||
nsIAtom* nsXULTreeElement::kTreeItemAtom;
|
||||
int nsXULTreeElement::gRefCnt = 0;
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsXULTreeElement, nsXULAggregateElement);
|
||||
@ -69,6 +74,9 @@ nsXULTreeElement::nsXULTreeElement(nsIDOMXULElement* aOuter)
|
||||
{
|
||||
if (gRefCnt++ == 0) {
|
||||
kSelectedAtom = NS_NewAtom("selected");
|
||||
kOpenAtom = NS_NewAtom("open");
|
||||
kTreeRowAtom = NS_NewAtom("treerow");
|
||||
kTreeItemAtom = NS_NewAtom("treeitem");
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
@ -382,3 +390,125 @@ nsXULTreeElement::FireOnSelectHandler()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
return IndexOfContent(treeContent, elementContent, aReturn);
|
||||
}
|
||||
|
||||
|
||||
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 = document->GetShellAt(i);
|
||||
if (!shell)
|
||||
continue;
|
||||
|
||||
nsIFrame *frame;
|
||||
shell->GetPrimaryFrameFor(content, &frame);
|
||||
|
||||
if (frame) {
|
||||
nsITreeFrame *treeFrame = nsnull;
|
||||
rv = frame->QueryInterface(NS_GET_IID(nsITreeFrame),
|
||||
(void **)&treeFrame);
|
||||
if (NS_SUCCEEDED(rv) && treeFrame) {
|
||||
treeFrame->EnsureRowIsVisible(indexOfContent);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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,
|
||||
PRInt32 *aResult)
|
||||
{
|
||||
// number of rows that are direct children of aRoot
|
||||
// on success, add this to aResult
|
||||
PRInt32 rows=0;
|
||||
|
||||
PRInt32 childCount=0;
|
||||
aRoot->ChildCount(childCount);
|
||||
|
||||
PRInt32 childIndex;
|
||||
for (childIndex=0; childIndex<childCount; childIndex++) {
|
||||
nsCOMPtr<nsIContent> child;
|
||||
aContent->ChildAt(childIndex, *getter_AddRefs(child));
|
||||
|
||||
nsCOMPtr<nsIAtom> childTag;
|
||||
child->GetTag(*getter_AddRefs(childTag));
|
||||
|
||||
// we hit a treerow, count it
|
||||
if (childTag.get() == kTreeRowAtom)
|
||||
rows++;
|
||||
|
||||
// is this it?
|
||||
if (child.get() == aContent) {
|
||||
*aResult += rows;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// check children only if open="true"
|
||||
if (childTag.get() == kTreeItemAtom) {
|
||||
nsAutoString isOpen;
|
||||
child->GetAttribute(kNameSpaceID_None, kOpenAtom, isOpen);
|
||||
|
||||
if (isOpen == "true" &&
|
||||
NS_SUCCEEDED(IndexOfContent(child, aContent, aResult))) {
|
||||
|
||||
*aResult += rows;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// not found
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
@ -60,6 +60,9 @@ public:
|
||||
NS_IMETHOD FireOnSelectHandler();
|
||||
|
||||
static nsIAtom* kSelectedAtom;
|
||||
static nsIAtom* kOpenAtom;
|
||||
static nsIAtom* kTreeRowAtom;
|
||||
static nsIAtom* kTreeItemAtom;
|
||||
static int gRefCnt;
|
||||
|
||||
protected:
|
||||
@ -70,7 +73,9 @@ protected:
|
||||
void RemoveItemFromSelectionInternal(nsIDOMXULElement* aTreeItem);
|
||||
void AddCellToSelectionInternal(nsIDOMXULElement* aTreeCell);
|
||||
void RemoveCellFromSelectionInternal(nsIDOMXULElement* aTreeCell);
|
||||
|
||||
|
||||
static nsresult IndexOfContent(nsIContent *aRoot, nsIContent *aContent,
|
||||
PRInt32* aResult);
|
||||
protected:
|
||||
nsRDFDOMNodeList* mSelectedItems;
|
||||
nsRDFDOMNodeList* mSelectedCells;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user