nsresult
nsTextEquivUtils::GetNameFromSubtree(nsIAccessible *aAccessible,
                                     nsAString& aName)
{
  aName.Truncate();

  if (gInitiatorAcc)
    return NS_OK;

  gInitiatorAcc = aAccessible;

  PRUint32 role = nsAccUtils::Role(aAccessible);
  PRUint32 nameRule = gRoleToNameRulesMap[role];

  if (nameRule == eFromSubtree) {
    nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(aAccessible));

    nsCOMPtr<nsIDOMNode> DOMNode;
    accessNode->GetDOMNode(getter_AddRefs(DOMNode));
    nsCOMPtr<nsIContent> content(do_QueryInterface(DOMNode));
    if (content) {
      nsAutoString name;
      AppendFromAccessibleChildren(aAccessible, &name);
      name.CompressWhitespace();
      if (!IsWhitespaceString(name))
        aName = name;
    }
  }

  gInitiatorAcc = nsnull;

  return NS_OK;
}
nsresult
nsTextEquivUtils::GetNameFromSubtree(nsAccessible *aAccessible,
                                     nsAString& aName)
{
  aName.Truncate();

  if (gInitiatorAcc)
    return NS_OK;

  gInitiatorAcc = aAccessible;

  PRUint32 nameRule = gRoleToNameRulesMap[aAccessible->Role()];
  if (nameRule == eFromSubtree) {
    //XXX: is it necessary to care the accessible is not a document?
    if (aAccessible->IsContent()) {
      nsAutoString name;
      AppendFromAccessibleChildren(aAccessible, &name);
      name.CompressWhitespace();
      if (!IsWhitespaceString(name))
        aName = name;
    }
  }

  gInitiatorAcc = nsnull;

  return NS_OK;
}
nsresult
nsTextEquivUtils::AppendFromAccessible(nsIAccessible *aAccessible,
                                       nsAString *aString)
{
  nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(aAccessible));

  nsCOMPtr<nsIDOMNode> DOMNode;
  accessNode->GetDOMNode(getter_AddRefs(DOMNode));
  nsCOMPtr<nsIContent> content(do_QueryInterface(DOMNode));
  NS_ASSERTION(content, "There is no content!");

  if (content) {
    nsresult rv = AppendTextEquivFromTextContent(content, aString);
    if (rv != NS_OK_NO_NAME_CLAUSE_HANDLED)
      return rv;
  }

  nsAutoString text;
  nsresult rv = aAccessible->GetName(text);
  NS_ENSURE_SUCCESS(rv, rv);

  PRBool isEmptyTextEquiv = PR_TRUE;

  // If the name is from tooltip then append it to result string in the end
  // (see h. step of name computation guide).
  if (rv != NS_OK_NAME_FROM_TOOLTIP)
    isEmptyTextEquiv = !AppendString(aString, text);

  // Implementation of f. step.
  rv = AppendFromValue(aAccessible, aString);
  NS_ENSURE_SUCCESS(rv, rv);

  if (rv != NS_OK_NO_NAME_CLAUSE_HANDLED)
    isEmptyTextEquiv = PR_FALSE;

  // Implementation of g) step of text equivalent computation guide. Go down
  // into subtree if accessible allows "text equivalent from subtree rule" or
  // it's not root and not control.
  if (isEmptyTextEquiv) {
    PRUint32 role = nsAccUtils::Role(aAccessible);
    PRUint32 nameRule = gRoleToNameRulesMap[role];

    if (nameRule & eFromSubtreeIfRec) {
      rv = AppendFromAccessibleChildren(aAccessible, aString);
      NS_ENSURE_SUCCESS(rv, rv);

      if (rv != NS_OK_NO_NAME_CLAUSE_HANDLED)
        isEmptyTextEquiv = PR_FALSE;
    }
  }

  // Implementation of h. step
  if (isEmptyTextEquiv && !text.IsEmpty()) {
    AppendString(aString, text);
    return NS_OK;
  }

  return rv;
}
nsresult
nsTextEquivUtils::AppendFromAccessible(nsAccessible *aAccessible,
                                       nsAString *aString)
{
  //XXX: is it necessary to care the accessible is not a document?
  if (aAccessible->IsContent()) {
    nsresult rv = AppendTextEquivFromTextContent(aAccessible->GetContent(),
                                                 aString);
    if (rv != NS_OK_NO_NAME_CLAUSE_HANDLED)
      return rv;
  }

  nsAutoString text;
  nsresult rv = aAccessible->GetName(text);
  NS_ENSURE_SUCCESS(rv, rv);

  bool isEmptyTextEquiv = true;

  // If the name is from tooltip then append it to result string in the end
  // (see h. step of name computation guide).
  if (rv != NS_OK_NAME_FROM_TOOLTIP)
    isEmptyTextEquiv = !AppendString(aString, text);

  // Implementation of f. step.
  rv = AppendFromValue(aAccessible, aString);
  NS_ENSURE_SUCCESS(rv, rv);

  if (rv != NS_OK_NO_NAME_CLAUSE_HANDLED)
    isEmptyTextEquiv = PR_FALSE;

  // Implementation of g) step of text equivalent computation guide. Go down
  // into subtree if accessible allows "text equivalent from subtree rule" or
  // it's not root and not control.
  if (isEmptyTextEquiv) {
    PRUint32 nameRule = gRoleToNameRulesMap[aAccessible->Role()];
    if (nameRule & eFromSubtreeIfRec) {
      rv = AppendFromAccessibleChildren(aAccessible, aString);
      NS_ENSURE_SUCCESS(rv, rv);

      if (rv != NS_OK_NO_NAME_CLAUSE_HANDLED)
        isEmptyTextEquiv = PR_FALSE;
    }
  }

  // Implementation of h. step
  if (isEmptyTextEquiv && !text.IsEmpty()) {
    AppendString(aString, text);
    return NS_OK;
  }

  return rv;
}