JAWS and NVDA will continue to use IA2 in Firefox.
However, enabling native UIA in Gecko causes them both to try to use UIA, which causes breakage.
The same is presumably true for other Vispero products, as they use components shared with JAWS.
Future versions of these products will handle this correctly themselves.
Until then, disable UIA when these products are detected.
As part of this, the UIA pref has been changed from a bool to a uint32_t.
This will cause existing configurations of this pref to be reset to the default, but this is okay because this pref has never been documented, exposed in the UI or intended for public usage.
This allows for three values: 0 to never enable, 1 to always enable and 2 to enable unless incompatible clients are detected.
This makes it possible for developers to test those clients with Gecko's UIA implementation when necessary.
Differential Revision: https://phabricator.services.mozilla.com/D243245
After bug 1953866, it will no longer be possible to have inline `<script>` elements in any document which runs in a chrome context.
Several accessibility tests currently rely on this to set things up which can't be done in pure HTML/CSS, but which need to be done before the content is initially added to the accessibility tree so that we can explicitly test the initial state (vs the state after it is mutated).
To work around this, a content task can be specified using the contentSetup argument to addAccessibleTask.
This causes the following to happen:
1. aria-hidden="true" is set on the body, preventing the initial accessibility tree update from including any content.
2. contentTask is executed in the context of the document.
3. aria-hidden is removed from the body, so that all of the content (including any changes made by contentSetup) is processed by accessibility.
4. A reorder event is awaited on the body, so that we can guarantee that (3) is complete.
Subsequent patches will adjust existing tests as needed.
Differential Revision: https://phabricator.services.mozilla.com/D242489
In bug 1951067, I pruned all 0 width whitespace text nodes from the accessibility tree.
However, it turns out that whitespace text nodes at the end of wrapped lines can also be 0 width.
These have semantic importance, since otherwise, words in separate inline nodes can be merged together without a space.
To fix this, explicitly check that the node is before a hard line break, not a soft (wrapped) line break.
Differential Revision: https://phabricator.services.mozilla.com/D242290
I previously thought that CaretAssociationHint::Before was only used either at the start of a node or at the end of a line.
However, it can also be used if the user clicks any character other than the first in a text node.
To fix this, check if we're at the start of a line for all offsets, not just offset 0.
I didn't do this originally in an attempt to reduce the cases where we must search for lines, but it seems this is unavoidable.
If we run into performance problems here, we might be able to restrict this check to cases where we're at the start of a layout frame.
However, that significantly complicates the code, I'm not entirely certain it will work and it is likely premature optimisation, so I opted not to do that in this patch.
Differential Revision: https://phabricator.services.mozilla.com/D241770
Had to get rid of dependency on MustPrune because this happens at
instantiaton. If an accessible loses or gains a child in its lifetime
the interfaces it supports cannot change.
Differential Revision: https://phabricator.services.mozilla.com/D241690
There are multiple problems and inconsistencies in the way we previously calculated text bounds in various places:
1. TextLeafRange::WalkLineRects and TextLeafRange::Bounds calculated bounds inclusive of the range end. However, everywhere else, range ends are exclusive.
2. To compensate for this, HyperTextAccessibleBase::TextBounds walked back 1 character from the end before calling TextLeafRange::Bounds. However, other callers (UIA and Mac) didn't do this. Including the range end meant we included the bounds for an additional character or even an entire line in some cases.
3. When lines end with a line feed character, we tried to include this in the bounds calculation. Since line feeds have a 0 rect, this messed up the calculation.
4. Even though WalkLineRects constrained line bounds to the end of the range, the provided sub-ranges were not constrained.
To fix these problems, TextLeafRange::WalkLineRects and TextLeafRange::Bounds now explicitly return bounds and sub-ranges constrained to, but exclusive of, the end of the range.
HyperTextAccessibleBase::TextBounds has been updated accordingly.
The line feed character is ignored when calculating line bounds.
Co-authored-by: Nathan LaPre <nlapre@mozilla.com>
Differential Revision: https://phabricator.services.mozilla.com/D237142
This was causing an assertion when firing caret events where the element containing the caret is aria-hidden, since the offset we produced was effectively bogus for the target Accessible.
Doing this is bad authoring, but we need to at least ensure the offset is valid.
Arguably, we shouldn't fire caret events at all in this case, but this is a trickier, riskier fix and I don't think it makes sense to spend time on that to compensate for bad authoring.
Differential Revision: https://phabricator.services.mozilla.com/D240579
This patch changes the backing prefs by relying on the tristate offered
by browser.display.document_color_use instead of
browser.display.use_system_colors. This simplifies the color
decision tree, and offers a simplified UI.
The tristate preference offered to the user is as follows:
1. "Use platform's contrast settings" (document_color_use=0)
2. "Off" - never use HCM, regardless of platform setting (document_color_use=1)
3. "On" - always use HCM, regardless of platform setting (document_color_use=2)
Option 3 also reveals a colors UI for the user to choose the palette the
browser HCM will use (bg/text/link/visited).
There are three color palettes to choose from in light of the preference
above they are:
1. WIDGET_COLORS: The OS's configured colors used by its theme.
2. HARDCODED_COLORS: Colors deemed as standard and are hard coded into
Firefox (eg. white on black text, blue and purple links).
3. PREFERENCE_COLORS: Colors that are stored in preferences and are
configurable from the colors UI (eg. browser.visited_color and
browser.display.background_color)
The decision over which palette to use is as follows:
* If we are styling browser UI -> WIDGET_COLORS
* else, if resist fingerprinting is enabled -> HARDCODED_COLORS
* else, if document_color_use==0 AND OS HCM is on -> WIDGET_COLORS
* else, if document_color_use==2 -> PREFERENCE_COLORS
* else -> HARDCODED_COLORS
Differential Revision: https://phabricator.services.mozilla.com/D211115
This patch changes the backing prefs by relying on the tristate offered
by browser.display.document_color_use instead of
browser.display.use_system_colors. This simplifies the color
decision tree, and offers a simplified UI.
The tristate preference offered to the user is as follows:
1. "Use platform's contrast settings" (document_color_use=0)
2. "Off" - never use HCM, regardless of platform setting (document_color_use=1)
3. "On" - always use HCM, regardless of platform setting (document_color_use=2)
Option 3 also reveals a colors UI for the user to choose the palette the
browser HCM will use (bg/text/link/visited).
There are three color palettes to choose from in light of the preference
above they are:
1. WIDGET_COLORS: The OS's configured colors used by its theme.
2. HARDCODED_COLORS: Colors deemed as standard and are hard coded into
Firefox (eg. white on black text, blue and purple links).
3. PREFERENCE_COLORS: Colors that are stored in preferences and are
configurable from the colors UI (eg. browser.visited_color and
browser.display.background_color)
The decision over which palette to use is as follows:
* If we are styling browser UI -> WIDGET_COLORS
* else, if resist fingerprinting is enabled -> HARDCODED_COLORS
* else, if document_color_use==0 AND OS HCM is on -> WIDGET_COLORS
* else, if document_color_use==2 -> PREFERENCE_COLORS
* else -> HARDCODED_COLORS
Differential Revision: https://phabricator.services.mozilla.com/D211115
Text children of links are (and should be) exposed in the UIA tree, but Narrator misbehaves when we return these from GetEnclosingElement.
Children of Accessibles for which MustPrune() returns true are not exposed in the UIA tree, so they shouldn't be returned by GetEnclosingElement.
Differential Revision: https://phabricator.services.mozilla.com/D239979
For now, the core SELECTABLE_TEXT state is only exposed on text containers, not on text leaves.
We may want to reconsider this at some point.
For now, just handle this case in the UIA code, since that's the only place it matters.
Differential Revision: https://phabricator.services.mozilla.com/D239855
We already had code to expose SELECTABLE_TEXT in HyperTextAccessible, from which DocAccessible inherits.
However, DocAccessible overrides the method and doesn't call the HyperTextAccessible implementation.
We don't want to do that because it does work that isn't necessary for DocAccessible.
In addition, we need to use a different layout frame for the document.
See the code comments for details.
Specific code has been added to DocAccessible to expose this state.
This fixes the UIA Text pattern's SupportedTextSelection property on documents.
Differential Revision: https://phabricator.services.mozilla.com/D239854
For now, the core SELECTABLE_TEXT state is only exposed on text containers, not on text leaves.
We may want to reconsider this at some point.
For now, just handle this case in the UIA code, since that's the only place it matters.
Differential Revision: https://phabricator.services.mozilla.com/D239855
We already had code to expose SELECTABLE_TEXT in HyperTextAccessible, from which DocAccessible inherits.
However, DocAccessible overrides the method and doesn't call the HyperTextAccessible implementation.
We don't want to do that because it does work that isn't necessary for DocAccessible.
In addition, we need to use a different layout frame for the document.
See the code comments for details.
Specific code has been added to DocAccessible to expose this state.
This fixes the UIA Text pattern's SupportedTextSelection property on documents.
Differential Revision: https://phabricator.services.mozilla.com/D239854
We need to support the Text pattern on text leaves to fix issues with Narrator.
Removing support on the root isn't strictly necessary, but the Text pattern isn't normally supported on a UIA Window and Chromium doesn't do this, so I think it's best to follow.
This change necessitated moving UiaText so that it is no longer inherited by ia2AccessibleHypertext.
I initially tried to inherit UiaText into uiaRawElmProvider, but that doesn't work because ITextProvider and ISelectionProvider both have a GetSelection method with the same signature.
This meant that the ISelectionProvider implementation of GetSelection in uiaRawElmProvider was overriding the implementation in UiaText.
Instead, UiaText has now been split into a separate object.
Differential Revision: https://phabricator.services.mozilla.com/D239811
Our normal computed style and bounds change notifications don't fire in this case.
Previously, we kept the bounds from before the change to display: contents in the cache.
Any new children added to the display: contents element would use their grandparent for parent relative bounds, since display: contents elements have no frame and thus can't be used for parent relative bounds.
When we accumulated bounds for the children in RemoteAccessible using their ancestors, we included the stale bounds for the element that is now display: contents.
This resulted in double counting the distance between the parent and the element before it became display: contents.
PruneOrInsertSubtree gets called for elements which are losing a frame, so we now check for this case here and update the cache appropriately.
Differential Revision: https://phabricator.services.mozilla.com/D239081
Our normal computed style and bounds change notifications don't fire in this case.
Previously, we kept the bounds from before the change to display: contents in the cache.
Any new children added to the display: contents element would use their grandparent for parent relative bounds, since display: contents elements have no frame and thus can't be used for parent relative bounds.
When we accumulated bounds for the children in RemoteAccessible using their ancestors, we included the stale bounds for the element that is now display: contents.
This resulted in double counting the distance between the parent and the element before it became display: contents.
PruneOrInsertSubtree gets called for elements which are losing a frame, so we now check for this case here and update the cache appropriately.
Differential Revision: https://phabricator.services.mozilla.com/D239081
These mitigations were implemented in AccessibleHandler in bug 1798098.
However, after CtW, AccessibleHandler no longer exists and these mitigations weren't ported across.
Differential Revision: https://phabricator.services.mozilla.com/D202369
It was possible for <input> and <textarea> to incorrectly report the IsReadOnly
property as "true" to UIA, particularly when empty. There is no text leaf in
empty text inputs, so our TextLeafPoint would point to the text field itself.
Code that retrieves attributes for UIA didn't handle this case, which caused AT
issues, such as Narrator failing to switch out of scan mode automatically.
This revision fixes the issue by properly checking for text fields when figuring
out whether a TextLeafPoint's Accessible is read-only. It also adds a test to
verify the same.
Differential Revision: https://phabricator.services.mozilla.com/D237644
In certain conditions, WalkLineRects uses the incorrect endpoint for
calculating rects for a given TextLeafRange. This revision fixes the problem by
properly walking the endpoint back by one character, if possible. It also adds a
test verifying that character bounds are fixed.
Differential Revision: https://phabricator.services.mozilla.com/D237142
This revision adds a loop condition to ensure we don't hit an infinite loop
while walking backwards in UiaTextRange::FindAttribute. It also adds a test to
verify that we won't hit this loop again.
Differential Revision: https://phabricator.services.mozilla.com/D237300
Before custom highlights, ranges from a dom::Selection couldn't overlap and thus TextLeafRange didn't handle this.
However, custom highlight ranges can overlap.
Because we can't sort by both start and end offset any more, we can unfortunately no longer binary search the array of ranges for RemoteAccessible.
Hopefully, there won't be so many text offset attribute ranges in a single text leaf that this will be problematic.
Gecko's own spell checker stops at 500 misspelled words in a text node.
If it does cause problems, we could split the ranges into smaller, non-overlapping ranges when we send them from the content process.
Note that overlapping spelling and grammar errors aren't yet supported due to their use of the same "invalid" text attribute, but I expect this should be rare and can be fixed in future if needed.
However, this does handle highlights overlapping with either spelling or grammar errors.
Differential Revision: https://phabricator.services.mozilla.com/D233807