예제 #1
0
FocusManager::FocusDisposition
FocusManager::IsInOrContainsFocus(const Accessible* aAccessible) const
{
    Accessible* focus = FocusedAccessible();
    if (!focus)
        return eNone;

    // If focused.
    if (focus == aAccessible)
        return eFocused;

    // If contains the focus.
    Accessible* child = focus->Parent();
    while (child) {
        if (child == aAccessible)
            return eContainsFocus;

        child = child->Parent();
    }

    // If contained by focus.
    child = aAccessible->Parent();
    while (child) {
        if (child == focus)
            return eContainedByFocus;

        child = child->Parent();
    }

    return eNone;
}
예제 #2
0
bool
EventQueue::PushEvent(AccEvent* aEvent)
{
  NS_ASSERTION((aEvent->mAccessible && aEvent->mAccessible->IsApplication()) ||
               aEvent->GetDocAccessible() == mDocument,
               "Queued event belongs to another document!");

  if (!mEvents.AppendElement(aEvent))
    return false;

  // Filter events.
  CoalesceEvents();

  // Fire name change event on parent given that this event hasn't been
  // coalesced, the parent's name was calculated from its subtree, and the
  // subtree was changed.
  Accessible* target = aEvent->mAccessible;
  if (aEvent->mEventRule != AccEvent::eDoNotEmit &&
      target->HasNameDependentParent() &&
      (aEvent->mEventType == nsIAccessibleEvent::EVENT_NAME_CHANGE ||
       aEvent->mEventType == nsIAccessibleEvent::EVENT_TEXT_REMOVED ||
       aEvent->mEventType == nsIAccessibleEvent::EVENT_TEXT_INSERTED ||
       aEvent->mEventType == nsIAccessibleEvent::EVENT_SHOW ||
       aEvent->mEventType == nsIAccessibleEvent::EVENT_HIDE)) {
    // Only continue traversing up the tree if it's possible that the parent
    // accessible's name can depend on this accessible's name.
    Accessible* parent = target->Parent();
    while (parent &&
           nsTextEquivUtils::HasNameRule(parent, eNameFromSubtreeIfReqRule)) {
      // Test possible name dependent parent.
      if (nsTextEquivUtils::HasNameRule(parent, eNameFromSubtreeRule)) {
        nsAutoString name;
        ENameValueFlag nameFlag = parent->Name(name);
        // If name is obtained from subtree, fire name change event.
        if (nameFlag == eNameFromSubtree) {
          RefPtr<AccEvent> nameChangeEvent =
            new AccEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, parent);
          PushEvent(nameChangeEvent);
        }
        break;
      }
      parent = parent->Parent();
    }
  }

  // Associate text change with hide event if it wasn't stolen from hiding
  // siblings during coalescence.
  AccMutationEvent* showOrHideEvent = downcast_accEvent(aEvent);
  if (showOrHideEvent && !showOrHideEvent->mTextChangeEvent)
    CreateTextChangeEventFor(showOrHideEvent);

  return true;
}
예제 #3
0
Accessible*
XULMenupopupAccessible::ContainerWidget() const
{
  DocAccessible* document = Document();

  nsMenuPopupFrame* menuPopupFrame = do_QueryFrame(GetFrame());
  while (menuPopupFrame) {
    Accessible* menuPopup =
      document->GetAccessible(menuPopupFrame->GetContent());
    if (!menuPopup) // shouldn't be a real case
      return nullptr;

    nsMenuFrame* menuFrame = do_QueryFrame(menuPopupFrame->GetParent());
    if (!menuFrame) // context menu or popups
      return nullptr;

    nsMenuParent* menuParent = menuFrame->GetMenuParent();
    if (!menuParent) // menulist or menubutton
      return menuPopup->Parent();

    if (menuParent->IsMenuBar()) { // menubar menu
      nsMenuBarFrame* menuBarFrame = static_cast<nsMenuBarFrame*>(menuParent);
      return document->GetAccessible(menuBarFrame->GetContent());
    }

    // different kind of popups like panel or tooltip
    if (!menuParent->IsMenu())
      return nullptr;

    menuPopupFrame = static_cast<nsMenuPopupFrame*>(menuParent);
  }

  MOZ_ASSERT_UNREACHABLE("Shouldn't be a real case.");
  return nullptr;
}
예제 #4
0
Accessible*
nsAccessiblePivot::AdjustStartPosition(Accessible* aAccessible,
                                       RuleCache& aCache,
                                       uint16_t* aFilterResult,
                                       nsresult* aResult)
{
  Accessible* matched = aAccessible;
  *aResult = aCache.ApplyFilter(aAccessible, aFilterResult);

  if (aAccessible != mRoot && aAccessible != mModalRoot) {
    for (Accessible* temp = aAccessible->Parent();
         temp && temp != mRoot && temp != mModalRoot; temp = temp->Parent()) {
      uint16_t filtered = nsIAccessibleTraversalRule::FILTER_IGNORE;
      *aResult = aCache.ApplyFilter(temp, &filtered);
      NS_ENSURE_SUCCESS(*aResult, nullptr);
      if (filtered & nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE) {
        *aFilterResult = filtered;
        matched = temp;
      }
    }
  }

  if (aAccessible == mPosition && mStartOffset != -1 && mEndOffset != -1) {
    HyperTextAccessible* text = aAccessible->AsHyperText();
    if (text) {
      matched = text->GetChildAtOffset(mStartOffset);
    }
  }

  return matched;
}
예제 #5
0
Accessible* HTMLLabelIterator::Next() {
  // Get either <label for="[id]"> element which explicitly points to given
  // element, or <label> ancestor which implicitly point to it.
  Accessible* label = nullptr;
  while ((label = mRelIter.Next())) {
    if (IsLabel(label)) {
      return label;
    }
  }

  // Ignore ancestor label on not widget accessible.
  if (mLabelFilter == eSkipAncestorLabel || !mAcc->IsWidget()) return nullptr;

  // Go up tree to get a name of ancestor label if there is one (an ancestor
  // <label> implicitly points to us). Don't go up farther than form or
  // document.
  Accessible* walkUp = mAcc->Parent();
  while (walkUp && !walkUp->IsDoc()) {
    nsIContent* walkUpEl = walkUp->GetContent();
    if (IsLabel(walkUp) &&
        !walkUpEl->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::_for)) {
      mLabelFilter = eSkipAncestorLabel;  // prevent infinite loop
      return walkUp;
    }

    if (walkUpEl->IsHTMLElement(nsGkAtoms::form)) break;

    walkUp = walkUp->Parent();
  }

  return nullptr;
}
예제 #6
0
bool
EventQueue::PushNameChange(Accessible* aTarget)
{
  // Fire name change event on parent given that this event hasn't been
  // coalesced, the parent's name was calculated from its subtree, and the
  // subtree was changed.
  if (aTarget->HasNameDependentParent()) {
    // Only continue traversing up the tree if it's possible that the parent
    // accessible's name can depend on this accessible's name.
    Accessible* parent = aTarget->Parent();
    while (parent &&
           nsTextEquivUtils::HasNameRule(parent, eNameFromSubtreeIfReqRule)) {
      // Test possible name dependent parent.
      if (nsTextEquivUtils::HasNameRule(parent, eNameFromSubtreeRule)) {
        nsAutoString name;
        ENameValueFlag nameFlag = parent->Name(name);
        // If name is obtained from subtree, fire name change event.
        if (nameFlag == eNameFromSubtree) {
          RefPtr<AccEvent> nameChangeEvent =
            new AccEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, parent);
          return PushEvent(nameChangeEvent);
        }
        break;
      }
      parent = parent->Parent();
    }
  }
  return false;
}
예제 #7
0
STDMETHODIMP
ia2Accessible::get_accessibleWithCaret(IUnknown** aAccessible,
                                       long* aCaretOffset)
{
  if (!aAccessible || !aCaretOffset)
    return E_INVALIDARG;

  *aAccessible = nullptr;
  *aCaretOffset = -1;

  AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
  if (acc->IsDefunct())
    return CO_E_OBJNOTCONNECTED;

  int32_t caretOffset = -1;
  Accessible* accWithCaret = SelectionMgr()->AccessibleWithCaret(&caretOffset);
  if (!accWithCaret || acc->Document() != accWithCaret->Document())
    return S_FALSE;

  Accessible* child = accWithCaret;
  while (!child->IsDoc() && child != acc)
    child = child->Parent();

  if (child != acc)
    return S_FALSE;

  *aAccessible =  static_cast<IAccessible2*>(
    static_cast<AccessibleWrap*>(accWithCaret));
  (*aAccessible)->AddRef();
  *aCaretOffset = caretOffset;
  return S_OK;
}
예제 #8
0
void
LinkableAccessible::BindToParent(Accessible* aParent,
                                 uint32_t aIndexInParent)
{
    AccessibleWrap::BindToParent(aParent, aIndexInParent);

    // Cache action content.
    mActionAcc = nullptr;
    mIsLink = false;
    mIsOnclick = false;

    if (nsCoreUtils::HasClickListener(mContent)) {
        mIsOnclick = true;
        return;
    }

    // XXX: The logic looks broken since the click listener may be registered
    // on non accessible node in parent chain but this node is skipped when tree
    // is traversed.
    Accessible* walkUpAcc = this;
    while ((walkUpAcc = walkUpAcc->Parent()) && !walkUpAcc->IsDoc()) {
        if (walkUpAcc->LinkState() & states::LINKED) {
            mIsLink = true;
            mActionAcc = walkUpAcc;
            return;
        }

        if (nsCoreUtils::HasClickListener(walkUpAcc->GetContent())) {
            mActionAcc = walkUpAcc;
            mIsOnclick = true;
            return;
        }
    }
}
예제 #9
0
NS_IMETHODIMP
ARIAGridCellAccessible::GetRowIndex(int32_t* aRowIndex)
{
  NS_ENSURE_ARG_POINTER(aRowIndex);
  *aRowIndex = -1;

  if (IsDefunct())
    return NS_ERROR_FAILURE;

  Accessible* row = Parent();
  if (!row)
    return NS_OK;

  Accessible* table = row->Parent();
  if (!table)
    return NS_OK;

  *aRowIndex = 0;

  int32_t indexInTable = row->IndexInParent();
  for (int32_t idx = 0; idx < indexInTable; idx++) {
    row = table->GetChildAt(idx);
    if (row->Role() == roles::ROW)
      (*aRowIndex)++;
  }

  return NS_OK;
}
예제 #10
0
Accessible*
nsAccessiblePivot::SearchBackward(Accessible* aAccessible,
                                  nsIAccessibleTraversalRule* aRule,
                                  bool aSearchCurrent,
                                  nsresult* aResult)
{
  *aResult = NS_OK;

  // Initial position could be unset, in that case return null.
  if (!aAccessible)
    return nullptr;

  RuleCache cache(aRule);
  uint16_t filtered = nsIAccessibleTraversalRule::FILTER_IGNORE;
  Accessible* accessible = AdjustStartPosition(aAccessible, cache,
                                               &filtered, aResult);
  NS_ENSURE_SUCCESS(*aResult, nullptr);

  if (aSearchCurrent && (filtered & nsIAccessibleTraversalRule::FILTER_MATCH)) {
    return accessible;
  }

  Accessible* root = GetActiveRoot();
  while (accessible != root) {
    Accessible* parent = accessible->Parent();
    int32_t idxInParent = accessible->IndexInParent();
    while (idxInParent > 0) {
      if (!(accessible = parent->GetChildAt(--idxInParent)))
        continue;

      *aResult = cache.ApplyFilter(accessible, &filtered);
      NS_ENSURE_SUCCESS(*aResult, nullptr);

      Accessible* lastChild = nullptr;
      while (!(filtered & nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE) &&
             (lastChild = accessible->LastChild())) {
        parent = accessible;
        accessible = lastChild;
        idxInParent = accessible->IndexInParent();
        *aResult = cache.ApplyFilter(accessible, &filtered);
        NS_ENSURE_SUCCESS(*aResult, nullptr);
      }

      if (filtered & nsIAccessibleTraversalRule::FILTER_MATCH)
        return accessible;
    }

    if (!(accessible = parent))
      break;

    *aResult = cache.ApplyFilter(accessible, &filtered);
    NS_ENSURE_SUCCESS(*aResult, nullptr);

    if (filtered & nsIAccessibleTraversalRule::FILTER_MATCH)
      return accessible;
  }

  return nullptr;
}
Accessible*
HTMLSelectOptionAccessible::ContainerWidget() const
{
  Accessible* parent = Parent();
  if (parent && parent->IsHTMLOptGroup())
    parent = parent->Parent();

  return parent && parent->IsListControl() ? parent : nullptr;
}
예제 #12
0
Accessible*
nsAccessiblePivot::SearchForward(Accessible* aAccessible,
                                 nsIAccessibleTraversalRule* aRule,
                                 bool aSearchCurrent,
                                 nsresult* aResult)
{
  *aResult = NS_OK;

  // Initial position could be not set, in that case begin search from root.
  Accessible* root = GetActiveRoot();
  Accessible* accessible = (!aAccessible) ? root : aAccessible;

  RuleCache cache(aRule);

  uint16_t filtered = nsIAccessibleTraversalRule::FILTER_IGNORE;
  accessible = AdjustStartPosition(accessible, cache, &filtered, aResult);
  NS_ENSURE_SUCCESS(*aResult, nullptr);
  if (aSearchCurrent && (filtered & nsIAccessibleTraversalRule::FILTER_MATCH))
    return accessible;

  while (true) {
    Accessible* firstChild = nullptr;
    while (!(filtered & nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE) &&
           (firstChild = accessible->FirstChild())) {
      accessible = firstChild;
      *aResult = cache.ApplyFilter(accessible, &filtered);
      NS_ENSURE_SUCCESS(*aResult, nullptr);

      if (filtered & nsIAccessibleTraversalRule::FILTER_MATCH)
        return accessible;
    }

    Accessible* sibling = nullptr;
    Accessible* temp = accessible;
    do {
      if (temp == root)
        break;

      sibling = temp->NextSibling();

      if (sibling)
        break;
    } while ((temp = temp->Parent()));

    if (!sibling)
      break;

    accessible = sibling;
    *aResult = cache.ApplyFilter(accessible, &filtered);
    NS_ENSURE_SUCCESS(*aResult, nullptr);

    if (filtered & nsIAccessibleTraversalRule::FILTER_MATCH)
      return accessible;
  }

  return nullptr;
}
Accessible*
ApplicationAccessible::FocusedChild()
{
  Accessible* focus = FocusMgr()->FocusedAccessible();
  if (focus && focus->Parent() == this)
    return focus;

  return nullptr;
}
예제 #14
0
nsresult
ARIAGridCellAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
{
  if (IsDefunct())
    return NS_ERROR_FAILURE;
  
  nsresult rv = HyperTextAccessibleWrap::GetAttributesInternal(aAttributes);
  NS_ENSURE_SUCCESS(rv, rv);

  // Expose "table-cell-index" attribute.

  Accessible* thisRow = Parent();
  if (!thisRow || thisRow->Role() != roles::ROW)
    return NS_OK;

  int32_t colIdx = 0, colCount = 0;
  uint32_t childCount = thisRow->ChildCount();
  for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
    Accessible* child = thisRow->GetChildAt(childIdx);
    if (child == this)
      colIdx = colCount;

    roles::Role role = child->Role();
    if (role == roles::GRID_CELL || role == roles::ROWHEADER ||
        role == roles::COLUMNHEADER)
      colCount++;
  }

  Accessible* table = thisRow->Parent();
  if (!table)
    return NS_OK;

  roles::Role tableRole = table->Role();
  if (tableRole != roles::TABLE && tableRole != roles::TREE_TABLE)
    return NS_OK;

  int32_t rowIdx = 0;
  childCount = table->ChildCount();
  for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
    Accessible* child = table->GetChildAt(childIdx);
    if (child == thisRow)
      break;

    if (child->Role() == roles::ROW)
      rowIdx++;
  }

  int32_t idx = rowIdx * colCount + colIdx;

  nsAutoString stringIdx;
  stringIdx.AppendInt(idx);
  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::tableCellIndex,
                         stringIdx);

  return NS_OK;
}
예제 #15
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;
}
예제 #16
0
TableAccessible*
HTMLTableCellAccessible::Table() const
{
  Accessible* parent = const_cast<HTMLTableCellAccessible*>(this);
  while ((parent = parent->Parent())) {
    if (parent->IsTable())
      return parent->AsTable();
  }

  return nullptr;
}
Accessible*
XULColorPickerTileAccessible::ContainerWidget() const
{
  Accessible* parent = Parent();
  if (parent) {
    Accessible* grandParent = parent->Parent();
    if (grandParent && grandParent->IsMenuButton())
      return grandParent;
  }
  return nullptr;
}
TableAccessible*
HTMLTableCellAccessible::Table() const
{
  Accessible* parent = const_cast<HTMLTableCellAccessible*>(this);
  while ((parent = parent->Parent())) {
    roles::Role role = parent->Role();
    if (role == roles::TABLE || role == roles::TREE_TABLE)
      return parent->AsTable();
  }

  return nullptr;
}
예제 #19
0
bool
FocusManager::IsFocusWithin(const Accessible* aContainer) const
{
    Accessible* child = FocusedAccessible();
    while (child) {
        if (child == aContainer)
            return true;

        child = child->Parent();
    }
    return false;
}
예제 #20
0
TableAccessible*
XULListCellAccessible::Table() const
{
  Accessible* thisRow = Parent();
  if (!thisRow || thisRow->Role() != roles::ROW)
    return nullptr;

  Accessible* table = thisRow->Parent();
  if (!table || table->Role() != roles::TABLE)
    return nullptr;

  return table->AsTable();
}
static const gchar*
getKeyBindingCB(AtkAction *aAction, gint aActionIndex)
{
  AccessibleWrap* acc = GetAccessibleWrap(ATK_OBJECT(aAction));
  if (!acc)
    return nullptr;

  // Return all key bindings including access key and keyboard shortcut.
  nsAutoString keyBindingsStr;

  // Get access key.
  KeyBinding keyBinding = acc->AccessKey();
  if (!keyBinding.IsEmpty()) {
    keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);

    Accessible* parent = acc->Parent();
    roles::Role role = parent ? parent->Role() : roles::NOTHING;
    if (role == roles::PARENT_MENUITEM || role == roles::MENUITEM ||
        role == roles::RADIO_MENU_ITEM || role == roles::CHECK_MENU_ITEM) {
      // It is submenu, expose keyboard shortcuts from menu hierarchy like
      // "s;<Alt>f:s"
      nsAutoString keysInHierarchyStr = keyBindingsStr;
      do {
        KeyBinding parentKeyBinding = parent->AccessKey();
        if (!parentKeyBinding.IsEmpty()) {
          nsAutoString str;
          parentKeyBinding.ToString(str, KeyBinding::eAtkFormat);
          str.Append(':');

          keysInHierarchyStr.Insert(str, 0);
        }
      } while ((parent = parent->Parent()) && parent->Role() != roles::MENUBAR);

      keyBindingsStr.Append(';');
      keyBindingsStr.Append(keysInHierarchyStr);
    }
  } else {
    // No access key, add ';' to point this.
    keyBindingsStr.Append(';');
  }

  // Get keyboard shortcut.
  keyBindingsStr.Append(';');
  keyBinding = acc->KeyboardShortcut();
  if (!keyBinding.IsEmpty()) {
    keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
  }

  return AccessibleWrap::ReturnString(keyBindingsStr);
}
예제 #22
0
Accessible*
nsAccUtils::GetAncestorWithRole(Accessible* aDescendant, uint32_t aRole)
{
  Accessible* document = aDescendant->Document();
  Accessible* parent = aDescendant;
  while ((parent = parent->Parent())) {
    uint32_t testRole = parent->Role();
    if (testRole == aRole)
      return parent;

    if (parent == document)
      break;
  }
  return nullptr;
}
예제 #23
0
bool
nsAccessiblePivot::IsDescendantOf(Accessible* aAccessible, Accessible* aAncestor)
{
  if (!aAncestor || aAncestor->IsDefunct())
    return false;

  // XXX Optimize with IsInDocument() when appropriate. Blocked by bug 759875.
  Accessible* accessible = aAccessible;
  do {
    if (accessible == aAncestor)
      return true;
  } while ((accessible = accessible->Parent()));

  return false;
}
already_AddRefed<nsIAccessibleTable>
nsHTMLTableCellAccessible::GetTableAccessible()
{
  Accessible* parent = this;
  while ((parent = parent->Parent())) {
    roles::Role role = parent->Role();
    if (role == roles::TABLE || role == roles::TREE_TABLE) {
      nsIAccessibleTable* tableAcc = nsnull;
      CallQueryInterface(parent, &tableAcc);
      return tableAcc;
    }
  }

  return nsnull;
}
예제 #25
0
void
TextRange::Text(nsAString& aText) const
{
  Accessible* current = mStartContainer->GetChildAtOffset(mStartOffset);
  uint32_t startIntlOffset =
    mStartOffset - mStartContainer->GetChildOffset(current);

  while (current && TextInternal(aText, current, startIntlOffset)) {
    current = current->Parent();
    if (!current)
      break;

    current = current->NextSibling();
  }
}
예제 #26
0
Accessible*
nsAccUtils::GetSelectableContainer(Accessible* aAccessible, uint64_t aState)
{
  if (!aAccessible)
    return nullptr;

  if (!(aState & states::SELECTABLE))
    return nullptr;

  Accessible* parent = aAccessible;
  while ((parent = parent->Parent()) && !parent->IsSelect()) {
    if (parent->Role() == roles::PANE)
      return nullptr;
  }
  return parent;
}
예제 #27
0
NS_IMETHODIMP
nsAccessiblePivot::MoveToPoint(nsIAccessibleTraversalRule* aRule,
                               int32_t aX, int32_t aY, bool aIgnoreNoMatch,
                               bool aIsFromUserInput, uint8_t aArgc,
                               bool* aResult)
{
  NS_ENSURE_ARG_POINTER(aResult);
  NS_ENSURE_ARG_POINTER(aRule);

  *aResult = false;

  Accessible* root = GetActiveRoot();
  NS_ENSURE_TRUE(root && !root->IsDefunct(), NS_ERROR_NOT_IN_TREE);

  RuleCache cache(aRule);
  Accessible* match = nullptr;
  Accessible* child = root->ChildAtPoint(aX, aY, Accessible::eDeepestChild);
  while (child && root != child) {
    uint16_t filtered = nsIAccessibleTraversalRule::FILTER_IGNORE;
    nsresult rv = cache.ApplyFilter(child, &filtered);
    NS_ENSURE_SUCCESS(rv, rv);

    // Ignore any matching nodes that were below this one
    if (filtered & nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE)
      match = nullptr;

    // Match if no node below this is a match
    if ((filtered & nsIAccessibleTraversalRule::FILTER_MATCH) && !match) {
      int32_t childX, childY, childWidth, childHeight;
      child->GetBounds(&childX, &childY, &childWidth, &childHeight);
      // Double-check child's bounds since the deepest child may have been out
      // of bounds. This assures we don't return a false positive.
      if (aX >= childX && aX < childX + childWidth &&
          aY >= childY && aY < childY + childHeight)
        match = child;
    }

    child = child->Parent();
  }

  if (match || !aIgnoreNoMatch)
    *aResult = MovePivotInternal(match, nsIAccessiblePivot::REASON_POINT,
                                 (aArgc > 0) ? aIsFromUserInput : true);

  return NS_OK;
}
NS_IMETHODIMP
nsXULListCellAccessible::GetTable(nsIAccessibleTable **aTable)
{
  NS_ENSURE_ARG_POINTER(aTable);
  *aTable = nsnull;

  if (IsDefunct())
    return NS_ERROR_FAILURE;

  Accessible* thisRow = Parent();
  if (!thisRow || thisRow->Role() != roles::ROW)
    return NS_OK;

  Accessible* table = thisRow->Parent();
  if (!table || table->Role() != roles::TABLE)
    return NS_OK;

  CallQueryInterface(table, aTable);
  return NS_OK;
}
예제 #29
0
Accessible*
nsAccUtils::TableFor(Accessible* aRow)
{
  if (aRow) {
    Accessible* table = aRow->Parent();
    if (table) {
      roles::Role tableRole = table->Role();
      if (tableRole == roles::GROUPING) { // if there's a rowgroup.
        table = table->Parent();
        if (table)
          tableRole = table->Role();
      }

      return (tableRole == roles::TABLE || tableRole == roles::TREE_TABLE ||
              tableRole == roles::MATHML_TABLE) ? table : nullptr;
    }
  }

  return nullptr;
}
예제 #30
0
uint32_t
XULListCellAccessible::RowIdx() const
{
  Accessible* row = Parent();
  if (!row)
    return 0;

  Accessible* table = row->Parent();
  if (!table)
    return 0;

  int32_t indexInTable = row->IndexInParent();
  uint32_t rowIdx = 0;
  for (int32_t idx = 0; idx < indexInTable; idx++) {
    row = table->GetChildAt(idx);
    if (row->Role() == roles::ROW)
      rowIdx++;
  }

  return rowIdx;
}