Aaron, a while ago we were talking about how in ff3 MSAA/IA2's event_reorder
on a parent object was removed in favour of event_show on the actual object,
when an object was added to the tree of IAccessibles.
NVDA has usually used event_reorder in its virtual buffers in order to
remove all descendants of the object the event_reorder was for, and
re-render the descendants.
We both agreed that this was very costly as you could have a parent with
many many children, but in reality, only one of them changed.
For NVDA to use event_show with minimal changes to its code, it would get
the parent of the object that event_show was for, and again, remove all its
descendants, and re-render them. But of course this is exactly the same as
event_reorder, what we really should do is get the object that event_show
was for, and investigate its previous or next or parent object's (what ever
was valid first) and then insert the object in to the virtual buffer
relative to the previous/next/parent.
This approach works ok when text of an object is represented as a textNode
(child object), but when the text of an object is represented with
IAccessibleText, with child objects as imbedded object chars with in that
text, this approach no longer works.
The reason for this is that when adding an object to the virtual buffer, it
becomes ambiguous as to where exactly the object should go, in regards to
surrounding text from the parent object.
For example the following html code:
<p>Click here to visit the <a href="community.html">Community page</a> and
check out our email lists</p>
Pretend for a second that that link didn't exist at all, but then some
script suddenly added it, we'd get an event_show for the link, it would have
no previous object, it would have no next object, but it would have a parent
object. But the question is, where do we insert it in regards to the parent
object? before the parent object's text, or after? the answer is in fact
right in the middle.
So the only safest thing to do is remove all the text and descendance of the
paragraph and re-render text and descendance.
That example is slightly wrong as currently in ff3, there are still
textNodes. So that link would have a previous object of a text node, and a
next object of a textNode. However, they are useless to us for positioning
as we didn't use these textNodes originally when rendering the text, we used
IAccessibleText of the parent.
To solve the problem, NVDA could just continue to use textNodes, and not use
IAccessibleText at all, though I assume that textNodes are going to be
removed in the future. Or, we could just continue to take the old approach
and remove all descendance of a parent and re-render.
I guess another approach would be to scan the parent's text for imbeded
objects, and locate eactly where this object is supposed to be by looking up
all the objects for the embeded object chars until we find the object in
question. Though I think that that would be way more costly.
So, this is my current problem I'm pondering over. Do you or anyone else
have any ideas on how I could still efficiently use event_show? or is the
only option to either use the textNodes, or re-render all descendants?
When the parent of the shown/hidden object support IAccessibleText, we
also fire a EVENT_TEXT_INSERTED or EVENT_TEXT_REMOVED to go along with
it. The inserted or removed text will just be a single embedded object
char for the node which is changing.