Closed Bug 390692 (livereal) Opened 14 years ago Closed 14 years ago

Provide useful information with live region change events


(Core :: Disability Access APIs, defect)

Not set





(Reporter: aaronlev, Assigned: aaronlev)


(Blocks 1 open bug, )


(Keywords: access, Whiteboard: This delivers the final needed polish for ARIA live regions, a very important piece of Firefox 3 accessibility)


(3 files, 3 obsolete files)

Right now when a node changes the AT must walk the parent chain and check the object attributes of each node to see if there is any live region markup.

I propose that the most recently changed node should set the relation member_of to the the first live region ancestor, which is defined as the first ancestor with a live region property (live/atomic/relevant/channel) set on it.

That way when a change occurs, the AT can check for member_of. If member_of is not set and the AT is not echoing changes without ARIA attributes, it can stop there. If member_of is present the AT can start at the member_of object and move up the tree from there collecting attributes.
We may also choose to provide the other ARIA attributes directly on the last changed node, via object attributes such as:
last-change-politeness, last-change-atomic, last-change-channel, last-change-relevant.

However, I'm not sure if this is necessary. Thoughts?
I need to figure out a good testing strategy for this.
Live regions report children-changed or text-changed events upon updates.  Here is a survey of some of the live region test cases we use.

I am seeing the events for the following:

but not these: (except for score, not stats) 
All the live region examples at are not exposing 'live' object attributes.
Regarding  the UIUC examples:
That's a bug in their examples. It's a text/html page and they're trying to use namespaced attributes directly in the markup.
All the clcworld examples work for me:
This one works for me, it just starts with live="off", so I see live:off as an object attribute. 
I noticed that this one marks the live property on the table rows, which are the parent of the table cells. A surprise, but nonetheless it's there. 
This one definitely works for me.
Attached patch Patch described in comment (obsolete) — Splinter Review
This patch ensures that we provide useful information for mutation events fired in accessibility APIs.

1. Split into nsIAccessibleEvent types into 6 kinds:

               Show             Hide              Significant change


The DOM names were changed to CREATE/DESTROY because that more accurately reflects what's happening in the DOM. DOM events are synchronous, which is important because we can find out whether user input started the event. This is an important factor in determining whether a screen reader should announce the change.

The notifications that come in from layout are always asynchronous, which means we need to find out whether user input caused it from a previous DOM event which caches that state.

Significant change events occur when the content or properties of an object have changed. In that case we will fire both a HIDE and then a SHOW event in the APIs.

2. In MSAA we no longer fire EVENT_REORDER. It's been removed completely. I checked with the AT vendors and there is no problem with this. They can get the same info from SHOW/HIDE.

3. Object attributes were empty for hidden objects of some types -- I fixed the incorrect early return.

4. Provide the following new object attributes for the last event object:
event-from-input: [true or false]
container-relevant, container-busy, container-atomic, container-live, container-channel which are the same as the non-container attributes, except that Mozilla does the work of navigating the parent chain to find the closest container with that info and exposes it on the node that's being shown or hidden.
5. If it's atomic, provide the member-of relation pointing to the container with atomic="true"
6. The rest of the changes are basically to get the results of IsHandlingUserInput() at the right time and keep them around so they can be retreived when the event is fired and the AT asks for the object attributes of that event
Attachment #275671 - Flags: review?(surkov.alexander)
BTW, I did a lot of testing to make sure the events we fire provide the correct information about whether or not they're caused by user input. However, any suggestions for improvements in keeping the info (instead of a global) would be appreciated. We may want to do a circular array instead, or try to find a way to pass it through event data in ATK. In MSAA it's not as much of an issue because the screen readers tend to get the events in process (synchronously).

