Backed out changeset 6ad72777c10d (bug 1274381) for causing m-oth failures
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 21 Sep 2016 15:25:15 +0200
changeset 355671 1563e99859383adaf22a8c285c8ec70e1db2e49b
parent 355670 9f757cfe0d33de3805de29045f9394323d4aa067
child 355672 7008e3ee291ec274025d72ebd157eef7588da291
push id6570
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:26:13 +0000
treeherdermozilla-beta@f455459b2ae5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1274381
milestone51.0a2
backs out6ad72777c10d5bd2c3107eafe922ccf2e130deff
Backed out changeset 6ad72777c10d (bug 1274381) for causing m-oth failures
accessible/base/TreeWalker.cpp
accessible/base/TreeWalker.h
accessible/generic/DocAccessible.cpp
--- a/accessible/base/TreeWalker.cpp
+++ b/accessible/base/TreeWalker.cpp
@@ -52,24 +52,39 @@ TreeWalker::
   MOZ_COUNT_CTOR(TreeWalker);
 }
 
 TreeWalker::~TreeWalker()
 {
   MOZ_COUNT_DTOR(TreeWalker);
 }
 
+Accessible*
+TreeWalker::Scope(nsIContent* aAnchorNode)
+{
+  Reset();
+
+  mAnchorNode = aAnchorNode;
+
+  bool skipSubtree = false;
+  Accessible* acc = AccessibleFor(aAnchorNode, 0, &skipSubtree);
+  if (acc) {
+    mPhase = eAtEnd;
+    return acc;
+  }
+
+  return skipSubtree ? nullptr : Next();
+}
+
 bool
 TreeWalker::Seek(nsIContent* aChildNode)
 {
   MOZ_ASSERT(aChildNode, "Child cannot be null");
 
-  mPhase = eAtStart;
-  mStateStack.Clear();
-  mARIAOwnsIdx = 0;
+  Reset();
 
   nsIContent* childNode = nullptr;
   nsINode* parentNode = aChildNode;
   do {
     childNode = parentNode->AsContent();
     parentNode = childNode->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR) &&
       (mChildFilter & nsIContent::eAllButXBL) ?
       childNode->GetParentNode() : childNode->GetFlattenedTreeParent();
@@ -105,17 +120,17 @@ TreeWalker::Seek(nsIContent* aChildNode)
       return true;
     }
   } while (true);
 
   return false;
 }
 
 Accessible*
