зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1662147: Add AXControlSearchKey to rotor r=eeejay
Differential Revision: https://phabricator.services.mozilla.com/D89073
This commit is contained in:
Родитель
f74cb16fd0
Коммит
b99c8c44b6
|
@ -70,7 +70,7 @@ class AccessibleOrProxy {
|
|||
* Return the child object either an accessible or a proxied accessible at
|
||||
* the given index.
|
||||
*/
|
||||
AccessibleOrProxy ChildAt(uint32_t aIdx) {
|
||||
AccessibleOrProxy ChildAt(uint32_t aIdx) const {
|
||||
if (IsProxy()) {
|
||||
return AsProxy()->ChildAt(aIdx);
|
||||
}
|
||||
|
|
|
@ -214,7 +214,7 @@ MARKUPMAP(
|
|||
}
|
||||
if (aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
|
||||
nsGkAtoms::time, eIgnoreCase)) {
|
||||
return new HTMLDateTimeAccessible<roles::GROUPING>(
|
||||
return new HTMLDateTimeAccessible<roles::TIME_EDITOR>(
|
||||
aElement, aContext->Document());
|
||||
}
|
||||
if (aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
|
||||
|
|
|
@ -1066,7 +1066,12 @@ enum Role {
|
|||
*/
|
||||
CODE = 182,
|
||||
|
||||
LAST_ROLE = CODE
|
||||
/**
|
||||
* Represents control whose purpose is to allow a user to edit a time.
|
||||
*/
|
||||
TIME_EDITOR = 183,
|
||||
|
||||
LAST_ROLE = TIME_EDITOR
|
||||
};
|
||||
|
||||
} // namespace roles
|
||||
|
|
|
@ -711,7 +711,7 @@ ROLE(COLOR_CHOOSER,
|
|||
ROLE(DATE_EDITOR,
|
||||
"date editor",
|
||||
ATK_ROLE_DATE_EDITOR,
|
||||
NSAccessibilityUnknownRole,
|
||||
@"AXDateField",
|
||||
NSAccessibilityUnknownSubrole,
|
||||
USE_ROLE_STRING,
|
||||
IA2_ROLE_DATE_EDITOR,
|
||||
|
@ -1856,4 +1856,14 @@ ROLE(CODE,
|
|||
IA2_ROLE_TEXT_FRAME,
|
||||
java::SessionAccessibility::CLASSNAME_VIEW,
|
||||
eNoNameRule)
|
||||
|
||||
ROLE(TIME_EDITOR,
|
||||
"time editor",
|
||||
ATK_ROLE_PANEL,
|
||||
@"AXTimeField",
|
||||
NSAccessibilityUnknownSubrole,
|
||||
ROLE_SYSTEM_GROUPING,
|
||||
ROLE_SYSTEM_GROUPING,
|
||||
java::SessionAccessibility::CLASSNAME_VIEW,
|
||||
eNameFromSubtreeIfReqRule)
|
||||
// clang-format on
|
||||
|
|
|
@ -1060,4 +1060,9 @@ interface nsIAccessibleRole : nsISupports
|
|||
*/
|
||||
const unsigned long ROLE_CODE = 182;
|
||||
|
||||
/**
|
||||
* Represents control whose purpose is to allow a user to edit a time.
|
||||
*/
|
||||
const unsigned long ROLE_TIME_EDITOR = 183;
|
||||
|
||||
};
|
||||
|
|
|
@ -76,7 +76,6 @@ using namespace mozilla::a11y;
|
|||
MOXSearchInfo* search =
|
||||
[[MOXSearchInfo alloc] initWithParameters:searchPredicate
|
||||
andRoot:mGeckoAccessible];
|
||||
|
||||
return [search performSearch];
|
||||
}
|
||||
|
||||
|
@ -205,6 +204,13 @@ using namespace mozilla::a11y;
|
|||
: RotorLandmarkRule();
|
||||
[matches addObjectsFromArray:[self getMatchesForRule:rule]];
|
||||
}
|
||||
|
||||
if ([key isEqualToString:@"AXControlSearchKey"]) {
|
||||
RotorControlRule rule = mImmediateDescendantsOnly
|
||||
? RotorControlRule(mStartElem)
|
||||
: RotorControlRule();
|
||||
[matches addObjectsFromArray:[self getMatchesForRule:rule]];
|
||||
}
|
||||
}
|
||||
|
||||
return matches;
|
||||
|
|
|
@ -39,6 +39,17 @@ class RotorLandmarkRule final : public PivotRoleRule {
|
|||
explicit RotorLandmarkRule(AccessibleOrProxy& aDirectDescendantsFrom);
|
||||
};
|
||||
|
||||
class RotorControlRule final : public PivotRule {
|
||||
public:
|
||||
explicit RotorControlRule(AccessibleOrProxy& aDirectDescendantsFrom);
|
||||
explicit RotorControlRule();
|
||||
|
||||
virtual uint16_t Match(const AccessibleOrProxy& aAccOrProxy) override;
|
||||
|
||||
private:
|
||||
AccessibleOrProxy mDirectDescendantsFrom;
|
||||
};
|
||||
|
||||
/**
|
||||
* This rule matches all accessibles, filtering out non-direct
|
||||
* descendants if necessary.
|
||||
|
|
|
@ -34,6 +34,74 @@ RotorLandmarkRule::RotorLandmarkRule() : PivotRoleRule(roles::LANDMARK) {}
|
|||
RotorLandmarkRule::RotorLandmarkRule(AccessibleOrProxy& aDirectDescendantsFrom)
|
||||
: PivotRoleRule(roles::LANDMARK, aDirectDescendantsFrom) {}
|
||||
|
||||
RotorControlRule::RotorControlRule(AccessibleOrProxy& aDirectDescendantsFrom)
|
||||
: mDirectDescendantsFrom(aDirectDescendantsFrom) {}
|
||||
|
||||
RotorControlRule::RotorControlRule() : mDirectDescendantsFrom(nullptr) {}
|
||||
|
||||
uint16_t RotorControlRule::Match(const AccessibleOrProxy& aAccOrProxy) {
|
||||
uint16_t result = nsIAccessibleTraversalRule::FILTER_IGNORE;
|
||||
|
||||
if (nsAccUtils::MustPrune(aAccOrProxy)) {
|
||||
result |= nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE;
|
||||
}
|
||||
|
||||
if (!mDirectDescendantsFrom.IsNull() &&
|
||||
(aAccOrProxy != mDirectDescendantsFrom)) {
|
||||
result |= nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE;
|
||||
}
|
||||
|
||||
switch (aAccOrProxy.Role()) {
|
||||
case roles::PUSHBUTTON:
|
||||
case roles::SPINBUTTON:
|
||||
case roles::DETAILS:
|
||||
case roles::CHECKBUTTON:
|
||||
case roles::COLOR_CHOOSER:
|
||||
case roles::BUTTONDROPDOWNGRID: // xul colorpicker
|
||||
case roles::LISTBOX:
|
||||
case roles::COMBOBOX:
|
||||
case roles::EDITCOMBOBOX:
|
||||
case roles::RADIOBUTTON:
|
||||
case roles::RADIO_GROUP:
|
||||
case roles::PAGETAB:
|
||||
case roles::SLIDER:
|
||||
case roles::SWITCH:
|
||||
case roles::ENTRY:
|
||||
case roles::OUTLINE:
|
||||
case roles::PASSWORD_TEXT:
|
||||
result |= nsIAccessibleTraversalRule::FILTER_MATCH;
|
||||
break;
|
||||
|
||||
case roles::GROUPING: {
|
||||
// Groupings are sometimes used (like radio groups) to denote
|
||||
// sets of controls. If that's the case, we want to surface
|
||||
// them. We also want to surface grouped time and date controls.
|
||||
for (unsigned int i = 0; i < aAccOrProxy.ChildCount(); i++) {
|
||||
AccessibleOrProxy currChild = aAccOrProxy.ChildAt(i);
|
||||
if (currChild.Role() == roles::CHECKBUTTON ||
|
||||
currChild.Role() == roles::SWITCH ||
|
||||
currChild.Role() == roles::SPINBUTTON ||
|
||||
currChild.Role() == roles::RADIOBUTTON) {
|
||||
result |= nsIAccessibleTraversalRule::FILTER_MATCH;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case roles::DATE_EDITOR:
|
||||
case roles::TIME_EDITOR:
|
||||
result |= nsIAccessibleTraversalRule::FILTER_MATCH;
|
||||
result |= nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Match All Rule
|
||||
|
||||
RotorAllRule::RotorAllRule(AccessibleOrProxy& aDirectDescendantsFrom)
|
||||
|
|
|
@ -399,3 +399,418 @@ addAccessibleTask(
|
|||
);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Test rotor with heading
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`<h1 id="hello">hello</h1><br><h2 id="world">world</h2><br>goodbye`,
|
||||
async (browser, accDoc) => {
|
||||
const searchPred = {
|
||||
AXSearchKey: "AXHeadingSearchKey",
|
||||
AXImmediateDescendants: 1,
|
||||
AXResultsLimit: -1,
|
||||
AXDirection: "AXDirectionNext",
|
||||
};
|
||||
|
||||
const webArea = accDoc.nativeInterface.QueryInterface(
|
||||
Ci.nsIAccessibleMacInterface
|
||||
);
|
||||
is(
|
||||
webArea.getAttributeValue("AXRole"),
|
||||
"AXWebArea",
|
||||
"Got web area accessible"
|
||||
);
|
||||
|
||||
const headingCount = webArea.getParameterizedAttributeValue(
|
||||
"AXUIElementCountForSearchPredicate",
|
||||
NSDictionary(searchPred)
|
||||
);
|
||||
is(2, headingCount, "Found two headings");
|
||||
|
||||
const headings = webArea.getParameterizedAttributeValue(
|
||||
"AXUIElementsForSearchPredicate",
|
||||
NSDictionary(searchPred)
|
||||
);
|
||||
const hello = getNativeInterface(accDoc, "hello");
|
||||
const world = getNativeInterface(accDoc, "world");
|
||||
is(
|
||||
hello.getAttributeValue("AXTitle"),
|
||||
headings[0].getAttributeValue("AXTitle"),
|
||||
"Found correct first heading"
|
||||
);
|
||||
is(
|
||||
world.getAttributeValue("AXTitle"),
|
||||
headings[1].getAttributeValue("AXTitle"),
|
||||
"Found correct second heading"
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Test rotor with buttons
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`
|
||||
<form>
|
||||
<h2>input[type=button]</h2>
|
||||
<input type="button" value="apply" id="button1">
|
||||
|
||||
<h2>input[type=submit]</h2>
|
||||
<input type="submit" value="submit now" id="submit">
|
||||
|
||||
<h2>input[type=image]</h2>
|
||||
<input type="image" src="sample.jpg" alt="submit image" id="image">
|
||||
|
||||
<h2>input[type=reset]</h2>
|
||||
<input type="reset" value="reset now" id="reset">
|
||||
|
||||
<h2>button element</h2>
|
||||
<button id="button2">Submit button</button>
|
||||
</form>
|
||||
`,
|
||||
async (browser, accDoc) => {
|
||||
const searchPred = {
|
||||
AXSearchKey: "AXControlSearchKey",
|
||||
AXImmediateDescendants: 1,
|
||||
AXResultsLimit: -1,
|
||||
AXDirection: "AXDirectionNext",
|
||||
};
|
||||
|
||||
const webArea = accDoc.nativeInterface.QueryInterface(
|
||||
Ci.nsIAccessibleMacInterface
|
||||
);
|
||||
is(
|
||||
webArea.getAttributeValue("AXRole"),
|
||||
"AXWebArea",
|
||||
"Got web area accessible"
|
||||
);
|
||||
|
||||
const controlsCount = webArea.getParameterizedAttributeValue(
|
||||
"AXUIElementCountForSearchPredicate",
|
||||
NSDictionary(searchPred)
|
||||
);
|
||||
is(5, controlsCount, "Found 5 controls");
|
||||
|
||||
const controls = webArea.getParameterizedAttributeValue(
|
||||
"AXUIElementsForSearchPredicate",
|
||||
NSDictionary(searchPred)
|
||||
);
|
||||
const button1 = getNativeInterface(accDoc, "button1");
|
||||
const submit = getNativeInterface(accDoc, "submit");
|
||||
const image = getNativeInterface(accDoc, "image");
|
||||
const reset = getNativeInterface(accDoc, "reset");
|
||||
const button2 = getNativeInterface(accDoc, "button2");
|
||||
|
||||
is(
|
||||
button1.getAttributeValue("AXTitle"),
|
||||
controls[0].getAttributeValue("AXTitle"),
|
||||
"Found correct first control"
|
||||
);
|
||||
is(
|
||||
submit.getAttributeValue("AXTitle"),
|
||||
controls[1].getAttributeValue("AXTitle"),
|
||||
"Found correct second control"
|
||||
);
|
||||
is(
|
||||
image.getAttributeValue("AXTitle"),
|
||||
controls[2].getAttributeValue("AXTitle"),
|
||||
"Found correct third control"
|
||||
);
|
||||
is(
|
||||
reset.getAttributeValue("AXTitle"),
|
||||
controls[3].getAttributeValue("AXTitle"),
|
||||
"Found correct third control"
|
||||
);
|
||||
is(
|
||||
button2.getAttributeValue("AXTitle"),
|
||||
controls[4].getAttributeValue("AXTitle"),
|
||||
"Found correct third control"
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Test rotor with inputs
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`
|
||||
<input type="text" value="I'm a text field." id="text"><br>
|
||||
<input type="text" value="me too" id="implText"><br>
|
||||
<textarea id="textarea">this is some text in a text area</textarea><br>
|
||||
<input type="tel" value="0000000000" id="tel"><br>
|
||||
<input type="url" value="https://example.com" id="url"><br>
|
||||
<input type="email" value="hi@example.com" id="email"><br>
|
||||
<input type="password" value="blah" id="password"><br>
|
||||
<input type="month" value="2020-01" id="month"><br>
|
||||
<input type="week" value="2020-W01" id="week"><br>
|
||||
<input type="number" value="12" id="number"><br>
|
||||
<input type="range" value="12" min="0" max="20" id="range"><br>
|
||||
<input type="date" value="2020-01-01" id="date"><br>
|
||||
<input type="time" value="10:10:10" id="time"><br>
|
||||
`,
|
||||
async (browser, accDoc) => {
|
||||
const searchPred = {
|
||||
AXSearchKey: "AXControlSearchKey",
|
||||
AXImmediateDescendants: 1,
|
||||
AXResultsLimit: -1,
|
||||
AXDirection: "AXDirectionNext",
|
||||
};
|
||||
|
||||
const webArea = accDoc.nativeInterface.QueryInterface(
|
||||
Ci.nsIAccessibleMacInterface
|
||||
);
|
||||
is(
|
||||
webArea.getAttributeValue("AXRole"),
|
||||
"AXWebArea",
|
||||
"Got web area accessible"
|
||||
);
|
||||
|
||||
const controlsCount = webArea.getParameterizedAttributeValue(
|
||||
"AXUIElementCountForSearchPredicate",
|
||||
NSDictionary(searchPred)
|
||||
);
|
||||
|
||||
is(13, controlsCount, "Found 13 controls");
|
||||
// the extra controls here come from our time control
|
||||
// we can't filter out its internal buttons/incrementors
|
||||
// like we do with the date entry because the time entry
|
||||
// doesn't have its own specific role -- its just a grouping.
|
||||
|
||||
const controls = webArea.getParameterizedAttributeValue(
|
||||
"AXUIElementsForSearchPredicate",
|
||||
NSDictionary(searchPred)
|
||||
);
|
||||
|
||||
const text = getNativeInterface(accDoc, "text");
|
||||
const implText = getNativeInterface(accDoc, "implText");
|
||||
const textarea = getNativeInterface(accDoc, "textarea");
|
||||
const tel = getNativeInterface(accDoc, "tel");
|
||||
const url = getNativeInterface(accDoc, "url");
|
||||
const email = getNativeInterface(accDoc, "email");
|
||||
const password = getNativeInterface(accDoc, "password");
|
||||
const month = getNativeInterface(accDoc, "month");
|
||||
const week = getNativeInterface(accDoc, "week");
|
||||
const number = getNativeInterface(accDoc, "number");
|
||||
const range = getNativeInterface(accDoc, "range");
|
||||
|
||||
const toCheck = [
|
||||
text,
|
||||
implText,
|
||||
textarea,
|
||||
tel,
|
||||
url,
|
||||
email,
|
||||
password,
|
||||
month,
|
||||
week,
|
||||
number,
|
||||
range,
|
||||
];
|
||||
|
||||
for (let i = 0; i < toCheck.length; i++) {
|
||||
is(
|
||||
toCheck[i].getAttributeValue("AXValue"),
|
||||
controls[i].getAttributeValue("AXValue"),
|
||||
"Found correct input control"
|
||||
);
|
||||
}
|
||||
|
||||
const date = getNativeInterface(accDoc, "date");
|
||||
const time = getNativeInterface(accDoc, "time");
|
||||
|
||||
is(
|
||||
date.getAttributeValue("AXRole"),
|
||||
controls[11].getAttributeValue("AXRole"),
|
||||
"Found corrent date editor"
|
||||
);
|
||||
|
||||
is(
|
||||
time.getAttributeValue("AXRole"),
|
||||
controls[12].getAttributeValue("AXRole"),
|
||||
"Found corrent time editor"
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Test rotor with groupings
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`
|
||||
<fieldset>
|
||||
<legend>Radios</legend>
|
||||
<div role="radiogroup" id="radios">
|
||||
<input id="radio1" type="radio" name="g1" checked="checked"> Radio 1
|
||||
<input id="radio2" type="radio" name="g1"> Radio 2
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset id="checkboxes">
|
||||
<legend>Checkboxes</legend>
|
||||
<input id="checkbox1" type="checkbox" name="g2"> Checkbox 1
|
||||
<input id="checkbox2" type="checkbox" name="g2" checked="checked">Checkbox 2
|
||||
</fieldset>
|
||||
|
||||
<fieldset id="switches">
|
||||
<legend>Switches</legend>
|
||||
<input id="switch1" name="g3" role="switch" type="checkbox">Switch 1
|
||||
<input checked="checked" id="switch2" name="g3" role="switch" type="checkbox">Switch 2
|
||||
</fieldset>
|
||||
`,
|
||||
async (browser, accDoc) => {
|
||||
const searchPred = {
|
||||
AXSearchKey: "AXControlSearchKey",
|
||||
AXImmediateDescendants: 1,
|
||||
AXResultsLimit: -1,
|
||||
AXDirection: "AXDirectionNext",
|
||||
};
|
||||
|
||||
const webArea = accDoc.nativeInterface.QueryInterface(
|
||||
Ci.nsIAccessibleMacInterface
|
||||
);
|
||||
is(
|
||||
webArea.getAttributeValue("AXRole"),
|
||||
"AXWebArea",
|
||||
"Got web area accessible"
|
||||
);
|
||||
|
||||
const controlsCount = webArea.getParameterizedAttributeValue(
|
||||
"AXUIElementCountForSearchPredicate",
|
||||
NSDictionary(searchPred)
|
||||
);
|
||||
is(9, controlsCount, "Found 9 controls");
|
||||
|
||||
const controls = webArea.getParameterizedAttributeValue(
|
||||
"AXUIElementsForSearchPredicate",
|
||||
NSDictionary(searchPred)
|
||||
);
|
||||
|
||||
const radios = getNativeInterface(accDoc, "radios");
|
||||
const radio1 = getNativeInterface(accDoc, "radio1");
|
||||
const radio2 = getNativeInterface(accDoc, "radio2");
|
||||
|
||||
is(
|
||||
radios.getAttributeValue("AXRole"),
|
||||
controls[0].getAttributeValue("AXRole"),
|
||||
"Found correct group of radios"
|
||||
);
|
||||
is(
|
||||
radio1.getAttributeValue("AXRole"),
|
||||
controls[1].getAttributeValue("AXRole"),
|
||||
"Found correct radio 1"
|
||||
);
|
||||
is(
|
||||
radio2.getAttributeValue("AXRole"),
|
||||
controls[2].getAttributeValue("AXRole"),
|
||||
"Found correct radio 2"
|
||||
);
|
||||
|
||||
const checkboxes = getNativeInterface(accDoc, "checkboxes");
|
||||
const checkbox1 = getNativeInterface(accDoc, "checkbox1");
|
||||
const checkbox2 = getNativeInterface(accDoc, "checkbox2");
|
||||
|
||||
is(
|
||||
checkboxes.getAttributeValue("AXRole"),
|
||||
controls[3].getAttributeValue("AXRole"),
|
||||
"Found correct group of checkboxes"
|
||||
);
|
||||
is(
|
||||
checkbox1.getAttributeValue("AXRole"),
|
||||
controls[4].getAttributeValue("AXRole"),
|
||||
"Found correct checkbox 1"
|
||||
);
|
||||
is(
|
||||
checkbox2.getAttributeValue("AXRole"),
|
||||
controls[5].getAttributeValue("AXRole"),
|
||||
"Found correct checkbox 2"
|
||||
);
|
||||
|
||||
const switches = getNativeInterface(accDoc, "switches");
|
||||
const switch1 = getNativeInterface(accDoc, "switch1");
|
||||
const switch2 = getNativeInterface(accDoc, "switch2");
|
||||
|
||||
is(
|
||||
switches.getAttributeValue("AXRole"),
|
||||
controls[6].getAttributeValue("AXRole"),
|
||||
"Found correct group of switches"
|
||||
);
|
||||
is(
|
||||
switch1.getAttributeValue("AXRole"),
|
||||
controls[7].getAttributeValue("AXRole"),
|
||||
"Found correct switch 1"
|
||||
);
|
||||
is(
|
||||
switch2.getAttributeValue("AXRole"),
|
||||
controls[8].getAttributeValue("AXRole"),
|
||||
"Found correct switch 2"
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Test rotor with misc controls
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`
|
||||
<input role="spinbutton" id="spinbutton" type="number" value="25">
|
||||
|
||||
<details id="details">
|
||||
<summary>Hello</summary>
|
||||
world
|
||||
</details>
|
||||
|
||||
<ul role="tree" id="tree">
|
||||
<li role="treeitem">item1</li>
|
||||
<li role="treeitem">item1</li>
|
||||
</ul>
|
||||
`,
|
||||
async (browser, accDoc) => {
|
||||
const searchPred = {
|
||||
AXSearchKey: "AXControlSearchKey",
|
||||
AXImmediateDescendants: 1,
|
||||
AXResultsLimit: -1,
|
||||
AXDirection: "AXDirectionNext",
|
||||
};
|
||||
|
||||
const webArea = accDoc.nativeInterface.QueryInterface(
|
||||
Ci.nsIAccessibleMacInterface
|
||||
);
|
||||
is(
|
||||
webArea.getAttributeValue("AXRole"),
|
||||
"AXWebArea",
|
||||
"Got web area accessible"
|
||||
);
|
||||
|
||||
const controlsCount = webArea.getParameterizedAttributeValue(
|
||||
"AXUIElementCountForSearchPredicate",
|
||||
NSDictionary(searchPred)
|
||||
);
|
||||
is(3, controlsCount, "Found 3 controls");
|
||||
|
||||
const controls = webArea.getParameterizedAttributeValue(
|
||||
"AXUIElementsForSearchPredicate",
|
||||
NSDictionary(searchPred)
|
||||
);
|
||||
|
||||
const spin = getNativeInterface(accDoc, "spinbutton");
|
||||
const details = getNativeInterface(accDoc, "details");
|
||||
const tree = getNativeInterface(accDoc, "tree");
|
||||
|
||||
is(
|
||||
spin.getAttributeValue("AXRole"),
|
||||
controls[0].getAttributeValue("AXRole"),
|
||||
"Found correct spinbutton"
|
||||
);
|
||||
is(
|
||||
details.getAttributeValue("AXRole"),
|
||||
controls[1].getAttributeValue("AXRole"),
|
||||
"Found correct details element"
|
||||
);
|
||||
is(
|
||||
tree.getAttributeValue("AXRole"),
|
||||
controls[2].getAttributeValue("AXRole"),
|
||||
"Found correct tree"
|
||||
);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -131,6 +131,7 @@ const ROLE_TERM = nsIAccessibleRole.ROLE_TERM;
|
|||
const ROLE_TEXT = nsIAccessibleRole.ROLE_TEXT;
|
||||
const ROLE_TEXT_CONTAINER = nsIAccessibleRole.ROLE_TEXT_CONTAINER;
|
||||
const ROLE_TEXT_LEAF = nsIAccessibleRole.ROLE_TEXT_LEAF;
|
||||
const ROLE_TIME_EDITOR = nsIAccessibleRole.ROLE_TIME_EDITOR;
|
||||
const ROLE_TOGGLE_BUTTON = nsIAccessibleRole.ROLE_TOGGLE_BUTTON;
|
||||
const ROLE_TOOLBAR = nsIAccessibleRole.ROLE_TOOLBAR;
|
||||
const ROLE_TOOLTIP = nsIAccessibleRole.ROLE_TOOLTIP;
|
||||
|
|
Загрузка…
Ссылка в новой задаче