Commit 72a5e88c authored by Alexander Surkov's avatar Alexander Surkov
Browse files

Bug 1274381 - scope accessible elements search to inserted nodes, r=yzen, f=marcoz

parent 4f6e8a25
Loading
Loading
Loading
Loading
+23 −16
Original line number Diff line number Diff line
@@ -57,14 +57,29 @@ 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;
@@ -110,7 +125,7 @@ TreeWalker::Seek(nsIContent* aChildNode)
}

Accessible*
TreeWalker::Next(nsIContent* aStopNode)
TreeWalker::Next()
{
  if (mStateStack.IsEmpty()) {
    if (mPhase == eAtEnd) {
@@ -139,10 +154,6 @@ TreeWalker::Next(nsIContent* aStopNode)

  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);
@@ -150,14 +161,10 @@ TreeWalker::Next(nsIContent* aStopNode)
        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();
  }
@@ -171,7 +178,7 @@ TreeWalker::Next(nsIContent* aStopNode)
      mPhase = eAtEnd;
      return nullptr;
    }
    return Next(aStopNode);
    return Next();
  }

  nsINode* contextNode = mContext->GetNode();
@@ -184,7 +191,7 @@ TreeWalker::Next(nsIContent* aStopNode)
    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
@@ -194,7 +201,7 @@ TreeWalker::Next(nsIContent* aStopNode)
    mAnchorNode = parent;
  }

  return Next(aStopNode);
  return Next();
}

Accessible*
+18 −3
Original line number Diff line number Diff line
@@ -50,8 +50,23 @@ public:
  ~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);

@@ -62,7 +77,7 @@ public:
   *       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; }
+11 −11
Original line number Diff line number Diff line
@@ -1684,7 +1684,7 @@ 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");
@@ -1712,7 +1712,6 @@ private:
  Accessible* mChild;
  Accessible* mChildBefore;
  TreeWalker mWalker;
  nsIContent* mStopNode;

  const nsTArray<nsCOMPtr<nsIContent> >* mNodes;
  uint32_t mNodesIdx;
@@ -1722,7 +1721,7 @@ bool
InsertIterator::Next()
{
  if (mNodesIdx > 0) {
    Accessible* nextChild = mWalker.Next(mStopNode);
    Accessible* nextChild = mWalker.Next();
    if (nextChild) {
      mChildBefore = mChild;
      mChild = nextChild;
@@ -1764,23 +1763,24 @@ InsertIterator::Next()

    // If inserted nodes are siblings then just move the walker next.
    if (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);
    else {
      TreeWalker finder(container);
      if (finder.Seek(node)) {
        mChild = mWalker.Scope(node);
        if (mChild) {
          mChildBefore = finder.Prev();
          return true;
        }
      }
    }
  }

  return false;
}