We can also file follow-up bugs so we can get this in now and have AT developers start to work with it. That way we can improve it in parallel.
Code style:

     else {
-      event = nsIAccessibleEvent::EVENT_SHOW;
-    }
+      event = nsIAccessibleEvent::EVENT_ASYNCH_SHOW;    }
Attachment #275671 - Flags: review?(ginn.chen)
I concur with comment #6.
+        NS_ASSERTION(type == nsIAccessibleEvent::EVENT_ASYNCH_SHOW ||
+                     type == nsIAccessibleEvent::EVENT_ASYNCH_HIDE,
+                     type == nsIAccessibleEvent::EVENT_DOM_CREATE,
+                     type == nsIAccessibleEvent::EVENT_DOM_DESTROY,
replace first two "," to "||"

+  aAttributes->SetStringProperty(NS_LITERAL_CSTRING("event-from-input"),
+                                 gLastEventFromUserInput ? NS_LITERAL_STRING("true") :
+                                                            NS_LITERAL_STRING("false"),
wrong indent

+void nsAccEvent::CaptureIsFromUserInput(PRBool aIsAsynch)
+  nsCOMPtr<nsIDOMNode> eventNode;
+  GetDOMNode(getter_AddRefs(eventNode));
+  if (!eventNode) {
+    NS_NOTREACHED("There should always be a DOM node for an event");
+    return;
+  }
+  gLastEventNodeWeak = eventNode;
+  mIsFromUserInput = gLastEventFromUserInput;
+  if (aIsAsynch) {
+    return; // Cannot calculate, so use previous value
+  }
+  PrepareForEvent(eventNode);
+  mIsFromUserInput = gLastEventFromUserInput;

I think it will look better, if we move
+  gLastEventNodeWeak = eventNode;
+  mIsFromUserInput = gLastEventFromUserInput;
+  if (aIsAsynch) {

Does it work?

+  nsCOMPtr<nsIDOMDocument> domDoc;
+  aEventNode->GetOwnerDocument(getter_AddRefs(domDoc));
+  nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
+  if (!doc) {
+    NS_NOTREACHED("There should always be a document for an event");
+    return;
+  }
the assert will fail if we're firing activate or focus event for nsRootAcc or nsDocAcc

+  static void GetLastEventAttributes(nsIDOMNode *aNode,
+                                      nsIPersistentProperties *aAttributes);
wrong indent

+  static nsIDOMNode* nsAccEvent::GetLastEventAtomicRegion(nsIDOMNode *aNode);
should be
+  static nsIDOMNode* GetLastEventAtomicRegion(nsIDOMNode *aNode);

+   * called from the synchronous code which is the true source ofe event,
+   * before the event is fired.
+   */

Should we update the iid?

I got assertion for every second when using the test case.

528       NS_ASSERTION(!SameCOMIdentity(parentContent, mDOMNode), "Cannot find child for DOMPointToHypertextOffset search");

Do we have a bug to address that?

I agree to get this in first and solve follow-up bugs in parallel.
Attachment #275671 - Flags: review?(ginn.chen) → review+
Changing name to more accurately reflect what the bug is about.
Alias: livereal
Summary: Make live regions less expensive to deal with → Provide useful information with live region change events
Attached patch Address Ginn's comments (obsolete) — Splinter Review
Roc, I need review for the very minor changes in content and layout.

Ginn, the assertion caught a bug, which was a regression that occured from making all nsHyperTextAccessible's support nsIAccessibleText, even if they don't have children. DOMPointToHypertextOffset() didn't know what to do when there are no children. That's fixed in this new patch. Thanks for noticing the assertion.
Attachment #275177 - Attachment is obsolete: true
Attachment #275671 - Attachment is obsolete: true
Attachment #275965 - Flags: superreview?(roc)
Attachment #275671 - Flags: review?(surkov.alexander)
As mentioned in comment 6 there are more testcases at
Those are useful for checking the "container-*" attributes and member_of relation we're exposing (basically the computed info for atomic, live, relevant, busy and channel).
Flags: blocking1.9?
Whiteboard: This delivers the final needed polish for ARIA live regions, a very important piece of Firefox 3 accessibility
Attachment #275965 - Attachment is obsolete: true
Attachment #276001 - Flags: superreview?(roc)
Attachment #275965 - Flags: superreview?(roc)
Comment on attachment 276001 [details] [diff] [review]
Forgot to include nsHyperTextAccessible.cpp in last patch

+  NS_IMETHOD_(PRBool) IsHandlingUserInputExternal() = 0;

Document what this means?
Attachment #276001 - Flags: superreview?(roc) → superreview+
Aaron, please comment new methods.
Comment on attachment 276001 [details] [diff] [review]
Forgot to include nsHyperTextAccessible.cpp in last patch

Drivers: this delivers the final needed polish for ARIA live regions, a very important piece of Firefox 3 accessibility. It also fixes several bugs with our text change events.

I will comment all the new methods.
Attachment #276001 - Flags: approval1.9?
Blocks: 391723
Closed: 14 years ago
Resolution: --- → FIXED
Depends on: 392130
You need to log in before you can comment on or make changes to this bug.