Fix for bug 139290. Interaction between windows leads to doubled bookmarks.

r=bryner, sr=jag
- cache the open state of container instead of quering the data source every time
This commit is contained in:
varga%netscape.com 2003-03-16 11:29:02 +00:00
parent 5b3486f79b
commit 38a22efa6b
3 changed files with 52 additions and 20 deletions

View File

@ -247,6 +247,7 @@ nsTreeRows::Subtree::InsertRowAt(nsTemplateMatch* aMatch, PRInt32 aIndex)
mRows[aIndex].mMatch = aMatch;
mRows[aIndex].mContainerType = eContainerType_Unknown;
mRows[aIndex].mContainerState = eContainerState_Unknown;
mRows[aIndex].mContainerFill = eContainerFill_Unknown;
mRows[aIndex].mSubtree = nsnull;
++mCount;

View File

@ -69,8 +69,14 @@ public:
enum ContainerState {
eContainerState_Unknown = 0,
eContainerState_Empty = 1,
eContainerState_Nonempty = -2
eContainerState_Open = 1,
eContainerState_Closed = -2
};
enum ContainerFill {
eContainerFill_Unknown = 0,
eContainerFill_Empty = 1,
eContainerFill_Nonempty = -2
};
class Subtree;
@ -84,6 +90,8 @@ public:
nsTemplateMatch* mMatch;
ContainerType mContainerType : 2;
ContainerState mContainerState : 2;
ContainerFill mContainerFill : 2;
Subtree* mSubtree; // XXX eventually move to hashtable
};

View File

@ -588,7 +588,19 @@ nsXULTreeBuilder::IsContainerOpen(PRInt32 aIndex, PRBool* aResult)
if (aIndex < 0 || aIndex >= mRows.Count())
return NS_ERROR_INVALID_ARG;
return IsContainerOpen(GetResourceFor(aIndex), aResult);
nsTreeRows::iterator iter = mRows[aIndex];
if (iter->mContainerState == nsTreeRows::eContainerState_Unknown) {
PRBool isOpen;
IsContainerOpen(GetResourceFor(aIndex), &isOpen);
iter->mContainerState = isOpen
? nsTreeRows::eContainerState_Open
: nsTreeRows::eContainerState_Closed;
}
*aResult = (iter->mContainerState == nsTreeRows::eContainerState_Open);
return NS_OK;
}
NS_IMETHODIMP
@ -602,16 +614,16 @@ nsXULTreeBuilder::IsContainerEmpty(PRInt32 aIndex, PRBool* aResult)
NS_ASSERTION(iter->mContainerType == nsTreeRows::eContainerType_Container,
"asking for empty state on non-container");
if (iter->mContainerState == nsTreeRows::eContainerState_Unknown) {
if (iter->mContainerFill == nsTreeRows::eContainerFill_Unknown) {
PRBool isEmpty;
CheckContainer(GetResourceFor(aIndex), nsnull, &isEmpty);
iter->mContainerState = isEmpty
? nsTreeRows::eContainerState_Empty
: nsTreeRows::eContainerState_Nonempty;
iter->mContainerFill = isEmpty
? nsTreeRows::eContainerFill_Empty
: nsTreeRows::eContainerFill_Nonempty;
}
*aResult = (iter->mContainerState == nsTreeRows::eContainerState_Empty);
*aResult = (iter->mContainerFill == nsTreeRows::eContainerFill_Empty);
return NS_OK;
}
@ -859,25 +871,32 @@ nsXULTreeBuilder::ToggleOpenState(PRInt32 aIndex)
}
if (mPersistStateStore) {
nsTreeRows::iterator iter = mRows[aIndex];
PRBool isOpen = iter->mContainerState == nsTreeRows::eContainerState_Open;
nsIRDFResource* container = GetResourceFor(aIndex);
if (! container)
return NS_ERROR_FAILURE;
PRBool open;
IsContainerOpen(container, &open);
PRBool hasProperty;
IsContainerOpen(container, &hasProperty);
if (open) {
mPersistStateStore->Unassert(container,
nsXULContentUtils::NC_open,
nsXULContentUtils::true_);
if (isOpen) {
if (hasProperty) {
mPersistStateStore->Unassert(container,
nsXULContentUtils::NC_open,
nsXULContentUtils::true_);
}
CloseContainer(aIndex, container);
}
else {
mPersistStateStore->Assert(VALUE_TO_IRDFRESOURCE(container),
nsXULContentUtils::NC_open,
nsXULContentUtils::true_,
PR_TRUE);
if (! hasProperty) {
mPersistStateStore->Assert(VALUE_TO_IRDFRESOURCE(container),
nsXULContentUtils::NC_open,
nsXULContentUtils::true_,
PR_TRUE);
}
OpenContainer(aIndex, container);
}
@ -1181,9 +1200,9 @@ nsXULTreeBuilder::ReplaceMatch(nsIRDFResource* aMember,
// container, so whether its open or closed, make sure
// that we've got our tree row's state correct.
if ((iter->mContainerType != nsTreeRows::eContainerType_Container) ||
(iter->mContainerState != nsTreeRows::eContainerState_Nonempty)) {
(iter->mContainerFill != nsTreeRows::eContainerFill_Nonempty)) {
iter->mContainerType = nsTreeRows::eContainerType_Container;
iter->mContainerState = nsTreeRows::eContainerState_Nonempty;
iter->mContainerFill = nsTreeRows::eContainerFill_Nonempty;
mBoxObject->InvalidateRow(iter.GetRowIndex());
}
}
@ -1565,6 +1584,8 @@ nsXULTreeBuilder::OpenContainer(PRInt32 aIndex, nsIRDFResource* aContainer)
nsTreeRows::iterator iter = mRows[aIndex];
container = mRows.EnsureSubtreeFor(iter.GetParent(),
iter.GetChildIndex());
iter->mContainerState = nsTreeRows::eContainerState_Open;
}
else
container = mRows.GetRoot();
@ -1771,6 +1792,8 @@ nsXULTreeBuilder::CloseContainer(PRInt32 aIndex, nsIRDFResource* aContainer)
PRInt32 count = mRows.GetSubtreeSizeFor(iter);
mRows.RemoveSubtreeFor(iter);
iter->mContainerState = nsTreeRows::eContainerState_Closed;
if (mBoxObject) {
mBoxObject->InvalidateRow(aIndex);