Open Bug 1009143 Opened 10 years ago Updated 2 years ago

Add option to match containers in pivot API

Categories

(Core :: Disability Access APIs, defect)

defect

Tracking

()

People

(Reporter: eeejay, Unassigned)

Details

There are currently 2 use cases in AccessFu that make our traversal rules complex. And defeat the purpose of having role-based traversal in the way we designed the pivot API.

I think we could provide features in the pivot API to answer each:

1. We want to land on the biggest touch target possible. For example, instead of moving to a text leaf during explore by touch, it would be good to land on its containing table cell. This should work only if there is a single child hierarchy between the table cell and the text leaf. If there are other children in the cell, like a collection of links, then don't land on the parent cell.

2. If there is a container that only contains text leafs move to the section, and not to each child individually. The best example for this is a paragraph with several formatting changes in its text. The entire paragraph should be read as one piece.

So my proposal:
interface nsIAccessibleTraversalRule : nsISupports {
...
  /* Prematch a container with a single child lineage to a descendant that prematches too */
  const unsigned long PREMATCH_CONTAINER_SIMPLE_DESCENDANTS  = 0x00000001;
  /* Prematch a container with text children regardless of its role. */
  const unsigned long PREMATCH_CONTAINER_TEXT_CHILDREN  = 0x00000002;

  readonly attribute unsigned long containerPreMatchFlags;

  unsigned short match(in nsIAccessible aAccessible, in nsIAccessible aDecendant);
};

The match algorithm would look something like this (in pseudo JS, but will be implemented in native):

function isTextParent(aAccessible) {
  if (aAccessible.childCount > 0)
    return false;

  for (var child = aAccessible.firstChild; child; child = nextSibling) {
    if (child.role != TEXT_LEAF || child.role != STATIC_TEXT)
      return false;
  }

  return true;
}

function filterMatches(aRule, aAccessible) {
  var matchTextContainers = aRule.containerPreMatchFlags & PREMATCH_CONTAINER_TEXT_CHILDREN;
  if (!aRule.matchRoles.contains(aAccessible.role) &&
      (matchTextContainers && !isTextParent(aAccessible))
    return false;
  }

  if (aAccessible fails prefilter tests) {
    return false;
  }

  return true;
}

function applyRule(aRule, aAccessible) {
  if (filterMatches(aAccessible)) {
    return aRule.match(aAccessible);
  }

  if (aRule.containerPreMatchFlags & PREMATCH_CONTAINER_SIMPLE_DESCENDANTS) {
    for (var child = aAccessible; child.childCount == 1;) {
      child = child.firstChild;
      if (filterMatches(aRule, child)) {
        return aRule.match(aAccessible, child);
      }
    }
  }

  return FILTER_IGNORE;
}
What's difference between 1 and 2? Do you have 3d option? If no then you can consider to make the wanted behavior by default.
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.