void nsTreeContentView::ToggleOpenState(int32_t aRow, ErrorResult& aError) { if (!IsValidRowIndex(aRow)) { aError.Throw(NS_ERROR_INVALID_ARG); return; } // We don't serialize content right here, since content might be generated // lazily. Row* row = mRows[aRow].get(); if (row->IsOpen()) row->mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::open, NS_LITERAL_STRING("false"), true); else row->mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::open, NS_LITERAL_STRING("true"), true); }
NS_IMETHODIMP nsTreeContentView::ToggleOpenState(int32_t aIndex) { NS_PRECONDITION(aIndex >= 0 && aIndex < int32_t(mRows.Length()), "bad index"); if (aIndex < 0 || aIndex >= int32_t(mRows.Length())) return NS_ERROR_INVALID_ARG; // We don't serialize content right here, since content might be generated // lazily. Row* row = mRows[aIndex]; if (row->IsOpen()) row->mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::open, NS_LITERAL_STRING("false"), true); else row->mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::open, NS_LITERAL_STRING("true"), true); return NS_OK; }
void nsTreeContentView::AttributeChanged(nsIDocument* aDocument, dom::Element* aElement, int32_t aNameSpaceID, nsAtom* aAttribute, int32_t aModType, const nsAttrValue* aOldValue) { // Lots of codepaths under here that do all sorts of stuff, so be safe. nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this); // Make sure this notification concerns us. // First check the tag to see if it's one that we care about. if (mBoxObject && (aElement == mRoot || aElement == mBody)) { mBoxObject->ClearStyleAndImageCaches(); mBoxObject->Invalidate(); } // We don't consider non-XUL nodes. nsIContent* parent = nullptr; if (!aElement->IsXULElement() || ((parent = aElement->GetParent()) && !parent->IsXULElement())) { return; } if (!aElement->IsAnyOfXULElements(nsGkAtoms::treecol, nsGkAtoms::treeitem, nsGkAtoms::treeseparator, nsGkAtoms::treerow, nsGkAtoms::treecell)) { return; } // If we have a legal tag, go up to the tree/select and make sure // that it's ours. for (nsIContent* element = aElement; element != mBody; element = element->GetParent()) { if (!element) return; // this is not for us if (element->IsXULElement(nsGkAtoms::tree)) return; // this is not for us } // Handle changes of the hidden attribute. if (aAttribute == nsGkAtoms::hidden && aElement->IsAnyOfXULElements(nsGkAtoms::treeitem, nsGkAtoms::treeseparator)) { bool hidden = aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::hidden, nsGkAtoms::_true, eCaseMatters); int32_t index = FindContent(aElement); if (hidden && index >= 0) { // Hide this row along with its children. int32_t count = RemoveRow(index); if (mBoxObject) mBoxObject->RowCountChanged(index, -count); } else if (!hidden && index < 0) { // Show this row along with its children. nsCOMPtr<nsIContent> parent = aElement->GetParent(); if (parent) { InsertRowFor(parent, aElement); } } return; } if (aElement->IsXULElement(nsGkAtoms::treecol)) { if (aAttribute == nsGkAtoms::properties) { if (mBoxObject) { nsCOMPtr<nsITreeColumns> cols; mBoxObject->GetColumns(getter_AddRefs(cols)); if (cols) { nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aElement); nsCOMPtr<nsITreeColumn> col; cols->GetColumnFor(element, getter_AddRefs(col)); mBoxObject->InvalidateColumn(col); } } } } else if (aElement->IsXULElement(nsGkAtoms::treeitem)) { int32_t index = FindContent(aElement); if (index >= 0) { Row* row = mRows[index].get(); if (aAttribute == nsGkAtoms::container) { bool isContainer = aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::container, nsGkAtoms::_true, eCaseMatters); row->SetContainer(isContainer); if (mBoxObject) mBoxObject->InvalidateRow(index); } else if (aAttribute == nsGkAtoms::open) { bool isOpen = aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::open, nsGkAtoms::_true, eCaseMatters); bool wasOpen = row->IsOpen(); if (! isOpen && wasOpen) CloseContainer(index); else if (isOpen && ! wasOpen) OpenContainer(index); } else if (aAttribute == nsGkAtoms::empty) { bool isEmpty = aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::empty, nsGkAtoms::_true, eCaseMatters); row->SetEmpty(isEmpty); if (mBoxObject) mBoxObject->InvalidateRow(index); } } } else if (aElement->IsXULElement(nsGkAtoms::treeseparator)) { int32_t index = FindContent(aElement); if (index >= 0) { if (aAttribute == nsGkAtoms::properties && mBoxObject) { mBoxObject->InvalidateRow(index); } } } else if (aElement->IsXULElement(nsGkAtoms::treerow)) { if (aAttribute == nsGkAtoms::properties) { nsCOMPtr<nsIContent> parent = aElement->GetParent(); if (parent) { int32_t index = FindContent(parent); if (index >= 0 && mBoxObject) { mBoxObject->InvalidateRow(index); } } } } else if (aElement->IsXULElement(nsGkAtoms::treecell)) { if (aAttribute == nsGkAtoms::properties || aAttribute == nsGkAtoms::mode || aAttribute == nsGkAtoms::src || aAttribute == nsGkAtoms::value || aAttribute == nsGkAtoms::label) { nsIContent* parent = aElement->GetParent(); if (parent) { nsCOMPtr<nsIContent> grandParent = parent->GetParent(); if (grandParent && grandParent->IsXULElement()) { int32_t index = FindContent(grandParent); if (index >= 0 && mBoxObject) { // XXX Should we make an effort to invalidate only cell ? mBoxObject->InvalidateRow(index); } } } } } }
void nsTreeContentView::ContentInserted(nsIDocument *aDocument, nsIContent* aContainer, nsIContent* aChild) { NS_ASSERTION(aChild, "null ptr"); // Make sure this notification concerns us. // First check the tag to see if it's one that we care about. // Don't allow non-XUL nodes. if (!aChild->IsXULElement() || !aContainer->IsXULElement()) return; if (!aChild->IsAnyOfXULElements(nsGkAtoms::treeitem, nsGkAtoms::treeseparator, nsGkAtoms::treechildren, nsGkAtoms::treerow, nsGkAtoms::treecell)) { return; } // If we have a legal tag, go up to the tree/select and make sure // that it's ours. for (nsIContent* element = aContainer; element != mBody; element = element->GetParent()) { if (!element) return; // this is not for us if (element->IsXULElement(nsGkAtoms::tree)) return; // this is not for us } // Lots of codepaths under here that do all sorts of stuff, so be safe. nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this); if (aChild->IsXULElement(nsGkAtoms::treechildren)) { int32_t index = FindContent(aContainer); if (index >= 0) { Row* row = mRows[index].get(); row->SetEmpty(false); if (mBoxObject) mBoxObject->InvalidateRow(index); if (row->IsContainer() && row->IsOpen()) { int32_t count = EnsureSubtree(index); if (mBoxObject) mBoxObject->RowCountChanged(index + 1, count); } } } else if (aChild->IsAnyOfXULElements(nsGkAtoms::treeitem, nsGkAtoms::treeseparator)) { InsertRowFor(aContainer, aChild); } else if (aChild->IsXULElement(nsGkAtoms::treerow)) { int32_t index = FindContent(aContainer); if (index >= 0 && mBoxObject) mBoxObject->InvalidateRow(index); } else if (aChild->IsXULElement(nsGkAtoms::treecell)) { nsCOMPtr<nsIContent> parent = aContainer->GetParent(); if (parent) { int32_t index = FindContent(parent); if (index >= 0 && mBoxObject) mBoxObject->InvalidateRow(index); } } }