-TreeWalker::Next(nsIContent* aStopNode)
+TreeWalker::Next()
 {
   if (mStateStack.IsEmpty()) {
     if (mPhase == eAtEnd) {
       return nullptr;
     }
 
     if (mPhase == eAtDOM || mPhase == eAtARIAOwns) {
       mPhase = eAtARIAOwns;
@@ -134,72 +149,64 @@ TreeWalker::Next(nsIContent* aStopNode)
     }
 
     mPhase = eAtDOM;
     PushState(mAnchorNode, true);
   }
 
   dom::AllChildrenIterator* top = &mStateStack[mStateStack.Length() - 1];
   while (top) {
-    if (aStopNode && top->Get() == aStopNode) {
-      return nullptr;
-    }
-
     while (nsIContent* childNode = top->GetNextChild()) {
       bool skipSubtree = false;
       Accessible* child = AccessibleFor(childNode, mFlags, &skipSubtree);
       if (child) {
         return child;
       }
 
-      // Walk down the subtree if allowed, otherwise check if we have reached
-      // a stop node.
+      // Walk down the subtree if allowed.
       if (!skipSubtree && childNode->IsElement()) {
         top = PushState(childNode, true);
       }
-      else if (childNode == aStopNode) {
-        return nullptr;
-      }
     }
     top = PopState();
   }
 
   // If we traversed the whole subtree of the anchor node. Move to next node
   // relative anchor node within the context subtree if asked.
   if (mFlags != eWalkContextTree) {
     // eWalkCache flag presence indicates that the search is scoped to the
     // anchor (no ARIA owns stuff).
     if (mFlags & eWalkCache) {
       mPhase = eAtEnd;
       return nullptr;
     }
-    return Next(aStopNode);
+    return Next();
   }
 
   nsINode* contextNode = mContext->GetNode();
   while (mAnchorNode != contextNode) {
     nsINode* parentNode = mAnchorNode->GetFlattenedTreeParent();
     if (!parentNode || !parentNode->IsElement())
       return nullptr;
 
     nsIContent* parent = parentNode->AsElement();
     top = PushState(parent, true);
     if (top->Seek(mAnchorNode)) {
       mAnchorNode = parent;
-      return Next(aStopNode);
+      return Next();
     }
 
     // XXX We really should never get here, it means we're trying to find an
     // accessible for a dom node where iterating over its parent's children
     // doesn't return it. However this sometimes happens when we're asked for
     // the nearest accessible to place holder content which we ignore.
     mAnchorNode = parent;
   }
 
-  return Next(aStopNode);
+  return Next();
 }
 
 Accessible*
 TreeWalker::Prev()
 {
   if (mStateStack.IsEmpty()) {
     if (mPhase == eAtStart || mPhase == eAtDOM) {
       mPhase = eAtStart;
--- a/accessible/base/TreeWalker.h
+++ b/accessible/base/TreeWalker.h
@@ -45,29 +45,44 @@ public:
    * @param aAnchorNode [in] the node the search will be prepared relative to
    * @param aFlags   [in] flags (see enum above)
    */
   TreeWalker(Accessible* aContext, nsIContent* aAnchorNode, uint32_t aFlags = eWalkCache);
 
   ~TreeWalker();
 
   /**
-   * Clears the tree walker state and resets it to the given child within
-   * the anchor.
+   * Resets the walker state, and sets the given node as an anchor. Returns a
+   * first accessible element within the node including the node itself.
+   */
+  Accessible* Scope(nsIContent* aAnchorNode);
+
+  /**
+   * Resets the walker state.
+   */
+  void Reset()
+  {
+    mPhase = eAtStart;
+    mStateStack.Clear();
+    mARIAOwnsIdx = 0;
+  }
+
+  /**
+   * Sets the walker state to the given child node if it's within the anchor.
    */
   bool Seek(nsIContent* aChildNode);
 
   /**
    * Return the next/prev accessible.
    *
    * @note Returned accessible is bound to the document, if the accessible is
    *       rejected during tree creation then the caller should be unbind it
    *       from the document.
    */
-  Accessible* Next(nsIContent* aStopNode = nullptr);
+  Accessible* Next();
   Accessible* Prev();
 
   Accessible* Context() const { return mContext; }
   DocAccessible* Document() const { return mDoc; }
 
 private:
   TreeWalker();
   TreeWalker(const TreeWalker&);
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -1701,17 +1701,17 @@ DocAccessible::UpdateRootElIfNeeded()
  * Content insertion helper.
  */
 class InsertIterator final
 {
 public:
   InsertIterator(Accessible* aContext,
                  const nsTArray<nsCOMPtr<nsIContent> >* aNodes) :
     mChild(nullptr), mChildBefore(nullptr), mWalker(aContext),
-    mStopNode(nullptr), mNodes(aNodes), mNodesIdx(0)
+    mNodes(aNodes), mNodesIdx(0)
   {
     MOZ_ASSERT(aContext, "No context");
     MOZ_ASSERT(aNodes, "No nodes to search for accessible elements");
     MOZ_COUNT_CTOR(InsertIterator);
   }
   ~InsertIterator() { MOZ_COUNT_DTOR(InsertIterator); }
 
   Accessible* Context() const { return mWalker.Context(); }
@@ -1729,27 +1729,26 @@ public:
     mChild = nullptr;
     mChildBefore = nullptr;
   }
 
 private:
   Accessible* mChild;
   Accessible* mChildBefore;
   TreeWalker mWalker;
-  nsIContent* mStopNode;
 
   const nsTArray<nsCOMPtr<nsIContent> >* mNodes;
   uint32_t mNodesIdx;
 };
 
 bool
 InsertIterator::Next()
 {
   if (mNodesIdx > 0) {
-    Accessible* nextChild = mWalker.Next(mStopNode);
+    Accessible* nextChild = mWalker.Next();
     if (nextChild) {
       mChildBefore = mChild;
       mChild = nextChild;
       return true;
     }
   }
 
   while (mNodesIdx < mNodes->Length()) {
@@ -1781,30 +1780,31 @@ InsertIterator::Next()
 
 #ifdef A11Y_LOG
     logging::TreeInfo("traversing an inserted node", logging::eVerbose,
                       "container", container, "node", node);
 #endif
 
     // If inserted nodes are siblings then just move the walker next.
     if (mChild && prevNode && prevNode->GetNextSibling() == node) {
-      mStopNode = node;
-      Accessible* nextChild = mWalker.Next(mStopNode);
+      Accessible* nextChild = mWalker.Scope(node);
       if (nextChild) {
         mChildBefore = mChild;
         mChild = nextChild;
         return true;
       }
     }
-    else if (mWalker.Seek(node)) {
-      mStopNode = node;
-      mChildBefore = mWalker.Prev();
-      mChild = mWalker.Next(mStopNode);
-      if (mChild) {
-        return true;
+    else {
+      TreeWalker finder(container);
+      if (finder.Seek(node)) {
+        mChild = mWalker.Scope(node);
+        if (mChild) {
+          mChildBefore = finder.Prev();
+          return true;
+        }
       }
     }
   }
 
   return false;
 }
 
 void