ax_role_properties.cc 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ui/accessibility/ax_role_properties.h"
  5. #include "build/build_config.h"
  6. #include "build/chromeos_buildflags.h"
  7. #include "ui/accessibility/ax_enums.mojom.h"
  8. namespace ui {
  9. namespace {
  10. #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH)
  11. constexpr bool kExposeLayoutTableAsDataTable = true;
  12. #else
  13. constexpr bool kExposeLayoutTableAsDataTable = false;
  14. #endif // BUILDFLAG(IS_WIN)
  15. } // namespace
  16. bool CanHaveInlineTextBoxChildren(ax::mojom::Role role) {
  17. switch (role) {
  18. case ax::mojom::Role::kLineBreak:
  19. case ax::mojom::Role::kStaticText:
  20. return true;
  21. default:
  22. return false;
  23. }
  24. }
  25. bool HasPresentationalChildren(const ax::mojom::Role role) {
  26. // See http://www.w3.org/TR/core-aam-1.1/#exclude_elements2.
  27. if (IsImage(role))
  28. return true;
  29. switch (role) {
  30. case ax::mojom::Role::kButton:
  31. case ax::mojom::Role::kCheckBox:
  32. case ax::mojom::Role::kMath:
  33. // Return false for kMathMLMath, since the children of a <math> tag should
  34. // be exposed to make MathML accessible.
  35. case ax::mojom::Role::kMenuItemCheckBox:
  36. case ax::mojom::Role::kMenuItemRadio:
  37. case ax::mojom::Role::kMenuListOption:
  38. case ax::mojom::Role::kProgressIndicator:
  39. case ax::mojom::Role::kScrollBar:
  40. case ax::mojom::Role::kSlider:
  41. case ax::mojom::Role::kSwitch:
  42. case ax::mojom::Role::kTab:
  43. return true;
  44. default:
  45. return false;
  46. }
  47. }
  48. bool IsAlert(const ax::mojom::Role role) {
  49. switch (role) {
  50. case ax::mojom::Role::kAlert:
  51. case ax::mojom::Role::kAlertDialog:
  52. return true;
  53. default:
  54. return false;
  55. }
  56. }
  57. bool IsAndroidTextViewCandidate(const ax::mojom::Role role) {
  58. switch (role) {
  59. case ax::mojom::Role::kGenericContainer:
  60. case ax::mojom::Role::kHeading:
  61. case ax::mojom::Role::kParagraph:
  62. return true;
  63. default:
  64. return false;
  65. }
  66. }
  67. bool IsButton(const ax::mojom::Role role) {
  68. // According to the WAI-ARIA spec, native button or role="button"
  69. // supports |aria-expanded| and |aria-pressed|.
  70. // If the button has |aria-expanded| set, then it takes on
  71. // Role::kPopUpButton.
  72. // If the button has |aria-pressed| set, then it takes on
  73. // Role::kToggleButton.
  74. // https://www.w3.org/TR/wai-aria-1.1/#button
  75. return role == ax::mojom::Role::kButton ||
  76. role == ax::mojom::Role::kPopUpButton ||
  77. role == ax::mojom::Role::kToggleButton;
  78. }
  79. bool IsCellOrTableHeader(const ax::mojom::Role role) {
  80. switch (role) {
  81. case ax::mojom::Role::kCell:
  82. case ax::mojom::Role::kColumnHeader:
  83. case ax::mojom::Role::kMathMLTableCell:
  84. case ax::mojom::Role::kRowHeader:
  85. return true;
  86. case ax::mojom::Role::kLayoutTableCell:
  87. return kExposeLayoutTableAsDataTable;
  88. default:
  89. return false;
  90. }
  91. }
  92. bool IsChildTreeOwner(const ax::mojom::Role role) {
  93. switch (role) {
  94. case ax::mojom::Role::kEmbeddedObject:
  95. case ax::mojom::Role::kIframe:
  96. case ax::mojom::Role::kIframePresentational:
  97. case ax::mojom::Role::kPluginObject:
  98. case ax::mojom::Role::kPortal:
  99. return true;
  100. default:
  101. return false;
  102. }
  103. }
  104. bool IsClickable(const ax::mojom::Role role) {
  105. switch (role) {
  106. case ax::mojom::Role::kButton:
  107. case ax::mojom::Role::kCheckBox:
  108. case ax::mojom::Role::kColorWell:
  109. case ax::mojom::Role::kComboBoxMenuButton:
  110. case ax::mojom::Role::kDate:
  111. case ax::mojom::Role::kDateTime:
  112. case ax::mojom::Role::kDisclosureTriangle:
  113. case ax::mojom::Role::kDocBackLink:
  114. case ax::mojom::Role::kDocBiblioRef:
  115. case ax::mojom::Role::kDocGlossRef:
  116. case ax::mojom::Role::kDocNoteRef:
  117. case ax::mojom::Role::kImeCandidate:
  118. case ax::mojom::Role::kInputTime:
  119. case ax::mojom::Role::kLink:
  120. case ax::mojom::Role::kListBox:
  121. case ax::mojom::Role::kListBoxOption:
  122. case ax::mojom::Role::kMenuItem:
  123. case ax::mojom::Role::kMenuItemCheckBox:
  124. case ax::mojom::Role::kMenuItemRadio:
  125. case ax::mojom::Role::kMenuListOption:
  126. case ax::mojom::Role::kPdfActionableHighlight:
  127. case ax::mojom::Role::kPopUpButton:
  128. case ax::mojom::Role::kPortal:
  129. case ax::mojom::Role::kRadioButton:
  130. case ax::mojom::Role::kSearchBox:
  131. case ax::mojom::Role::kSpinButton:
  132. case ax::mojom::Role::kSwitch:
  133. case ax::mojom::Role::kTab:
  134. case ax::mojom::Role::kTextField:
  135. case ax::mojom::Role::kTextFieldWithComboBox:
  136. // kTree and related roles are not included because they are not natively
  137. // supported by HTML and so their "clickable" behavior is uncertain.
  138. case ax::mojom::Role::kToggleButton:
  139. return true;
  140. default:
  141. return false;
  142. }
  143. }
  144. bool IsCheckBox(const ax::mojom::Role role) {
  145. switch (role) {
  146. case ax::mojom::Role::kCheckBox:
  147. case ax::mojom::Role::kMenuItemCheckBox:
  148. case ax::mojom::Role::kSwitch:
  149. return true;
  150. default:
  151. return false;
  152. }
  153. }
  154. bool IsComboBox(const ax::mojom::Role role) {
  155. switch (role) {
  156. case ax::mojom::Role::kComboBoxMenuButton:
  157. case ax::mojom::Role::kComboBoxGrouping:
  158. case ax::mojom::Role::kTextFieldWithComboBox:
  159. return true;
  160. default:
  161. return false;
  162. }
  163. }
  164. bool IsComboBoxContainer(const ax::mojom::Role role) {
  165. switch (role) {
  166. case ax::mojom::Role::kDialog:
  167. case ax::mojom::Role::kGrid:
  168. case ax::mojom::Role::kListBox:
  169. case ax::mojom::Role::kTree:
  170. return true;
  171. default:
  172. return false;
  173. }
  174. }
  175. bool IsContainerWithSelectableChildren(const ax::mojom::Role role) {
  176. switch (role) {
  177. case ax::mojom::Role::kComboBoxGrouping:
  178. case ax::mojom::Role::kComboBoxMenuButton:
  179. case ax::mojom::Role::kGrid:
  180. case ax::mojom::Role::kListBox:
  181. case ax::mojom::Role::kListGrid:
  182. case ax::mojom::Role::kMenu:
  183. case ax::mojom::Role::kMenuBar:
  184. case ax::mojom::Role::kMenuListPopup:
  185. case ax::mojom::Role::kRadioGroup:
  186. case ax::mojom::Role::kTabList:
  187. case ax::mojom::Role::kToolbar:
  188. case ax::mojom::Role::kTree:
  189. case ax::mojom::Role::kTreeGrid:
  190. return true;
  191. default:
  192. return false;
  193. }
  194. }
  195. bool IsControl(const ax::mojom::Role role) {
  196. switch (role) {
  197. case ax::mojom::Role::kButton:
  198. case ax::mojom::Role::kCheckBox:
  199. case ax::mojom::Role::kColorWell:
  200. case ax::mojom::Role::kComboBoxMenuButton:
  201. case ax::mojom::Role::kDate:
  202. case ax::mojom::Role::kDateTime:
  203. case ax::mojom::Role::kDisclosureTriangle:
  204. case ax::mojom::Role::kInputTime:
  205. case ax::mojom::Role::kListBox:
  206. case ax::mojom::Role::kListGrid:
  207. case ax::mojom::Role::kMenuItem:
  208. case ax::mojom::Role::kMenuItemCheckBox:
  209. case ax::mojom::Role::kMenuItemRadio:
  210. case ax::mojom::Role::kMenuListOption:
  211. case ax::mojom::Role::kPdfActionableHighlight:
  212. case ax::mojom::Role::kPopUpButton:
  213. case ax::mojom::Role::kRadioButton:
  214. case ax::mojom::Role::kScrollBar:
  215. case ax::mojom::Role::kSearchBox:
  216. case ax::mojom::Role::kSlider:
  217. case ax::mojom::Role::kSpinButton:
  218. case ax::mojom::Role::kSwitch:
  219. case ax::mojom::Role::kTab:
  220. case ax::mojom::Role::kTextField:
  221. case ax::mojom::Role::kTextFieldWithComboBox:
  222. case ax::mojom::Role::kToggleButton:
  223. case ax::mojom::Role::kTree:
  224. case ax::mojom::Role::kTreeGrid:
  225. case ax::mojom::Role::kTreeItem:
  226. return true;
  227. default:
  228. return false;
  229. }
  230. }
  231. bool IsControlOnAndroid(const ax::mojom::Role role, bool isFocusable) {
  232. switch (role) {
  233. case ax::mojom::Role::kSplitter:
  234. return isFocusable;
  235. case ax::mojom::Role::kDate:
  236. case ax::mojom::Role::kDateTime:
  237. case ax::mojom::Role::kDocBackLink:
  238. case ax::mojom::Role::kDocBiblioRef:
  239. case ax::mojom::Role::kDocGlossRef:
  240. case ax::mojom::Role::kDocNoteRef:
  241. case ax::mojom::Role::kInputTime:
  242. case ax::mojom::Role::kLink:
  243. case ax::mojom::Role::kTreeItem:
  244. return true;
  245. case ax::mojom::Role::kAlert:
  246. case ax::mojom::Role::kDialog:
  247. case ax::mojom::Role::kMenu:
  248. case ax::mojom::Role::kMenuBar:
  249. case ax::mojom::Role::kTree:
  250. case ax::mojom::Role::kUnknown:
  251. return false;
  252. default:
  253. return IsControl(role);
  254. }
  255. }
  256. bool IsDateOrTimeInput(const ax::mojom::Role role) {
  257. switch (role) {
  258. case ax::mojom::Role::kDate:
  259. case ax::mojom::Role::kDateTime:
  260. case ax::mojom::Role::kInputTime:
  261. return true;
  262. default:
  263. return false;
  264. }
  265. }
  266. bool IsDialog(const ax::mojom::Role role) {
  267. switch (role) {
  268. case ax::mojom::Role::kAlertDialog:
  269. case ax::mojom::Role::kDialog:
  270. return true;
  271. default:
  272. return false;
  273. }
  274. }
  275. bool IsGridLike(const ax::mojom::Role role) {
  276. switch (role) {
  277. case ax::mojom::Role::kGrid:
  278. case ax::mojom::Role::kListGrid:
  279. case ax::mojom::Role::kTree:
  280. case ax::mojom::Role::kTreeGrid:
  281. return true;
  282. default:
  283. return false;
  284. }
  285. }
  286. bool IsForm(const ax::mojom::Role role) {
  287. switch (role) {
  288. case ax::mojom::Role::kForm:
  289. return true;
  290. default:
  291. return false;
  292. }
  293. }
  294. bool IsFormatBoundary(const ax::mojom::Role role) {
  295. return IsControl(role) || IsHeading(role) || IsImageOrVideo(role);
  296. }
  297. bool IsHeading(const ax::mojom::Role role) {
  298. switch (role) {
  299. case ax::mojom::Role::kHeading:
  300. case ax::mojom::Role::kDocSubtitle:
  301. return true;
  302. default:
  303. return false;
  304. }
  305. }
  306. bool IsHeadingOrTableHeader(const ax::mojom::Role role) {
  307. switch (role) {
  308. case ax::mojom::Role::kColumnHeader:
  309. case ax::mojom::Role::kDocSubtitle:
  310. case ax::mojom::Role::kHeading:
  311. case ax::mojom::Role::kRowHeader:
  312. return true;
  313. default:
  314. return false;
  315. }
  316. }
  317. bool IsIframe(ax::mojom::Role role) {
  318. switch (role) {
  319. case ax::mojom::Role::kIframe:
  320. case ax::mojom::Role::kIframePresentational:
  321. return true;
  322. default:
  323. return false;
  324. }
  325. }
  326. bool IsImageOrVideo(const ax::mojom::Role role) {
  327. return IsImage(role) || role == ax::mojom::Role::kVideo;
  328. }
  329. bool IsImage(const ax::mojom::Role role) {
  330. switch (role) {
  331. case ax::mojom::Role::kCanvas:
  332. case ax::mojom::Role::kDocCover:
  333. case ax::mojom::Role::kGraphicsSymbol:
  334. case ax::mojom::Role::kImage:
  335. case ax::mojom::Role::kSvgRoot:
  336. return true;
  337. default:
  338. return false;
  339. }
  340. }
  341. bool IsItemLike(const ax::mojom::Role role) {
  342. switch (role) {
  343. case ax::mojom::Role::kArticle:
  344. case ax::mojom::Role::kComment:
  345. case ax::mojom::Role::kListItem:
  346. case ax::mojom::Role::kMenuItem:
  347. case ax::mojom::Role::kMenuItemRadio:
  348. case ax::mojom::Role::kTab:
  349. case ax::mojom::Role::kMenuItemCheckBox:
  350. case ax::mojom::Role::kTreeItem:
  351. case ax::mojom::Role::kListBoxOption:
  352. case ax::mojom::Role::kMenuListOption:
  353. case ax::mojom::Role::kRadioButton:
  354. case ax::mojom::Role::kDescriptionListTerm:
  355. case ax::mojom::Role::kTerm:
  356. DCHECK(!IsSetLike(role)) << "Role cannot be both item-like and set-like.";
  357. return true;
  358. default:
  359. return false;
  360. }
  361. }
  362. bool IsLandmark(const ax::mojom::Role role) {
  363. switch (role) {
  364. case ax::mojom::Role::kBanner:
  365. case ax::mojom::Role::kComplementary:
  366. case ax::mojom::Role::kContentInfo:
  367. case ax::mojom::Role::kForm:
  368. case ax::mojom::Role::kMain:
  369. case ax::mojom::Role::kNavigation:
  370. case ax::mojom::Role::kRegion:
  371. case ax::mojom::Role::kSearch:
  372. return true;
  373. default:
  374. return false;
  375. }
  376. }
  377. bool IsLink(const ax::mojom::Role role) {
  378. switch (role) {
  379. case ax::mojom::Role::kDocBackLink:
  380. case ax::mojom::Role::kDocBiblioRef:
  381. case ax::mojom::Role::kDocGlossRef:
  382. case ax::mojom::Role::kDocNoteRef:
  383. case ax::mojom::Role::kLink:
  384. return true;
  385. default:
  386. return false;
  387. }
  388. }
  389. bool IsList(const ax::mojom::Role role) {
  390. switch (role) {
  391. case ax::mojom::Role::kDescriptionList:
  392. case ax::mojom::Role::kDirectory:
  393. case ax::mojom::Role::kDocBibliography:
  394. case ax::mojom::Role::kList:
  395. case ax::mojom::Role::kListBox:
  396. case ax::mojom::Role::kListGrid:
  397. return true;
  398. default:
  399. return false;
  400. }
  401. }
  402. bool IsListItem(const ax::mojom::Role role) {
  403. switch (role) {
  404. case ax::mojom::Role::kDescriptionListTerm:
  405. case ax::mojom::Role::kDocBiblioEntry:
  406. case ax::mojom::Role::kDocEndnote:
  407. case ax::mojom::Role::kListBoxOption:
  408. case ax::mojom::Role::kListItem:
  409. case ax::mojom::Role::kTerm:
  410. return true;
  411. default:
  412. return false;
  413. }
  414. }
  415. bool IsMenuItem(ax::mojom::Role role) {
  416. switch (role) {
  417. case ax::mojom::Role::kMenuItem:
  418. case ax::mojom::Role::kMenuItemCheckBox:
  419. case ax::mojom::Role::kMenuItemRadio:
  420. return true;
  421. default:
  422. return false;
  423. }
  424. }
  425. bool IsMenuRelated(const ax::mojom::Role role) {
  426. switch (role) {
  427. case ax::mojom::Role::kMenu:
  428. case ax::mojom::Role::kMenuBar:
  429. case ax::mojom::Role::kMenuItem:
  430. case ax::mojom::Role::kMenuItemCheckBox:
  431. case ax::mojom::Role::kMenuItemRadio:
  432. case ax::mojom::Role::kMenuListOption:
  433. case ax::mojom::Role::kMenuListPopup:
  434. return true;
  435. default:
  436. return false;
  437. }
  438. }
  439. bool IsPlatformDocument(const ax::mojom::Role role) {
  440. // "ax::mojom::Role::kDocument" is excluded because it refers to nodes with
  441. // the ARIA document role. These are not at the root of an HTML document. They
  442. // can appear anywhere within an HTML document, but never at its root.
  443. switch (role) {
  444. case ax::mojom::Role::kPdfRoot:
  445. case ax::mojom::Role::kRootWebArea:
  446. return true;
  447. default:
  448. return false;
  449. }
  450. }
  451. bool IsPresentational(const ax::mojom::Role role) {
  452. switch (role) {
  453. case ax::mojom::Role::kNone:
  454. return true;
  455. default:
  456. return false;
  457. }
  458. }
  459. bool IsRadio(const ax::mojom::Role role) {
  460. switch (role) {
  461. case ax::mojom::Role::kRadioButton:
  462. case ax::mojom::Role::kMenuItemRadio:
  463. return true;
  464. default:
  465. return false;
  466. }
  467. }
  468. bool IsRangeValueSupported(const ax::mojom::Role role) {
  469. // https://www.w3.org/TR/wai-aria-1.1/#aria-valuenow
  470. // https://www.w3.org/TR/wai-aria-1.1/#aria-valuetext
  471. // Roles that support aria-valuetext / aria-valuenow
  472. switch (role) {
  473. case ax::mojom::Role::kMeter:
  474. case ax::mojom::Role::kProgressIndicator:
  475. case ax::mojom::Role::kScrollBar:
  476. case ax::mojom::Role::kSlider:
  477. case ax::mojom::Role::kSpinButton:
  478. case ax::mojom::Role::kSplitter:
  479. return true;
  480. default:
  481. return false;
  482. }
  483. }
  484. bool IsReadOnlySupported(const ax::mojom::Role role) {
  485. // https://www.w3.org/TR/wai-aria-1.1/#aria-readonly
  486. // Roles that support aria-readonly
  487. switch (role) {
  488. case ax::mojom::Role::kCheckBox:
  489. case ax::mojom::Role::kColorWell:
  490. case ax::mojom::Role::kComboBoxGrouping:
  491. case ax::mojom::Role::kComboBoxMenuButton:
  492. case ax::mojom::Role::kDate:
  493. case ax::mojom::Role::kDateTime:
  494. case ax::mojom::Role::kGrid:
  495. case ax::mojom::Role::kInputTime:
  496. case ax::mojom::Role::kListBox:
  497. case ax::mojom::Role::kMenuItemCheckBox:
  498. case ax::mojom::Role::kMenuItemRadio:
  499. case ax::mojom::Role::kMenuListPopup:
  500. case ax::mojom::Role::kPopUpButton:
  501. case ax::mojom::Role::kRadioButton:
  502. case ax::mojom::Role::kRadioGroup:
  503. case ax::mojom::Role::kSearchBox:
  504. case ax::mojom::Role::kSlider:
  505. case ax::mojom::Role::kSpinButton:
  506. case ax::mojom::Role::kSwitch:
  507. case ax::mojom::Role::kTextField:
  508. case ax::mojom::Role::kTextFieldWithComboBox:
  509. case ax::mojom::Role::kTreeGrid:
  510. return true;
  511. // https://www.w3.org/TR/wai-aria-1.1/#aria-readonly
  512. // ARIA-1.1+ 'gridcell', supports aria-readonly, but 'cell' does not.
  513. //
  514. // https://www.w3.org/TR/wai-aria-1.1/#columnheader
  515. // https://www.w3.org/TR/wai-aria-1.1/#rowheader
  516. // While the [columnheader|rowheader] role can be used in both interactive
  517. // grids and non-interactive tables, the use of aria-readonly and
  518. // aria-required is only applicable to interactive elements.
  519. // Therefore, [...] user agents SHOULD NOT expose either property to
  520. // assistive technologies unless the columnheader descends from a grid.
  521. case ax::mojom::Role::kCell:
  522. case ax::mojom::Role::kColumnHeader:
  523. case ax::mojom::Role::kMathMLTableCell:
  524. case ax::mojom::Role::kRowHeader:
  525. return false;
  526. default:
  527. return false;
  528. }
  529. }
  530. bool IsRootLike(ax::mojom::Role role) {
  531. if (IsDialog(role) || IsPlatformDocument(role))
  532. return true;
  533. switch (role) {
  534. case ax::mojom::Role::kDesktop:
  535. case ax::mojom::Role::kWindow:
  536. return true;
  537. default:
  538. return false;
  539. }
  540. }
  541. bool IsRowContainer(const ax::mojom::Role role) {
  542. switch (role) {
  543. case ax::mojom::Role::kGrid:
  544. case ax::mojom::Role::kListGrid:
  545. case ax::mojom::Role::kTable:
  546. case ax::mojom::Role::kTree:
  547. case ax::mojom::Role::kTreeGrid:
  548. return true;
  549. case ax::mojom::Role::kLayoutTable:
  550. return kExposeLayoutTableAsDataTable;
  551. default:
  552. return false;
  553. }
  554. }
  555. bool IsSection(const ax::mojom::Role role) {
  556. if (IsLandmark(role) || IsSelect(role))
  557. return true;
  558. switch (role) {
  559. case ax::mojom::Role::kAlert:
  560. case ax::mojom::Role::kAlertDialog: // Subclass of kAlert.
  561. case ax::mojom::Role::kCell:
  562. case ax::mojom::Role::kColumnHeader: // Subclass of kCell.
  563. case ax::mojom::Role::kDefinition:
  564. case ax::mojom::Role::kDirectory: // Subclass of kList.
  565. case ax::mojom::Role::kFeed: // Subclass of kList.
  566. case ax::mojom::Role::kFigure:
  567. case ax::mojom::Role::kGrid: // Subclass of kTable.
  568. case ax::mojom::Role::kGroup:
  569. case ax::mojom::Role::kImage:
  570. case ax::mojom::Role::kList:
  571. case ax::mojom::Role::kListItem:
  572. case ax::mojom::Role::kLog:
  573. case ax::mojom::Role::kMarquee:
  574. case ax::mojom::Role::kMath:
  575. case ax::mojom::Role::kMathMLMath:
  576. case ax::mojom::Role::kMathMLTableCell:
  577. case ax::mojom::Role::kNote:
  578. case ax::mojom::Role::kProgressIndicator: // Subclass of kStatus.
  579. case ax::mojom::Role::kRow: // Subclass of kGroup.
  580. case ax::mojom::Role::kRowHeader: // Subclass of kCell.
  581. case ax::mojom::Role::kSection:
  582. case ax::mojom::Role::kStatus:
  583. case ax::mojom::Role::kTable:
  584. case ax::mojom::Role::kTabPanel:
  585. case ax::mojom::Role::kTerm:
  586. case ax::mojom::Role::kTimer: // Subclass of kStatus.
  587. case ax::mojom::Role::kToolbar: // Subclass of kGroup.
  588. case ax::mojom::Role::kTooltip:
  589. case ax::mojom::Role::kTreeItem: // Subclass of kListItem.
  590. return true;
  591. default:
  592. return false;
  593. }
  594. }
  595. bool IsSectionhead(const ax::mojom::Role role) {
  596. switch (role) {
  597. case ax::mojom::Role::kColumnHeader:
  598. case ax::mojom::Role::kHeading:
  599. case ax::mojom::Role::kRowHeader:
  600. case ax::mojom::Role::kTab:
  601. return true;
  602. default:
  603. return false;
  604. }
  605. }
  606. bool IsSelect(const ax::mojom::Role role) {
  607. switch (role) {
  608. case ax::mojom::Role::kComboBoxGrouping:
  609. case ax::mojom::Role::kListBox:
  610. case ax::mojom::Role::kMenu:
  611. case ax::mojom::Role::kMenuBar: // Subclass of kMenu.
  612. case ax::mojom::Role::kRadioGroup:
  613. case ax::mojom::Role::kTree:
  614. case ax::mojom::Role::kTreeGrid: // Subclass of kTree.
  615. return true;
  616. default:
  617. return false;
  618. }
  619. }
  620. bool IsSelectElement(const ax::mojom::Role role) {
  621. // Depending on their "size" attribute, <select> elements come in two flavors:
  622. // the first appears like a list box and the second like a popup menu.
  623. switch (role) {
  624. case ax::mojom::Role::kListBox:
  625. case ax::mojom::Role::kPopUpButton:
  626. return true;
  627. default:
  628. return false;
  629. }
  630. }
  631. bool IsSelectRequiredOrImplicit(const ax::mojom::Role role) {
  632. switch (role) {
  633. case ax::mojom::Role::kListBoxOption:
  634. case ax::mojom::Role::kMenuListOption:
  635. case ax::mojom::Role::kTab:
  636. case ax::mojom::Role::kTreeItem:
  637. return true;
  638. default:
  639. return false;
  640. }
  641. }
  642. bool IsSelectSupported(const ax::mojom::Role role) {
  643. switch (role) {
  644. case ax::mojom::Role::kCell:
  645. case ax::mojom::Role::kColumnHeader:
  646. case ax::mojom::Role::kListBoxOption:
  647. case ax::mojom::Role::kMathMLTableCell:
  648. case ax::mojom::Role::kMenuListOption:
  649. case ax::mojom::Role::kRow:
  650. case ax::mojom::Role::kRowHeader:
  651. case ax::mojom::Role::kTab:
  652. case ax::mojom::Role::kTreeItem:
  653. return true;
  654. default:
  655. return false;
  656. }
  657. }
  658. bool IsSetLike(const ax::mojom::Role role) {
  659. switch (role) {
  660. case ax::mojom::Role::kDescriptionList:
  661. case ax::mojom::Role::kDirectory:
  662. case ax::mojom::Role::kDocBibliography:
  663. case ax::mojom::Role::kFeed:
  664. case ax::mojom::Role::kGroup:
  665. case ax::mojom::Role::kList:
  666. case ax::mojom::Role::kListBox:
  667. case ax::mojom::Role::kListGrid:
  668. case ax::mojom::Role::kMenu:
  669. case ax::mojom::Role::kMenuBar:
  670. case ax::mojom::Role::kMenuListPopup:
  671. case ax::mojom::Role::kPopUpButton:
  672. case ax::mojom::Role::kRadioGroup:
  673. case ax::mojom::Role::kTabList:
  674. case ax::mojom::Role::kTree:
  675. case ax::mojom::Role::kTreeGrid:
  676. return true;
  677. default:
  678. return false;
  679. }
  680. }
  681. bool IsStaticList(const ax::mojom::Role role) {
  682. switch (role) {
  683. case ax::mojom::Role::kList:
  684. case ax::mojom::Role::kDescriptionList:
  685. return true;
  686. default:
  687. return false;
  688. }
  689. }
  690. bool IsStructure(const ax::mojom::Role role) {
  691. if (IsSection(role) || IsSectionhead(role) || IsPresentational(role))
  692. return true;
  693. switch (role) {
  694. case ax::mojom::Role::kApplication:
  695. case ax::mojom::Role::kDocument:
  696. case ax::mojom::Role::kArticle: // Subclass of kDocument.
  697. case ax::mojom::Role::kRowGroup:
  698. case ax::mojom::Role::kSplitter:
  699. // Dpub roles.
  700. case ax::mojom::Role::kDocAbstract:
  701. case ax::mojom::Role::kDocAcknowledgments:
  702. case ax::mojom::Role::kDocAfterword:
  703. case ax::mojom::Role::kDocAppendix:
  704. case ax::mojom::Role::kDocBiblioEntry:
  705. case ax::mojom::Role::kDocBibliography:
  706. case ax::mojom::Role::kDocChapter:
  707. case ax::mojom::Role::kDocColophon:
  708. case ax::mojom::Role::kDocConclusion:
  709. case ax::mojom::Role::kDocCover:
  710. case ax::mojom::Role::kDocCredit:
  711. case ax::mojom::Role::kDocCredits:
  712. case ax::mojom::Role::kDocDedication:
  713. case ax::mojom::Role::kDocEndnote:
  714. case ax::mojom::Role::kDocEndnotes:
  715. case ax::mojom::Role::kDocEpigraph:
  716. case ax::mojom::Role::kDocEpilogue:
  717. case ax::mojom::Role::kDocErrata:
  718. case ax::mojom::Role::kDocExample:
  719. case ax::mojom::Role::kDocFootnote:
  720. case ax::mojom::Role::kDocForeword:
  721. case ax::mojom::Role::kDocGlossary:
  722. case ax::mojom::Role::kDocIndex:
  723. case ax::mojom::Role::kDocIntroduction:
  724. case ax::mojom::Role::kDocNotice:
  725. case ax::mojom::Role::kDocPageBreak:
  726. case ax::mojom::Role::kDocPageList:
  727. case ax::mojom::Role::kDocPart:
  728. case ax::mojom::Role::kDocPreface:
  729. case ax::mojom::Role::kDocPrologue:
  730. case ax::mojom::Role::kDocQna:
  731. case ax::mojom::Role::kDocSubtitle:
  732. case ax::mojom::Role::kDocTip:
  733. case ax::mojom::Role::kDocToc:
  734. return true;
  735. default:
  736. return false;
  737. }
  738. }
  739. bool IsTableColumn(ax::mojom::Role role) {
  740. return role == ax::mojom::Role::kColumn;
  741. }
  742. bool IsTableHeader(ax::mojom::Role role) {
  743. switch (role) {
  744. case ax::mojom::Role::kColumnHeader:
  745. case ax::mojom::Role::kRowHeader:
  746. return true;
  747. default:
  748. return false;
  749. }
  750. }
  751. bool IsTableItem(ax::mojom::Role role) {
  752. switch (role) {
  753. case ax::mojom::Role::kDescriptionListTerm:
  754. case ax::mojom::Role::kListBoxOption:
  755. case ax::mojom::Role::kListItem:
  756. case ax::mojom::Role::kTreeItem:
  757. return true;
  758. default:
  759. return IsCellOrTableHeader(role);
  760. }
  761. }
  762. #if BUILDFLAG(IS_ANDROID)
  763. bool IsTableLike(const ax::mojom::Role role) {
  764. switch (role) {
  765. case ax::mojom::Role::kGrid:
  766. case ax::mojom::Role::kDescriptionList:
  767. case ax::mojom::Role::kDirectory:
  768. case ax::mojom::Role::kList:
  769. case ax::mojom::Role::kListBox:
  770. case ax::mojom::Role::kListGrid:
  771. case ax::mojom::Role::kTable:
  772. case ax::mojom::Role::kTree:
  773. case ax::mojom::Role::kTreeGrid:
  774. return true;
  775. default:
  776. return false;
  777. }
  778. }
  779. #else
  780. bool IsTableLike(const ax::mojom::Role role) {
  781. switch (role) {
  782. case ax::mojom::Role::kGrid:
  783. case ax::mojom::Role::kListGrid:
  784. case ax::mojom::Role::kTable:
  785. case ax::mojom::Role::kTreeGrid:
  786. return true;
  787. case ax::mojom::Role::kLayoutTable:
  788. return kExposeLayoutTableAsDataTable;
  789. default:
  790. return false;
  791. }
  792. }
  793. #endif
  794. bool IsTableRow(ax::mojom::Role role) {
  795. switch (role) {
  796. case ax::mojom::Role::kRow:
  797. return true;
  798. case ax::mojom::Role::kLayoutTableRow:
  799. return kExposeLayoutTableAsDataTable;
  800. default:
  801. return false;
  802. }
  803. }
  804. bool IsText(ax::mojom::Role role) {
  805. switch (role) {
  806. case ax::mojom::Role::kInlineTextBox:
  807. case ax::mojom::Role::kLineBreak:
  808. case ax::mojom::Role::kStaticText:
  809. return true;
  810. default:
  811. return false;
  812. }
  813. }
  814. bool IsTextField(ax::mojom::Role role) {
  815. switch (role) {
  816. case ax::mojom::Role::kSearchBox:
  817. case ax::mojom::Role::kTextField:
  818. case ax::mojom::Role::kTextFieldWithComboBox:
  819. return true;
  820. default:
  821. return false;
  822. }
  823. }
  824. bool IsUIAEmbeddedObject(ax::mojom::Role role) {
  825. // A UIA embedded object "is any element that has non-textual boundaries such
  826. // as an image, hyperlink, table", etc. For more info, see
  827. // https://docs.microsoft.com/en-us/windows/win32/winauto/uiauto-textpattern-and-embedded-objects-overview.
  828. switch (role) {
  829. case ax::mojom::Role::kButton:
  830. case ax::mojom::Role::kCanvas:
  831. case ax::mojom::Role::kCell:
  832. case ax::mojom::Role::kCheckBox:
  833. case ax::mojom::Role::kColorWell:
  834. case ax::mojom::Role::kColumn:
  835. case ax::mojom::Role::kColumnHeader:
  836. case ax::mojom::Role::kComboBoxGrouping:
  837. case ax::mojom::Role::kComboBoxMenuButton:
  838. case ax::mojom::Role::kDate:
  839. case ax::mojom::Role::kDateTime:
  840. case ax::mojom::Role::kDescriptionList:
  841. case ax::mojom::Role::kDescriptionListTerm:
  842. case ax::mojom::Role::kDirectory:
  843. case ax::mojom::Role::kDisclosureTriangle:
  844. case ax::mojom::Role::kDocBackLink:
  845. case ax::mojom::Role::kDocBiblioEntry:
  846. case ax::mojom::Role::kDocBiblioRef:
  847. case ax::mojom::Role::kDocBibliography:
  848. case ax::mojom::Role::kDocCover:
  849. case ax::mojom::Role::kDocEndnote:
  850. case ax::mojom::Role::kDocGlossRef:
  851. case ax::mojom::Role::kDocNoteRef:
  852. case ax::mojom::Role::kForm:
  853. case ax::mojom::Role::kGraphicsSymbol:
  854. case ax::mojom::Role::kGrid:
  855. case ax::mojom::Role::kIframe:
  856. case ax::mojom::Role::kIframePresentational:
  857. case ax::mojom::Role::kImage:
  858. case ax::mojom::Role::kInputTime:
  859. case ax::mojom::Role::kLink:
  860. case ax::mojom::Role::kList:
  861. case ax::mojom::Role::kListBox:
  862. case ax::mojom::Role::kListBoxOption:
  863. case ax::mojom::Role::kListGrid:
  864. case ax::mojom::Role::kListItem:
  865. case ax::mojom::Role::kMenu:
  866. case ax::mojom::Role::kMenuBar:
  867. case ax::mojom::Role::kMenuItem:
  868. case ax::mojom::Role::kMenuItemCheckBox:
  869. case ax::mojom::Role::kMenuItemRadio:
  870. case ax::mojom::Role::kMenuListOption:
  871. case ax::mojom::Role::kMenuListPopup:
  872. case ax::mojom::Role::kMeter:
  873. case ax::mojom::Role::kPdfActionableHighlight:
  874. case ax::mojom::Role::kPopUpButton:
  875. case ax::mojom::Role::kProgressIndicator:
  876. case ax::mojom::Role::kRadioButton:
  877. case ax::mojom::Role::kRadioGroup:
  878. case ax::mojom::Role::kRow:
  879. case ax::mojom::Role::kRowHeader:
  880. case ax::mojom::Role::kScrollBar:
  881. case ax::mojom::Role::kSearchBox:
  882. case ax::mojom::Role::kSlider:
  883. case ax::mojom::Role::kSpinButton:
  884. case ax::mojom::Role::kSplitter:
  885. case ax::mojom::Role::kSvgRoot:
  886. case ax::mojom::Role::kSwitch:
  887. case ax::mojom::Role::kTab:
  888. case ax::mojom::Role::kTabList:
  889. case ax::mojom::Role::kTable:
  890. case ax::mojom::Role::kTerm:
  891. case ax::mojom::Role::kTextField:
  892. case ax::mojom::Role::kTextFieldWithComboBox:
  893. case ax::mojom::Role::kToggleButton:
  894. case ax::mojom::Role::kToolbar:
  895. case ax::mojom::Role::kTree:
  896. case ax::mojom::Role::kTreeGrid:
  897. case ax::mojom::Role::kTreeItem:
  898. case ax::mojom::Role::kVideo:
  899. return true;
  900. case ax::mojom::Role::kLayoutTableCell:
  901. return kExposeLayoutTableAsDataTable;
  902. default:
  903. return false;
  904. }
  905. }
  906. bool IsUIATableLike(ax::mojom::Role role) {
  907. if (role == ax::mojom::Role::kLayoutTable)
  908. return false;
  909. return IsTableLike(role);
  910. }
  911. bool IsUIACellOrTableHeader(ax::mojom::Role role) {
  912. if (role == ax::mojom::Role::kLayoutTableCell)
  913. return false;
  914. return IsCellOrTableHeader(role);
  915. }
  916. bool IsWindow(ax::mojom::Role role) {
  917. switch (role) {
  918. case ax::mojom::Role::kWindow:
  919. return true;
  920. default:
  921. return false;
  922. }
  923. }
  924. bool ShouldHaveReadonlyStateByDefault(const ax::mojom::Role role) {
  925. switch (role) {
  926. case ax::mojom::Role::kArticle:
  927. case ax::mojom::Role::kDefinition:
  928. case ax::mojom::Role::kDescriptionList:
  929. case ax::mojom::Role::kDescriptionListTerm:
  930. case ax::mojom::Role::kDirectory:
  931. case ax::mojom::Role::kDocument:
  932. case ax::mojom::Role::kGraphicsDocument:
  933. case ax::mojom::Role::kImage:
  934. case ax::mojom::Role::kList:
  935. case ax::mojom::Role::kListItem:
  936. case ax::mojom::Role::kPdfRoot:
  937. case ax::mojom::Role::kProgressIndicator:
  938. case ax::mojom::Role::kRootWebArea:
  939. case ax::mojom::Role::kTerm:
  940. case ax::mojom::Role::kTimer:
  941. case ax::mojom::Role::kToolbar:
  942. case ax::mojom::Role::kTooltip:
  943. return true;
  944. case ax::mojom::Role::kGrid:
  945. // TODO(aleventhal) this changed between ARIA 1.0 and 1.1.
  946. // We need to determine whether grids/treegrids should really be readonly
  947. // or editable by default.
  948. default:
  949. return false;
  950. }
  951. }
  952. bool SupportsExpandCollapse(const ax::mojom::Role role) {
  953. switch (role) {
  954. case ax::mojom::Role::kComboBoxGrouping:
  955. case ax::mojom::Role::kComboBoxMenuButton:
  956. case ax::mojom::Role::kDisclosureTriangle:
  957. case ax::mojom::Role::kTextFieldWithComboBox:
  958. case ax::mojom::Role::kTreeItem:
  959. return true;
  960. default:
  961. return false;
  962. }
  963. }
  964. bool SupportsHierarchicalLevel(const ax::mojom::Role role) {
  965. switch (role) {
  966. case ax::mojom::Role::kComment:
  967. case ax::mojom::Role::kListItem:
  968. case ax::mojom::Role::kRow:
  969. case ax::mojom::Role::kTreeItem:
  970. return true;
  971. default:
  972. return false;
  973. }
  974. }
  975. bool SupportsOrientation(const ax::mojom::Role role) {
  976. switch (role) {
  977. case ax::mojom::Role::kComboBoxGrouping:
  978. case ax::mojom::Role::kComboBoxMenuButton:
  979. case ax::mojom::Role::kListBox:
  980. case ax::mojom::Role::kMenu:
  981. case ax::mojom::Role::kMenuBar:
  982. case ax::mojom::Role::kRadioGroup:
  983. case ax::mojom::Role::kScrollBar:
  984. case ax::mojom::Role::kSlider:
  985. case ax::mojom::Role::kSplitter:
  986. case ax::mojom::Role::kTabList:
  987. case ax::mojom::Role::kToolbar:
  988. case ax::mojom::Role::kTreeGrid:
  989. case ax::mojom::Role::kTree:
  990. return true;
  991. default:
  992. return false;
  993. }
  994. }
  995. bool SupportsRequired(const ax::mojom::Role role) {
  996. switch (role) {
  997. case ax::mojom::Role::kButton: // Used by the file upload button.
  998. case ax::mojom::Role::kCell: // Used only for grid.
  999. case ax::mojom::Role::kColumnHeader: // Used only for gridheaders.
  1000. case ax::mojom::Role::kComboBoxGrouping:
  1001. case ax::mojom::Role::kCheckBox:
  1002. case ax::mojom::Role::kDate:
  1003. case ax::mojom::Role::kDateTime:
  1004. case ax::mojom::Role::kInputTime:
  1005. case ax::mojom::Role::kListBox:
  1006. case ax::mojom::Role::kRadioButton:
  1007. case ax::mojom::Role::kRadioGroup:
  1008. case ax::mojom::Role::kRowHeader:
  1009. case ax::mojom::Role::kSearchBox:
  1010. case ax::mojom::Role::kSlider:
  1011. case ax::mojom::Role::kSpinButton:
  1012. case ax::mojom::Role::kSwitch:
  1013. case ax::mojom::Role::kTextField:
  1014. case ax::mojom::Role::kTextFieldWithComboBox:
  1015. case ax::mojom::Role::kToggleButton:
  1016. case ax::mojom::Role::kTree:
  1017. case ax::mojom::Role::kTreeGrid:
  1018. return true;
  1019. default:
  1020. return false;
  1021. }
  1022. }
  1023. bool SupportsToggle(const ax::mojom::Role role) {
  1024. switch (role) {
  1025. case ax::mojom::Role::kCheckBox:
  1026. case ax::mojom::Role::kMenuItemCheckBox:
  1027. case ax::mojom::Role::kSwitch:
  1028. case ax::mojom::Role::kToggleButton:
  1029. return true;
  1030. default:
  1031. return false;
  1032. }
  1033. }
  1034. } // namespace ui