Bug 1672694 - P1: Query layout for selectable text state. r=morgan,Jamie

The SELECTABLE_TEXT state is currently under-utilized and probably wrong, since it simply relies on testing if a hypertext has any text. A more correct reflection of the state should be taken from layout's IsSelectable method.

Note, even if an element is styled `user-select: none`, the text will still be keyboard selectable if it is editable (eg. input or contenteditable), so we should consider that SELECTABLE_TEXT.

Differential Revision: https://phabricator.services.mozilla.com/D95783
This commit is contained in:
Eitan Isaacson 2020-11-04 00:28:57 +00:00
parent 848e6efc73
commit 8a078f1f55
3 changed files with 16 additions and 2 deletions

View File

@ -192,7 +192,12 @@ uint64_t HyperTextAccessible::NativeState() const {
states |= states::READONLY;
}
if (HasChildren()) states |= states::SELECTABLE_TEXT;
nsIFrame* frame = GetFrame();
if ((states & states::EDITABLE) || (frame && frame->IsSelectable(nullptr))) {
// If the accessible is editable the layout selectable state only disables
// mouse selection, but keyboard (shift+arrow) selection is still possible.
states |= states::SELECTABLE_TEXT;
}
return states;
}

View File

@ -54,6 +54,7 @@ const EXT_STATE_STALE = nsIAccessibleStates.EXT_STATE_STALE;
const EXT_STATE_SUPPORTS_AUTOCOMPLETION =
nsIAccessibleStates.EXT_STATE_SUPPORTS_AUTOCOMPLETION;
const EXT_STATE_VERTICAL = nsIAccessibleStates.EXT_STATE_VERTICAL;
const EXT_STATE_SELECTABLE_TEXT = nsIAccessibleStates.EXT_STATE_SELECTABLE_TEXT;
const kOrdinalState = false;
const kExtraState = 1;

View File

@ -34,12 +34,18 @@
testStates("document", STATE_READONLY);
testStates("editable_document", 0, EXT_STATE_EDITABLE, STATE_READONLY);
testStates("p", 0, EXT_STATE_SELECTABLE_TEXT, 0, EXT_STATE_EDITABLE);
testStates("unselectable_p", 0, 0, 0, EXT_STATE_SELECTABLE_TEXT | EXT_STATE_EDITABLE);
testStates("unselectable_link", 0, 0, 0, EXT_STATE_SELECTABLE_TEXT | EXT_STATE_EDITABLE);
document.designMode = "on";
testStates(document, 0, EXT_STATE_EDITABLE, STATE_READONLY);
testStates("p", 0, EXT_STATE_EDITABLE, STATE_READONLY);
testStates("p", 0, EXT_STATE_EDITABLE | EXT_STATE_SELECTABLE_TEXT, STATE_READONLY);
testStates("document", 0, EXT_STATE_EDITABLE, STATE_READONLY);
testStates("editable_document", 0, EXT_STATE_EDITABLE, STATE_READONLY);
testStates("unselectable_p", 0, EXT_STATE_SELECTABLE_TEXT | EXT_STATE_EDITABLE);
testStates("unselectable_link", 0, EXT_STATE_SELECTABLE_TEXT | EXT_STATE_EDITABLE);
document.designMode = "off";
@ -80,6 +86,8 @@
<p id="p">hello</p>
<p id="unselectable_p" style="user-select: none;">unselectable <a id="unselectable_link" href="#">link</a></p>
<div id="document" role="document">document</div>
<div id="editable_document" role="document" contentEditable="true">editable document</doc>