mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
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:
parent
5b3486f79b
commit
38a22efa6b
@ -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;
|
||||
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user