void
WalkAncestorsResetAutoDirection(Element* aElement, bool aNotify)
{
  nsINode* setByNode;
  Element* parent = aElement->GetElementParent();

  while (parent && parent->NodeOrAncestorHasDirAuto()) {
    if (parent->HasDirAutoSet()) {
      // If the parent has the DirAutoSet flag, its direction is determined by
      // some text node descendant.
      // Remove it from the map and reset its direction by the downward
      // propagation algorithm
      setByNode =
        static_cast<nsINode*>(parent->GetProperty(nsGkAtoms::dirAutoSetBy));
      if (setByNode) {
        nsTextNodeDirectionalityMap::RemoveElementFromMap(setByNode, parent);
      }
    }
    if (parent->HasDirAuto()) {
      setByNode = WalkDescendantsSetDirectionFromText(parent, aNotify);
      if (setByNode) {
        nsTextNodeDirectionalityMap::AddEntryToMap(setByNode, parent);
      }
      break;
    }
    parent = parent->GetElementParent();
  }
}
void
WalkDescendantsSetDirAuto(Element* aElement, bool aNotify)
{
  bool setAncestorDirAutoFlag =
#ifdef DEBUG
    true;
#else
    !aElement->AncestorHasDirAuto();
#endif

  if (setAncestorDirAutoFlag) {
    nsIContent* child = aElement->GetFirstChild();
    while (child) {
      MOZ_ASSERT(!aElement->AncestorHasDirAuto() ||
                 child->AncestorHasDirAuto(),
                 "AncestorHasDirAuto set on node but not its children");
      child->SetHasDirAuto();
      child = child->GetNextNode(aElement);
    }
  }

  nsINode* textNode = WalkDescendantsSetDirectionFromText(aElement, aNotify);
  if (textNode) {
    nsTextNodeDirectionalityMap::AddEntryToMap(textNode, aElement);
  }
}
 static PLDHashOperator ResetNodeDirection(nsPtrHashKey<Element>* aEntry, void* aData)
 {
   MOZ_ASSERT(aEntry->GetKey()->IsElement(), "Must be an Element");
   // run the downward propagation algorithm
   // and remove the text node from the map
   Element* rootNode = aEntry->GetKey();
   nsINode* textNode = WalkDescendantsSetDirectionFromText(rootNode, true);
   if (textNode) {
     nsTextNodeDirectionalityMap::AddEntryToMap(textNode, rootNode);
   } else {
     rootNode->ClearHasDirAutoSet();
     rootNode->UnsetProperty(nsGkAtoms::dirAutoSetBy);
   }
   return PL_DHASH_REMOVE;
 }