michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsReadableUtils.h" michael@0: #include "nsTreeUtils.h" michael@0: #include "ChildIterator.h" michael@0: #include "nsCRT.h" michael@0: #include "nsIAtom.h" michael@0: #include "nsNameSpaceManager.h" michael@0: #include "nsGkAtoms.h" michael@0: #include "nsINodeInfo.h" michael@0: michael@0: using namespace mozilla; michael@0: michael@0: nsresult michael@0: nsTreeUtils::TokenizeProperties(const nsAString& aProperties, AtomArray & aPropertiesArray) michael@0: { michael@0: nsAString::const_iterator end; michael@0: aProperties.EndReading(end); michael@0: michael@0: nsAString::const_iterator iter; michael@0: aProperties.BeginReading(iter); michael@0: michael@0: do { michael@0: // Skip whitespace michael@0: while (iter != end && nsCRT::IsAsciiSpace(*iter)) michael@0: ++iter; michael@0: michael@0: // If only whitespace, we're done michael@0: if (iter == end) michael@0: break; michael@0: michael@0: // Note the first non-whitespace character michael@0: nsAString::const_iterator first = iter; michael@0: michael@0: // Advance to the next whitespace character michael@0: while (iter != end && ! nsCRT::IsAsciiSpace(*iter)) michael@0: ++iter; michael@0: michael@0: // XXX this would be nonsensical michael@0: NS_ASSERTION(iter != first, "eh? something's wrong here"); michael@0: if (iter == first) michael@0: break; michael@0: michael@0: nsCOMPtr atom = do_GetAtom(Substring(first, iter)); michael@0: aPropertiesArray.AppendElement(atom); michael@0: } while (iter != end); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsIContent* michael@0: nsTreeUtils::GetImmediateChild(nsIContent* aContainer, nsIAtom* aTag) michael@0: { michael@0: dom::FlattenedChildIterator iter(aContainer); michael@0: for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { michael@0: if (child->Tag() == aTag) { michael@0: return child; michael@0: } michael@0: } michael@0: michael@0: return nullptr; michael@0: } michael@0: michael@0: nsIContent* michael@0: nsTreeUtils::GetDescendantChild(nsIContent* aContainer, nsIAtom* aTag) michael@0: { michael@0: dom::FlattenedChildIterator iter(aContainer); michael@0: for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { michael@0: if (child->Tag() == aTag) { michael@0: return child; michael@0: } michael@0: michael@0: child = GetDescendantChild(child, aTag); michael@0: if (child) { michael@0: return child; michael@0: } michael@0: } michael@0: michael@0: return nullptr; michael@0: } michael@0: michael@0: nsresult michael@0: nsTreeUtils::UpdateSortIndicators(nsIContent* aColumn, const nsAString& aDirection) michael@0: { michael@0: aColumn->SetAttr(kNameSpaceID_None, nsGkAtoms::sortDirection, aDirection, true); michael@0: aColumn->SetAttr(kNameSpaceID_None, nsGkAtoms::sortActive, NS_LITERAL_STRING("true"), true); michael@0: michael@0: // Unset sort attribute(s) on the other columns michael@0: nsCOMPtr parentContent = aColumn->GetParent(); michael@0: if (parentContent && michael@0: parentContent->NodeInfo()->Equals(nsGkAtoms::treecols, michael@0: kNameSpaceID_XUL)) { michael@0: uint32_t i, numChildren = parentContent->GetChildCount(); michael@0: for (i = 0; i < numChildren; ++i) { michael@0: nsCOMPtr childContent = parentContent->GetChildAt(i); michael@0: michael@0: if (childContent && michael@0: childContent != aColumn && michael@0: childContent->NodeInfo()->Equals(nsGkAtoms::treecol, michael@0: kNameSpaceID_XUL)) { michael@0: childContent->UnsetAttr(kNameSpaceID_None, michael@0: nsGkAtoms::sortDirection, true); michael@0: childContent->UnsetAttr(kNameSpaceID_None, michael@0: nsGkAtoms::sortActive, true); michael@0: } michael@0: } michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsTreeUtils::GetColumnIndex(nsIContent* aColumn, int32_t* aResult) michael@0: { michael@0: nsIContent* parentContent = aColumn->GetParent(); michael@0: if (parentContent && michael@0: parentContent->NodeInfo()->Equals(nsGkAtoms::treecols, michael@0: kNameSpaceID_XUL)) { michael@0: uint32_t i, numChildren = parentContent->GetChildCount(); michael@0: int32_t colIndex = 0; michael@0: for (i = 0; i < numChildren; ++i) { michael@0: nsIContent *childContent = parentContent->GetChildAt(i); michael@0: if (childContent && michael@0: childContent->NodeInfo()->Equals(nsGkAtoms::treecol, michael@0: kNameSpaceID_XUL)) { michael@0: if (childContent == aColumn) { michael@0: *aResult = colIndex; michael@0: return NS_OK; michael@0: } michael@0: ++colIndex; michael@0: } michael@0: } michael@0: } michael@0: michael@0: *aResult = -1; michael@0: return NS_OK; michael@0: }