Example #1
0
Accessible*
TreeWalker::AccessibleFor(nsIContent* aNode, uint32_t aFlags, bool* aSkipSubtree)
{
  // Ignore the accessible and its subtree if it was repositioned by means
  // of aria-owns.
  Accessible* child = mDoc->GetAccessible(aNode);
  if (child) {
    if (child->IsRelocated()) {
      *aSkipSubtree = true;
      return nullptr;
    }
    return child;
  }

  // Create an accessible if allowed.
  if (!(aFlags & eWalkCache) && mContext->IsAcceptableChild(aNode)) {
    // We may have ARIA owned element in the dependent attributes map, but the
    // element may be not allowed for this ARIA owns relation, if the relation
    // crosses out XBL anonymous content boundaries. In this case we won't
    // create an accessible object for it, when aria-owns is processed, which
    // may make the element subtree inaccessible. To avoid that let's create
    // an accessible object now, and later, if allowed, move it in the tree,
    // when aria-owns relation is processed.
    if (mDoc->RelocateARIAOwnedIfNeeded(aNode) && !aNode->IsXULElement()) {
      *aSkipSubtree = true;
      return nullptr;
    }
    return GetAccService()->CreateAccessible(aNode, mContext, aSkipSubtree);
  }

  return nullptr;
}
Example #2
0
bool
TreeWalker::Seek(nsIContent* aChildNode)
{
  MOZ_ASSERT(aChildNode, "Child cannot be null");

  Reset();

  if (mAnchorNode == aChildNode) {
    return true;
  }

  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();

    if (!parentNode || !parentNode->IsElement()) {
      return false;
    }

    // If ARIA owned child.
    Accessible* child = mDoc->GetAccessible(childNode);
    if (child && child->IsRelocated()) {
      MOZ_ASSERT(!(mFlags & eScoped),
        "Walker should not be scoped when seeking into relocated children");
      if (child->Parent() != mContext) {
        return false;
      }

      Accessible* ownedChild = nullptr;
      while ((ownedChild = mDoc->ARIAOwnedAt(mContext, mARIAOwnsIdx++)) &&
             ownedChild != child);

      MOZ_ASSERT(ownedChild, "A child has to be in ARIA owned elements");
      mPhase = eAtARIAOwns;
      return true;
    }

    // Look in DOM.
    dom::AllChildrenIterator* iter = PrependState(parentNode->AsElement(), true);
    if (!iter->Seek(childNode)) {
      return false;
    }

    if (parentNode == mAnchorNode) {
      mPhase = eAtDOM;
      return true;
    }
  } while (true);

  return false;
}
Example #3
0
Accessible*
TreeWalker::AccessibleFor(nsIContent* aNode, uint32_t aFlags, bool* aSkipSubtree)
{
  Accessible* child = nullptr;
  if (aFlags & eWalkCache) {
    child = mDoc->GetAccessible(aNode);
  }
  else if (mContext->IsAcceptableChild(aNode)) {
    child = GetAccService()->
      GetOrCreateAccessible(aNode, mContext, aSkipSubtree);
  }

  // Ignore the accessible and its subtree if it was repositioned by means
  // of aria-owns.
  if (child && child->IsRelocated()) {
    *aSkipSubtree = true;
    return nullptr;
  }

  return child;
}
Example #4
0
nsIContent*
TreeWalker::Next(ChildrenIterator* aIter, Accessible** aAccesible,
                 bool* aSkipSubtree)
{
  nsIContent* childEl = aIter->mDOMIter.GetNextChild();
  if (!aAccesible)
    return childEl;

  *aAccesible = nullptr;
  *aSkipSubtree = false;

  if (childEl) {
    Accessible* accessible = mFlags & eWalkCache ?
      mDoc->GetAccessible(childEl) :
      GetAccService()->GetOrCreateAccessible(childEl, mContext, aSkipSubtree);

    // Ignore the accessible and its subtree if it was repositioned by means of
    // aria-owns.
    if (accessible) {
      if (accessible->IsRelocated()) {
        *aSkipSubtree = true;
      } else {
        *aAccesible = accessible;
      }
    }
    return childEl;
  }

  // At last iterate over ARIA owned children.
  Accessible* parent = mDoc->GetAccessible(aIter->mDOMIter.Parent());
  if (parent) {
    Accessible* child = mDoc->ARIAOwnedAt(parent, aIter->mARIAOwnsIdx++);
    if (child) {
      *aAccesible = child;
      return child->GetContent();
    }
  }
  return nullptr;
}