We have RemoteAccessible::mParent and RemoteAccessible::mDoc, so DocAccessibleParent::mParentDoc was redundant.
Aside from the redundancy, this was one extra thing we needed to keep up to date and reason about.
This involved changing the call to RemoveChildDoc in Destroy to use Unbind instead because Unbind clears the parent RemoteAccessible, but RemoveChildDoc didn't.
That meant we had a dangling RemoteAccessible::mParent pointer, which was always a problem, but is more problematic now that we no longer have mParentDoc and the destructor checks the parent document.
Since Unbind is the only caller of RemoveChildDoc, RemoveChildDoc has been merged into Unbind.
This means there is now only a single place where child documents are unbound from their parent, which should make things easier to reason about.
Differential Revision: https://phabricator.services.mozilla.com/D218802
While an id was slightly safer, it also required a hash lookup every time we retrieved a parent.
This got expensive when there was a lot of tree walking, particularly given that we walk ancestors in some cases and we have to get the parent for NextSibling and PrevSibling.
Instead, mParent is now a RemoteAccessible pointer.
mChildren is already raw pointers (even when crossing documents) and we haven't encountered problems there recently, so I don't anticipate safety problems here.
Differential Revision: https://phabricator.services.mozilla.com/D218801
In bug 1779578, I changed the way a11y trees are serialised such that the parent id is included for each Accessible.
When de-serialising in DocAccessibleParent::RecvShowEvent, in order to avoid a theoretical performance regression caused by repeatedly looking up the same parent, I added an optimisation to use the last parent if it is the same as the current parent.
Unfortunately, it seems I never actually set the lastParent and lastParentID variables, so this optimisation was a no-op!
This is a micro-optimisation: it doesn't seem to make any observable difference.
However, it seems silly to have effectively dead code and it's a very straightforward fix.
Differential Revision: https://phabricator.services.mozilla.com/D213177
This is needed in order to support find in page on Android using remote caret events instead of virtual cursor change events.
Depends on D192641
Differential Revision: https://phabricator.services.mozilla.com/D192642
This is needed in order to support find in page on Android using remote caret events instead of virtual cursor change events.
Depends on D192641
Differential Revision: https://phabricator.services.mozilla.com/D192642
This is what we did before the fix for bug 1779578.
Failure to do this meant that RemoteAccessible::IsLink() returned false even for a child of a HyperText Accessible, which meant the ATK object was created without the HyperLink interface.
This change requires that we move the handling of pending OOP child docs, since we can't add a child document until ProxyCreated has been called on the OuterDoc.
Differential Revision: https://phabricator.services.mozilla.com/D186423
This was done with the following Python script:
```
import re
cacheConsts = open("accessible/base/CacheConstants.h", "rt").read()
aliases = {
alias: atom
for atom, alias in
re.findall(
r'static constexpr nsStaticAtom\*\s+(.*?)\s+=\s+(nsGkAtoms::.*?);',
cacheConsts
)
}
RE_ATOM = re.compile(r'(fields->SetAttribute|(?:mCachedFields|aFields)->(?:GetAttribute|GetAttributeRefPtr|GetMutableAttribute|HasAttribute|Remove|SetAttribute)(?:<.+>)?)(\(\s*)(nsGkAtoms::[a-zA-Z_]+)')
def repl(m):
# Group 3 is the atom.
alias = aliases.get(m.group(3))
if not alias:
# No alias for this atom. Return input unaltered.
return m.group(0)
alias = "CacheKey::" + alias
# Groups 1 and 2 should be returned unaltered. Group 3 (the atom) is replaced
# with the alias.
return m.group(1) + m.group(2) + alias
for fn in (
# Found with: git grep -l 'ields->'
"accessible/base/CachedTableAccessible.cpp",
"accessible/base/nsAccessibilityService.cpp",
"accessible/base/TextLeafRange.cpp",
"accessible/generic/LocalAccessible.cpp",
"accessible/ipc/DocAccessibleParent.cpp",
"accessible/ipc/RemoteAccessible.cpp",
"accessible/ipc/RemoteAccessible.h",
"accessible/windows/sdn/sdnAccessible.cpp",
):
input = open(fn, "rt").read()
output = RE_ATOM.sub(repl, input)
open(fn, "wt").write(output)
```
Differential Revision: https://phabricator.services.mozilla.com/D184791
In the content process, we simply split into multiple calls when the number of Accessibles exceeds our maximum.
The maximum is calculated to allow for every Accessible to consume 2 KB in the IPDL message.
Currently, this means we split every 131072 Accessibles.
Of course, we could still exceed this IPDL message size if one or more Accessibles consumed a lot more than this; e.g. many labels longer than 2 KB.
However, this seems unlikely in the real world.
If this turns out to be a problem, we'll need to count the actual size of the serialized data for each Accessible.
For example, we could use AccAttributes::SizeOfExcludingThis, though that isn't exactly the serialized size.
I worry though that such data structure traversal could get expensive at scale.
In the parent process, we defer attaching the root of the new subtree to its parent until the final call.
This is achieved by saving the root during the first call and using that to attach and fire events in the final call.
Differential Revision: https://phabricator.services.mozilla.com/D184367
When we serialize a subtree, we put it into a flat list.
Previously, we included the child count for each Accessible so that we knew how many Accessibels to consume as children when de-serializing.
We also de-serialized recursively.
This made it very difficult to split serialization across IPDL calls, since we would always end up splitting in the middle of some Accessible's children.
Instead, we now no longer include the child count, but we do include the parent id and the index of the child in that parent.
This means that each Accessible can be de-serialized independently and iteratively, making it possible to split wherever we need to.
RemoteAccessible creation has also been separated from attachment of the child to its parent, since we will need this when splitting.
Differential Revision: https://phabricator.services.mozilla.com/D184366
This was done with the following command in the accessible/ directory:
```
sed -i 's/\bProxy\(.*\)Event\b/Platform\1Event/' `git grep -l 'Proxy.*Event'`
```
Differential Revision: https://phabricator.services.mozilla.com/D183700
On Windows, focus and caret move events include the caret rectangle.
This isn't used on other platforms.
To simplify the cross-platform interface (including Platform.h), remove the ifdefs from there.
However, we use ifdefs to avoid calculating the rectangle on non-Windows platforms, instead just sending an empty rectangle.
Differential Revision: https://phabricator.services.mozilla.com/D182138
This involved moving ApplyCache from the .h into the .cpp because now that the class is no longer a template, forward declaration of DocAccessibleParent is not sufficient.
Differential Revision: https://phabricator.services.mozilla.com/D181852
This revision modifies UncacheChildrenInSubtree such that removed but relocated
accessibles that are aria-owned are actually relocated to their proper parent
after the removal of the formerly-aria-owning parent. It also contains some
fixes for issues that allowing this relocation unleashes. In particular:
- Logic in PutChildrenBack is reworked in order to better handle different
reparenting situations, such as unacceptable parents or original containers
(or ancestors thereof) that are no longer in the document. These changes help
us avoid failure modes related to events on defunct accessibles, or bad
coalescence due to partially-shut-down trees.
- ShutdownOrPrepareForMove has been updated to handle moving children. We now
recurse through children and move them rather than just shutting them down.
This revision adds tests which verify that the functionality works as intended.
Differential Revision: https://phabricator.services.mozilla.com/D176204
This was done using the following script:
```
matchingFiles=`git grep -l accessibility_cache_enabled`
sed -i 's/StaticPrefs::accessibility_cache_enabled_AtStartup/a11y::IsCacheActive/' $matchingFiles
for f in $matchingFiles; do
usesA11yPref=
grep -q StaticPrefs::accessibility_ $f && usesA11yPref=1
hasA11yInclude=
grep -q 'nsAccessibilityService.h' $f && hasA11yInclude=1
if [ -z $usesA11yPref ] && [ -z $hasA11yInclude ]; then
sed -i 's,mozilla/StaticPrefs_accessibility.h,nsAccessibilityService.h,' $f
elif [ -z $usesA11yPref ] && [ $hasA11yInclude ]; then
sed -i '/"mozilla.StaticPrefs_accessibility.h"/d' $f
elif [ $usesA11yPref ] && [ -z $hasA11yInclude ]; then
sed -i '/"mozilla.StaticPrefs_accessibility.h"/a#include "nsAccessibilityService.h"' $f
fi
done
```
Differential Revision: https://phabricator.services.mozilla.com/D177722
This combines the multiple fields or variants which were previously used to
track sided types like protocol types into a single field wrapped with a
SideVariant.
This will be used in the next part to avoid the need for default constructors
for actor types allowing the proper types to be used.
Differential Revision: https://phabricator.services.mozilla.com/D168879
This should fully eliminate the case where remote accessibles fail to
unregister because of the outer PresShell's lifecycle.
Differential Revision: https://phabricator.services.mozilla.com/D172473
This combines the multiple fields or variants which were previously used to
track sided types like protocol types into a single field wrapped with a
SideVariant.
This will be used in the next part to avoid the need for default constructors
for actor types allowing the proper types to be used.
Differential Revision: https://phabricator.services.mozilla.com/D168879
Otherwise, tests can take a very long time to run due to a bug without us realising that this is due to cache condition timeouts.
This patch also notifies observers of a cache update when state change events are received, as those do update the cache but aren't handled by RecvCache.
Some Mac tests depend on cache notifications for these instead of state change events, so these were hitting cache condition timeouts.
Differential Revision: https://phabricator.services.mozilla.com/D171417
Otherwise, tests can take a very long time to run due to a bug without us realising that this is due to cache condition timeouts.
This patch also notifies observers of a cache update when state change events are received, as those do update the cache but aren't handled by RecvCache.
Some Mac tests depend on cache notifications for these instead of state change events, so these were hitting cache condition timeouts.
Differential Revision: https://phabricator.services.mozilla.com/D171417