diff --git a/content/xul/content/src/nsXULElement.cpp b/content/xul/content/src/nsXULElement.cpp index 928edbf1a982..db7230650cfd 100644 --- a/content/xul/content/src/nsXULElement.cpp +++ b/content/xul/content/src/nsXULElement.cpp @@ -114,6 +114,7 @@ #include "nsIDOMViewCSS.h" #include "nsIDOMCSSStyleDeclaration.h" #include "nsXULAtoms.h" +#include "nsITreeBoxObject.h" // Used for the temporary DOM Level2 hack #include "nsIPref.h" @@ -2506,14 +2507,17 @@ nsXULElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify) // the possibility exists that some of the items in the removed subtree // are selected (and therefore need to be deselected). We need to account for this. nsCOMPtr tag; + nsCOMPtr treeElement; + nsCOMPtr treeBox; + PRInt32 newSelectIndex = -1; + PRBool fireSelectionHandler = PR_FALSE; + oldKid->GetTag(*getter_AddRefs(tag)); if (tag && (tag.get() == nsXULAtoms::treechildren || tag.get() == nsXULAtoms::treeitem || tag.get() == nsXULAtoms::treecell)) { // This is the nasty case. We have (potentially) a slew of selected items // and cells going away. // First, retrieve the tree. - nsCOMPtr treeElement; - // Check first whether this element IS the tree treeElement = do_QueryInterface((nsIDOMXULElement*)this); @@ -2525,7 +2529,6 @@ nsXULElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify) treeElement->GetSelectedItems(getter_AddRefs(itemList)); nsCOMPtr parentKid = do_QueryInterface(oldKid); - PRBool fireSelectionHandler = PR_FALSE; if (itemList) { // Iterate over all of the items and find out if they are contained inside // the removed subtree. @@ -2542,13 +2545,22 @@ nsXULElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify) fireSelectionHandler = PR_TRUE; } } - } + } - if (fireSelectionHandler) { - nsCOMPtr tree = do_QueryInterface(treeElement); - if (tree) { - tree->FireOnSelectHandler(); - } + nsCOMPtr curItem; + treeElement->GetCurrentItem(getter_AddRefs(curItem)); + nsCOMPtr curNode = do_QueryInterface(curItem); + if (IsAncestor(parentKid, curNode)) { + // Current item going away + nsCOMPtr box; + treeElement->GetBoxObject(getter_AddRefs(box)); + treeBox = do_QueryInterface(box); + if (treeBox) { + nsCOMPtr domElem = do_QueryInterface(parentKid); + if (domElem) { + treeBox->GetIndexOfItem(domElem, &newSelectIndex); + } + } } } } @@ -2561,6 +2573,23 @@ nsXULElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify) doc->ContentRemoved(NS_STATIC_CAST(nsIStyledContent*, this), oldKid, aIndex); } + if (newSelectIndex != -1) { + nsCOMPtr newSelectItem; + treeBox->GetItemAtIndex(newSelectIndex, getter_AddRefs(newSelectItem)); + if (newSelectItem) { + nsCOMPtr xulSelItem = do_QueryInterface(newSelectItem); + if (xulSelItem) + treeElement->SetCurrentItem(xulSelItem); + } + } + + if (fireSelectionHandler) { + nsCOMPtr tree = do_QueryInterface(treeElement); + if (tree) { + tree->FireOnSelectHandler(); + } + } + // This will cause the script object to be unrooted for each // element in the subtree. oldKid->SetDocument(nsnull, PR_TRUE, PR_TRUE); diff --git a/rdf/content/src/nsXULElement.cpp b/rdf/content/src/nsXULElement.cpp index 928edbf1a982..db7230650cfd 100644 --- a/rdf/content/src/nsXULElement.cpp +++ b/rdf/content/src/nsXULElement.cpp @@ -114,6 +114,7 @@ #include "nsIDOMViewCSS.h" #include "nsIDOMCSSStyleDeclaration.h" #include "nsXULAtoms.h" +#include "nsITreeBoxObject.h" // Used for the temporary DOM Level2 hack #include "nsIPref.h" @@ -2506,14 +2507,17 @@ nsXULElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify) // the possibility exists that some of the items in the removed subtree // are selected (and therefore need to be deselected). We need to account for this. nsCOMPtr tag; + nsCOMPtr treeElement; + nsCOMPtr treeBox; + PRInt32 newSelectIndex = -1; + PRBool fireSelectionHandler = PR_FALSE; + oldKid->GetTag(*getter_AddRefs(tag)); if (tag && (tag.get() == nsXULAtoms::treechildren || tag.get() == nsXULAtoms::treeitem || tag.get() == nsXULAtoms::treecell)) { // This is the nasty case. We have (potentially) a slew of selected items // and cells going away. // First, retrieve the tree. - nsCOMPtr treeElement; - // Check first whether this element IS the tree treeElement = do_QueryInterface((nsIDOMXULElement*)this); @@ -2525,7 +2529,6 @@ nsXULElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify) treeElement->GetSelectedItems(getter_AddRefs(itemList)); nsCOMPtr parentKid = do_QueryInterface(oldKid); - PRBool fireSelectionHandler = PR_FALSE; if (itemList) { // Iterate over all of the items and find out if they are contained inside // the removed subtree. @@ -2542,13 +2545,22 @@ nsXULElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify) fireSelectionHandler = PR_TRUE; } } - } + } - if (fireSelectionHandler) { - nsCOMPtr tree = do_QueryInterface(treeElement); - if (tree) { - tree->FireOnSelectHandler(); - } + nsCOMPtr curItem; + treeElement->GetCurrentItem(getter_AddRefs(curItem)); + nsCOMPtr curNode = do_QueryInterface(curItem); + if (IsAncestor(parentKid, curNode)) { + // Current item going away + nsCOMPtr box; + treeElement->GetBoxObject(getter_AddRefs(box)); + treeBox = do_QueryInterface(box); + if (treeBox) { + nsCOMPtr domElem = do_QueryInterface(parentKid); + if (domElem) { + treeBox->GetIndexOfItem(domElem, &newSelectIndex); + } + } } } } @@ -2561,6 +2573,23 @@ nsXULElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify) doc->ContentRemoved(NS_STATIC_CAST(nsIStyledContent*, this), oldKid, aIndex); } + if (newSelectIndex != -1) { + nsCOMPtr newSelectItem; + treeBox->GetItemAtIndex(newSelectIndex, getter_AddRefs(newSelectItem)); + if (newSelectItem) { + nsCOMPtr xulSelItem = do_QueryInterface(newSelectItem); + if (xulSelItem) + treeElement->SetCurrentItem(xulSelItem); + } + } + + if (fireSelectionHandler) { + nsCOMPtr tree = do_QueryInterface(treeElement); + if (tree) { + tree->FireOnSelectHandler(); + } + } + // This will cause the script object to be unrooted for each // element in the subtree. oldKid->SetDocument(nsnull, PR_TRUE, PR_TRUE);