Bug 1869092 - Fix timeouts in browser_PanelMultiView.js. r=twisniewski,test-only
[gecko.git] / accessible / base / ARIAMap.cpp
blobf750ac95d53c8b7f92034c1f2d3e7ff355658346
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=2:tabstop=2:
3 */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "ARIAMap.h"
10 #include "AccAttributes.h"
11 #include "nsAccUtils.h"
12 #include "nsCoreUtils.h"
13 #include "mozilla/a11y/Role.h"
14 #include "States.h"
16 #include "nsAttrName.h"
17 #include "nsWhitespaceTokenizer.h"
19 #include "mozilla/BinarySearch.h"
20 #include "mozilla/dom/Element.h"
22 #include "nsUnicharUtils.h"
24 using namespace mozilla;
25 using namespace mozilla::a11y;
26 using namespace mozilla::a11y::aria;
28 static const uint32_t kGenericAccType = 0;
30 /**
31 * This list of WAI-defined roles are currently hardcoded.
32 * Eventually we will most likely be loading an RDF resource that contains this
33 * information Using RDF will also allow for role extensibility. See bug 280138.
35 * Definition of nsRoleMapEntry contains comments explaining this table.
37 * When no Role enum mapping exists for an ARIA role, the role will be exposed
38 * via the object attribute "xml-roles".
40 * Note: the list must remain alphabetically ordered to support binary search.
43 static const nsRoleMapEntry sWAIRoleMaps[] = {
44 // clang-format off
45 { // alert
46 nsGkAtoms::alert,
47 roles::ALERT,
48 kUseMapRole,
49 eNoValue,
50 eNoAction,
51 #if defined(XP_MACOSX)
52 eAssertiveLiveAttr,
53 #else
54 eNoLiveAttr,
55 #endif
56 eAlert,
57 kNoReqStates
59 { // alertdialog
60 nsGkAtoms::alertdialog,
61 roles::DIALOG,
62 kUseMapRole,
63 eNoValue,
64 eNoAction,
65 eNoLiveAttr,
66 kGenericAccType,
67 kNoReqStates
69 { // application
70 nsGkAtoms::application,
71 roles::APPLICATION,
72 kUseMapRole,
73 eNoValue,
74 eNoAction,
75 eNoLiveAttr,
76 eLandmark,
77 kNoReqStates
79 { // article
80 nsGkAtoms::article,
81 roles::ARTICLE,
82 kUseMapRole,
83 eNoValue,
84 eNoAction,
85 eNoLiveAttr,
86 kGenericAccType,
87 kNoReqStates,
88 eReadonlyUntilEditable
90 { // banner
91 nsGkAtoms::banner,
92 roles::LANDMARK,
93 kUseMapRole,
94 eNoValue,
95 eNoAction,
96 eNoLiveAttr,
97 eLandmark,
98 kNoReqStates
100 { // blockquote
101 nsGkAtoms::blockquote,
102 roles::BLOCKQUOTE,
103 kUseMapRole,
104 eNoValue,
105 eNoAction,
106 eNoLiveAttr,
107 kGenericAccType,
109 { // button
110 nsGkAtoms::button,
111 roles::PUSHBUTTON,
112 kUseMapRole,
113 eNoValue,
114 ePressAction,
115 eNoLiveAttr,
116 eButton,
117 kNoReqStates
118 // eARIAPressed is auto applied on any button
120 { // caption
121 nsGkAtoms::caption,
122 roles::CAPTION,
123 kUseMapRole,
124 eNoValue,
125 eNoAction,
126 eNoLiveAttr,
127 kGenericAccType,
129 { // cell
130 nsGkAtoms::cell,
131 roles::CELL,
132 kUseMapRole,
133 eNoValue,
134 eNoAction,
135 eNoLiveAttr,
136 eTableCell,
137 kNoReqStates
139 { // checkbox
140 nsGkAtoms::checkbox,
141 roles::CHECKBUTTON,
142 kUseMapRole,
143 eNoValue,
144 eCheckUncheckAction,
145 eNoLiveAttr,
146 kGenericAccType,
147 kNoReqStates,
148 eARIACheckableMixed,
149 eARIAReadonly
151 { // code
152 nsGkAtoms::code,
153 roles::CODE,
154 kUseMapRole,
155 eNoValue,
156 eNoAction,
157 eNoLiveAttr,
158 kGenericAccType,
160 { // columnheader
161 nsGkAtoms::columnheader,
162 roles::COLUMNHEADER,
163 kUseMapRole,
164 eNoValue,
165 eSortAction,
166 eNoLiveAttr,
167 eTableCell,
168 kNoReqStates,
169 eARIASelectableIfDefined,
170 eARIAReadonly
172 { // combobox, which consists of text input and popup
173 nsGkAtoms::combobox,
174 roles::EDITCOMBOBOX,
175 kUseMapRole,
176 eNoValue,
177 eOpenCloseAction,
178 eNoLiveAttr,
179 eCombobox,
180 states::COLLAPSED | states::HASPOPUP,
181 eARIAAutoComplete,
182 eARIAReadonly,
183 eARIAOrientation
185 { // comment
186 nsGkAtoms::comment,
187 roles::COMMENT,
188 kUseMapRole,
189 eNoValue,
190 eNoAction,
191 eNoLiveAttr,
192 kGenericAccType,
194 { // complementary
195 nsGkAtoms::complementary,
196 roles::LANDMARK,
197 kUseMapRole,
198 eNoValue,
199 eNoAction,
200 eNoLiveAttr,
201 eLandmark,
202 kNoReqStates
204 { // contentinfo
205 nsGkAtoms::contentinfo,
206 roles::LANDMARK,
207 kUseMapRole,
208 eNoValue,
209 eNoAction,
210 eNoLiveAttr,
211 eLandmark,
212 kNoReqStates
214 { // deletion
215 nsGkAtoms::deletion,
216 roles::CONTENT_DELETION,
217 kUseMapRole,
218 eNoValue,
219 eNoAction,
220 eNoLiveAttr,
221 kGenericAccType,
223 { // dialog
224 nsGkAtoms::dialog,
225 roles::DIALOG,
226 kUseMapRole,
227 eNoValue,
228 eNoAction,
229 eNoLiveAttr,
230 kGenericAccType,
231 kNoReqStates
233 { // directory
234 nsGkAtoms::directory,
235 roles::LIST,
236 kUseMapRole,
237 eNoValue,
238 eNoAction,
239 eNoLiveAttr,
240 eList,
241 states::READONLY
243 { // doc-abstract
244 nsGkAtoms::docAbstract,
245 roles::SECTION,
246 kUseMapRole,
247 eNoValue,
248 eNoAction,
249 eNoLiveAttr,
250 kGenericAccType,
251 kNoReqStates
253 { // doc-acknowledgments
254 nsGkAtoms::docAcknowledgments,
255 roles::LANDMARK,
256 kUseMapRole,
257 eNoValue,
258 eNoAction,
259 eNoLiveAttr,
260 eLandmark,
261 kNoReqStates
263 { // doc-afterword
264 nsGkAtoms::docAfterword,
265 roles::LANDMARK,
266 kUseMapRole,
267 eNoValue,
268 eNoAction,
269 eNoLiveAttr,
270 eLandmark,
271 kNoReqStates
273 { // doc-appendix
274 nsGkAtoms::docAppendix,
275 roles::LANDMARK,
276 kUseMapRole,
277 eNoValue,
278 eNoAction,
279 eNoLiveAttr,
280 eLandmark,
281 kNoReqStates
283 { // doc-backlink
284 nsGkAtoms::docBacklink,
285 roles::LINK,
286 kUseMapRole,
287 eNoValue,
288 eJumpAction,
289 eNoLiveAttr,
290 kGenericAccType,
291 states::LINKED
293 { // doc-biblioentry
294 nsGkAtoms::docBiblioentry,
295 roles::LISTITEM,
296 kUseMapRole,
297 eNoValue,
298 eNoAction,
299 eNoLiveAttr,
300 kGenericAccType,
301 states::READONLY
303 { // doc-bibliography
304 nsGkAtoms::docBibliography,
305 roles::LANDMARK,
306 kUseMapRole,
307 eNoValue,
308 eNoAction,
309 eNoLiveAttr,
310 eLandmark,
311 kNoReqStates
313 { // doc-biblioref
314 nsGkAtoms::docBiblioref,
315 roles::LINK,
316 kUseMapRole,
317 eNoValue,
318 eJumpAction,
319 eNoLiveAttr,
320 kGenericAccType,
321 states::LINKED
323 { // doc-chapter
324 nsGkAtoms::docChapter,
325 roles::LANDMARK,
326 kUseMapRole,
327 eNoValue,
328 eNoAction,
329 eNoLiveAttr,
330 eLandmark,
331 kNoReqStates
333 { // doc-colophon
334 nsGkAtoms::docColophon,
335 roles::SECTION,
336 kUseMapRole,
337 eNoValue,
338 eNoAction,
339 eNoLiveAttr,
340 kGenericAccType,
341 kNoReqStates
343 { // doc-conclusion
344 nsGkAtoms::docConclusion,
345 roles::LANDMARK,
346 kUseMapRole,
347 eNoValue,
348 eNoAction,
349 eNoLiveAttr,
350 eLandmark,
351 kNoReqStates
353 { // doc-cover
354 nsGkAtoms::docCover,
355 roles::GRAPHIC,
356 kUseMapRole,
357 eNoValue,
358 eNoAction,
359 eNoLiveAttr,
360 kGenericAccType,
361 kNoReqStates
363 { // doc-credit
364 nsGkAtoms::docCredit,
365 roles::SECTION,
366 kUseMapRole,
367 eNoValue,
368 eNoAction,
369 eNoLiveAttr,
370 kGenericAccType,
371 kNoReqStates
373 { // doc-credits
374 nsGkAtoms::docCredits,
375 roles::LANDMARK,
376 kUseMapRole,
377 eNoValue,
378 eNoAction,
379 eNoLiveAttr,
380 eLandmark,
381 kNoReqStates
383 { // doc-dedication
384 nsGkAtoms::docDedication,
385 roles::SECTION,
386 kUseMapRole,
387 eNoValue,
388 eNoAction,
389 eNoLiveAttr,
390 kGenericAccType,
391 kNoReqStates
393 { // doc-endnote
394 nsGkAtoms::docEndnote,
395 roles::LISTITEM,
396 kUseMapRole,
397 eNoValue,
398 eNoAction,
399 eNoLiveAttr,
400 kGenericAccType,
401 states::READONLY
403 { // doc-endnotes
404 nsGkAtoms::docEndnotes,
405 roles::LANDMARK,
406 kUseMapRole,
407 eNoValue,
408 eNoAction,
409 eNoLiveAttr,
410 eLandmark,
411 kNoReqStates
413 { // doc-epigraph
414 nsGkAtoms::docEpigraph,
415 roles::SECTION,
416 kUseMapRole,
417 eNoValue,
418 eNoAction,
419 eNoLiveAttr,
420 kGenericAccType,
421 kNoReqStates
423 { // doc-epilogue
424 nsGkAtoms::docEpilogue,
425 roles::LANDMARK,
426 kUseMapRole,
427 eNoValue,
428 eNoAction,
429 eNoLiveAttr,
430 eLandmark,
431 kNoReqStates
433 { // doc-errata
434 nsGkAtoms::docErrata,
435 roles::LANDMARK,
436 kUseMapRole,
437 eNoValue,
438 eNoAction,
439 eNoLiveAttr,
440 eLandmark,
441 kNoReqStates
443 { // doc-example
444 nsGkAtoms::docExample,
445 roles::SECTION,
446 kUseMapRole,
447 eNoValue,
448 eNoAction,
449 eNoLiveAttr,
450 kGenericAccType,
451 kNoReqStates
453 { // doc-footnote
454 nsGkAtoms::docFootnote,
455 roles::FOOTNOTE,
456 kUseMapRole,
457 eNoValue,
458 eNoAction,
459 eNoLiveAttr,
460 eLandmark,
461 kNoReqStates
463 { // doc-foreword
464 nsGkAtoms::docForeword,
465 roles::LANDMARK,
466 kUseMapRole,
467 eNoValue,
468 eNoAction,
469 eNoLiveAttr,
470 eLandmark,
471 kNoReqStates
473 { // doc-glossary
474 nsGkAtoms::docGlossary,
475 roles::LANDMARK,
476 kUseMapRole,
477 eNoValue,
478 eNoAction,
479 eNoLiveAttr,
480 eLandmark,
481 kNoReqStates
483 { // doc-glossref
484 nsGkAtoms::docGlossref,
485 roles::LINK,
486 kUseMapRole,
487 eNoValue,
488 eJumpAction,
489 eNoLiveAttr,
490 kGenericAccType,
491 states::LINKED
493 { // doc-index
494 nsGkAtoms::docIndex,
495 roles::NAVIGATION,
496 kUseMapRole,
497 eNoValue,
498 eNoAction,
499 eNoLiveAttr,
500 eLandmark,
501 kNoReqStates
503 { // doc-introduction
504 nsGkAtoms::docIntroduction,
505 roles::LANDMARK,
506 kUseMapRole,
507 eNoValue,
508 eNoAction,
509 eNoLiveAttr,
510 eLandmark,
511 kNoReqStates
513 { // doc-noteref
514 nsGkAtoms::docNoteref,
515 roles::LINK,
516 kUseMapRole,
517 eNoValue,
518 eJumpAction,
519 eNoLiveAttr,
520 kGenericAccType,
521 states::LINKED
523 { // doc-notice
524 nsGkAtoms::docNotice,
525 roles::NOTE,
526 kUseMapRole,
527 eNoValue,
528 eNoAction,
529 eNoLiveAttr,
530 kGenericAccType,
531 kNoReqStates
533 { // doc-pagebreak
534 nsGkAtoms::docPagebreak,
535 roles::SEPARATOR,
536 kUseMapRole,
537 eNoValue,
538 eNoAction,
539 eNoLiveAttr,
540 kGenericAccType,
541 kNoReqStates
543 { // doc-pagelist
544 nsGkAtoms::docPagelist,
545 roles::NAVIGATION,
546 kUseMapRole,
547 eNoValue,
548 eNoAction,
549 eNoLiveAttr,
550 eLandmark,
551 kNoReqStates
553 { // doc-part
554 nsGkAtoms::docPart,
555 roles::LANDMARK,
556 kUseMapRole,
557 eNoValue,
558 eNoAction,
559 eNoLiveAttr,
560 eLandmark,
561 kNoReqStates
563 { // doc-preface
564 nsGkAtoms::docPreface,
565 roles::LANDMARK,
566 kUseMapRole,
567 eNoValue,
568 eNoAction,
569 eNoLiveAttr,
570 eLandmark,
571 kNoReqStates
573 { // doc-prologue
574 nsGkAtoms::docPrologue,
575 roles::LANDMARK,
576 kUseMapRole,
577 eNoValue,
578 eNoAction,
579 eNoLiveAttr,
580 eLandmark,
581 kNoReqStates
583 { // doc-pullquote
584 nsGkAtoms::docPullquote,
585 roles::SECTION,
586 kUseMapRole,
587 eNoValue,
588 eNoAction,
589 eNoLiveAttr,
590 kGenericAccType,
591 kNoReqStates
593 { // doc-qna
594 nsGkAtoms::docQna,
595 roles::SECTION,
596 kUseMapRole,
597 eNoValue,
598 eNoAction,
599 eNoLiveAttr,
600 kGenericAccType,
601 kNoReqStates
603 { // doc-subtitle
604 nsGkAtoms::docSubtitle,
605 roles::HEADING,
606 kUseMapRole,
607 eNoValue,
608 eNoAction,
609 eNoLiveAttr,
610 kGenericAccType,
611 kNoReqStates
613 { // doc-tip
614 nsGkAtoms::docTip,
615 roles::NOTE,
616 kUseMapRole,
617 eNoValue,
618 eNoAction,
619 eNoLiveAttr,
620 kGenericAccType,
621 kNoReqStates
623 { // doc-toc
624 nsGkAtoms::docToc,
625 roles::NAVIGATION,
626 kUseMapRole,
627 eNoValue,
628 eNoAction,
629 eNoLiveAttr,
630 eLandmark,
631 kNoReqStates
633 { // document
634 nsGkAtoms::document,
635 roles::NON_NATIVE_DOCUMENT,
636 kUseMapRole,
637 eNoValue,
638 eNoAction,
639 eNoLiveAttr,
640 kGenericAccType,
641 kNoReqStates,
642 eReadonlyUntilEditable
644 { // feed
645 nsGkAtoms::feed,
646 roles::GROUPING,
647 kUseMapRole,
648 eNoValue,
649 eNoAction,
650 eNoLiveAttr,
651 kGenericAccType,
652 kNoReqStates
654 { // figure
655 nsGkAtoms::figure,
656 roles::FIGURE,
657 kUseMapRole,
658 eNoValue,
659 eNoAction,
660 eNoLiveAttr,
661 kGenericAccType,
662 kNoReqStates
664 { // form
665 nsGkAtoms::form,
666 roles::FORM,
667 kUseMapRole,
668 eNoValue,
669 eNoAction,
670 eNoLiveAttr,
671 eLandmark,
672 kNoReqStates
674 { // graphics-document
675 nsGkAtoms::graphicsDocument,
676 roles::NON_NATIVE_DOCUMENT,
677 kUseMapRole,
678 eNoValue,
679 eNoAction,
680 eNoLiveAttr,
681 kGenericAccType,
682 kNoReqStates,
683 eReadonlyUntilEditable
685 { // graphics-object
686 nsGkAtoms::graphicsObject,
687 roles::GROUPING,
688 kUseMapRole,
689 eNoValue,
690 eNoAction,
691 eNoLiveAttr,
692 kGenericAccType,
693 kNoReqStates
695 { // graphics-symbol
696 nsGkAtoms::graphicsSymbol,
697 roles::GRAPHIC,
698 kUseMapRole,
699 eNoValue,
700 eNoAction,
701 eNoLiveAttr,
702 kGenericAccType,
703 kNoReqStates
705 { // grid
706 nsGkAtoms::grid,
707 roles::TABLE,
708 kUseMapRole,
709 eNoValue,
710 eNoAction,
711 eNoLiveAttr,
712 eSelect | eTable,
713 kNoReqStates,
714 eARIAMultiSelectable,
715 eARIAReadonly,
716 eFocusableUntilDisabled
718 { // gridcell
719 nsGkAtoms::gridcell,
720 roles::GRID_CELL,
721 kUseMapRole,
722 eNoValue,
723 eNoAction,
724 eNoLiveAttr,
725 eTableCell,
726 kNoReqStates,
727 eARIASelectable,
728 eARIAReadonly
730 { // group
731 nsGkAtoms::group,
732 roles::GROUPING,
733 kUseMapRole,
734 eNoValue,
735 eNoAction,
736 eNoLiveAttr,
737 kGenericAccType,
738 kNoReqStates
740 { // heading
741 nsGkAtoms::heading,
742 roles::HEADING,
743 kUseMapRole,
744 eNoValue,
745 eNoAction,
746 eNoLiveAttr,
747 kGenericAccType,
748 kNoReqStates
750 { // image
751 nsGkAtoms::image,
752 roles::GRAPHIC,
753 kUseMapRole,
754 eNoValue,
755 eNoAction,
756 eNoLiveAttr,
757 kGenericAccType,
758 kNoReqStates
760 { // img
761 nsGkAtoms::img,
762 roles::GRAPHIC,
763 kUseMapRole,
764 eNoValue,
765 eNoAction,
766 eNoLiveAttr,
767 kGenericAccType,
768 kNoReqStates
770 { // insertion
771 nsGkAtoms::insertion,
772 roles::CONTENT_INSERTION,
773 kUseMapRole,
774 eNoValue,
775 eNoAction,
776 eNoLiveAttr,
777 kGenericAccType,
779 { // key
780 nsGkAtoms::key,
781 roles::KEY,
782 kUseMapRole,
783 eNoValue,
784 ePressAction,
785 eNoLiveAttr,
786 kGenericAccType,
787 kNoReqStates,
788 eARIAPressed
790 { // link
791 nsGkAtoms::link,
792 roles::LINK,
793 kUseMapRole,
794 eNoValue,
795 eJumpAction,
796 eNoLiveAttr,
797 kGenericAccType,
798 states::LINKED
800 { // list
801 nsGkAtoms::list_,
802 roles::LIST,
803 kUseMapRole,
804 eNoValue,
805 eNoAction,
806 eNoLiveAttr,
807 eList,
808 states::READONLY
810 { // listbox
811 nsGkAtoms::listbox,
812 roles::LISTBOX,
813 kUseMapRole,
814 eNoValue,
815 eNoAction,
816 eNoLiveAttr,
817 eListControl | eSelect,
818 states::VERTICAL,
819 eARIAMultiSelectable,
820 eARIAReadonly,
821 eFocusableUntilDisabled,
822 eARIAOrientation
824 { // listitem
825 nsGkAtoms::listitem,
826 roles::LISTITEM,
827 kUseMapRole,
828 eNoValue,
829 eNoAction, // XXX: should depend on state, parent accessible
830 eNoLiveAttr,
831 kGenericAccType,
832 states::READONLY
834 { // log
835 nsGkAtoms::log_,
836 roles::NOTHING,
837 kUseNativeRole,
838 eNoValue,
839 eNoAction,
840 ePoliteLiveAttr,
841 kGenericAccType,
842 kNoReqStates
844 { // main
845 nsGkAtoms::main,
846 roles::LANDMARK,
847 kUseMapRole,
848 eNoValue,
849 eNoAction,
850 eNoLiveAttr,
851 eLandmark,
852 kNoReqStates
854 { // mark
855 nsGkAtoms::mark,
856 roles::MARK,
857 kUseMapRole,
858 eNoValue,
859 eNoAction,
860 eNoLiveAttr,
861 kGenericAccType,
863 { // marquee
864 nsGkAtoms::marquee,
865 roles::ANIMATION,
866 kUseMapRole,
867 eNoValue,
868 eNoAction,
869 eOffLiveAttr,
870 kGenericAccType,
871 kNoReqStates
873 { // math
874 nsGkAtoms::math,
875 roles::FLAT_EQUATION,
876 kUseMapRole,
877 eNoValue,
878 eNoAction,
879 eNoLiveAttr,
880 kGenericAccType,
881 kNoReqStates
883 { // menu
884 nsGkAtoms::menu,
885 roles::MENUPOPUP,
886 kUseMapRole,
887 eNoValue,
888 eNoAction, // XXX: technically accessibles of menupopup role haven't
889 // any action, but menu can be open or close.
890 eNoLiveAttr,
891 kGenericAccType,
892 states::VERTICAL,
893 eARIAOrientation
895 { // menubar
896 nsGkAtoms::menubar,
897 roles::MENUBAR,
898 kUseMapRole,
899 eNoValue,
900 eNoAction,
901 eNoLiveAttr,
902 kGenericAccType,
903 states::HORIZONTAL,
904 eARIAOrientation
906 { // menuitem
907 nsGkAtoms::menuitem,
908 roles::MENUITEM,
909 kUseMapRole,
910 eNoValue,
911 eClickAction,
912 eNoLiveAttr,
913 kGenericAccType,
914 kNoReqStates
916 { // menuitemcheckbox
917 nsGkAtoms::menuitemcheckbox,
918 roles::CHECK_MENU_ITEM,
919 kUseMapRole,
920 eNoValue,
921 eClickAction,
922 eNoLiveAttr,
923 kGenericAccType,
924 kNoReqStates,
925 eARIACheckableMixed,
926 eARIAReadonly
928 { // menuitemradio
929 nsGkAtoms::menuitemradio,
930 roles::RADIO_MENU_ITEM,
931 kUseMapRole,
932 eNoValue,
933 eClickAction,
934 eNoLiveAttr,
935 kGenericAccType,
936 kNoReqStates,
937 eARIACheckableBool,
938 eARIAReadonly
940 { // meter
941 nsGkAtoms::meter,
942 roles::METER,
943 kUseMapRole,
944 eHasValueMinMax,
945 eNoAction,
946 eNoLiveAttr,
947 kGenericAccType,
948 states::READONLY
950 { // navigation
951 nsGkAtoms::navigation,
952 roles::LANDMARK,
953 kUseMapRole,
954 eNoValue,
955 eNoAction,
956 eNoLiveAttr,
957 eLandmark,
958 kNoReqStates
960 { // none
961 nsGkAtoms::none,
962 roles::NOTHING,
963 kUseMapRole,
964 eNoValue,
965 eNoAction,
966 eNoLiveAttr,
967 kGenericAccType,
968 kNoReqStates
970 { // note
971 nsGkAtoms::note_,
972 roles::NOTE,
973 kUseMapRole,
974 eNoValue,
975 eNoAction,
976 eNoLiveAttr,
977 kGenericAccType,
978 kNoReqStates
980 { // option
981 nsGkAtoms::option,
982 roles::OPTION,
983 kUseMapRole,
984 eNoValue,
985 eSelectAction,
986 eNoLiveAttr,
987 kGenericAccType,
988 kNoReqStates,
989 eARIASelectable,
990 eARIACheckedMixed
992 { // paragraph
993 nsGkAtoms::paragraph,
994 roles::PARAGRAPH,
995 kUseMapRole,
996 eNoValue,
997 eNoAction,
998 eNoLiveAttr,
999 kGenericAccType,
1001 { // presentation
1002 nsGkAtoms::presentation,
1003 roles::NOTHING,
1004 kUseMapRole,
1005 eNoValue,
1006 eNoAction,
1007 eNoLiveAttr,
1008 kGenericAccType,
1009 kNoReqStates
1011 { // progressbar
1012 nsGkAtoms::progressbar,
1013 roles::PROGRESSBAR,
1014 kUseMapRole,
1015 eHasValueMinMax,
1016 eNoAction,
1017 eNoLiveAttr,
1018 kGenericAccType,
1019 states::READONLY,
1020 eIndeterminateIfNoValue
1022 { // radio
1023 nsGkAtoms::radio,
1024 roles::RADIOBUTTON,
1025 kUseMapRole,
1026 eNoValue,
1027 eSelectAction,
1028 eNoLiveAttr,
1029 kGenericAccType,
1030 kNoReqStates,
1031 eARIACheckableBool
1033 { // radiogroup
1034 nsGkAtoms::radiogroup,
1035 roles::RADIO_GROUP,
1036 kUseMapRole,
1037 eNoValue,
1038 eNoAction,
1039 eNoLiveAttr,
1040 kGenericAccType,
1041 kNoReqStates,
1042 eARIAOrientation,
1043 eARIAReadonly
1045 { // region
1046 nsGkAtoms::region,
1047 roles::REGION,
1048 kUseMapRole,
1049 eNoValue,
1050 eNoAction,
1051 eNoLiveAttr,
1052 eLandmark,
1053 kNoReqStates
1055 { // row
1056 nsGkAtoms::row,
1057 roles::ROW,
1058 kUseMapRole,
1059 eNoValue,
1060 eNoAction,
1061 eNoLiveAttr,
1062 eTableRow,
1063 kNoReqStates,
1064 eARIASelectable
1066 { // rowgroup
1067 nsGkAtoms::rowgroup,
1068 roles::GROUPING,
1069 kUseMapRole,
1070 eNoValue,
1071 eNoAction,
1072 eNoLiveAttr,
1073 kGenericAccType,
1074 kNoReqStates
1076 { // rowheader
1077 nsGkAtoms::rowheader,
1078 roles::ROWHEADER,
1079 kUseMapRole,
1080 eNoValue,
1081 eSortAction,
1082 eNoLiveAttr,
1083 eTableCell,
1084 kNoReqStates,
1085 eARIASelectableIfDefined,
1086 eARIAReadonly
1088 { // scrollbar
1089 nsGkAtoms::scrollbar,
1090 roles::SCROLLBAR,
1091 kUseMapRole,
1092 eHasValueMinMax,
1093 eNoAction,
1094 eNoLiveAttr,
1095 kGenericAccType,
1096 states::VERTICAL,
1097 eARIAOrientation,
1098 eARIAReadonly
1100 { // search
1101 nsGkAtoms::search,
1102 roles::LANDMARK,
1103 kUseMapRole,
1104 eNoValue,
1105 eNoAction,
1106 eNoLiveAttr,
1107 eLandmark,
1108 kNoReqStates
1110 { // searchbox
1111 nsGkAtoms::searchbox,
1112 roles::ENTRY,
1113 kUseMapRole,
1114 eNoValue,
1115 eActivateAction,
1116 eNoLiveAttr,
1117 kGenericAccType,
1118 kNoReqStates,
1119 eARIAAutoComplete,
1120 eARIAMultiline,
1121 eARIAReadonlyOrEditable
1123 { // separator
1124 nsGkAtoms::separator_,
1125 roles::SEPARATOR,
1126 kUseMapRole,
1127 eHasValueMinMaxIfFocusable,
1128 eNoAction,
1129 eNoLiveAttr,
1130 kGenericAccType,
1131 states::HORIZONTAL,
1132 eARIAOrientation
1134 { // slider
1135 nsGkAtoms::slider,
1136 roles::SLIDER,
1137 kUseMapRole,
1138 eHasValueMinMax,
1139 eNoAction,
1140 eNoLiveAttr,
1141 kGenericAccType,
1142 states::HORIZONTAL,
1143 eARIAOrientation,
1144 eARIAReadonly
1146 { // spinbutton
1147 nsGkAtoms::spinbutton,
1148 roles::SPINBUTTON,
1149 kUseMapRole,
1150 eHasValueMinMax,
1151 eNoAction,
1152 eNoLiveAttr,
1153 kGenericAccType,
1154 kNoReqStates,
1155 eARIAReadonly
1157 { // status
1158 nsGkAtoms::status,
1159 roles::STATUSBAR,
1160 kUseMapRole,
1161 eNoValue,
1162 eNoAction,
1163 ePoliteLiveAttr,
1164 kGenericAccType,
1165 kNoReqStates
1167 { // subscript
1168 nsGkAtoms::subscript,
1169 roles::SUBSCRIPT,
1170 kUseMapRole,
1171 eNoValue,
1172 eNoAction,
1173 eNoLiveAttr,
1174 kGenericAccType
1176 { // suggestion
1177 nsGkAtoms::suggestion,
1178 roles::SUGGESTION,
1179 kUseMapRole,
1180 eNoValue,
1181 eNoAction,
1182 eNoLiveAttr,
1183 kGenericAccType,
1185 { // superscript
1186 nsGkAtoms::superscript,
1187 roles::SUPERSCRIPT,
1188 kUseMapRole,
1189 eNoValue,
1190 eNoAction,
1191 eNoLiveAttr,
1192 kGenericAccType
1194 { // switch
1195 nsGkAtoms::svgSwitch,
1196 roles::SWITCH,
1197 kUseMapRole,
1198 eNoValue,
1199 eCheckUncheckAction,
1200 eNoLiveAttr,
1201 kGenericAccType,
1202 kNoReqStates,
1203 eARIACheckableBool,
1204 eARIAReadonly
1206 { // tab
1207 nsGkAtoms::tab,
1208 roles::PAGETAB,
1209 kUseMapRole,
1210 eNoValue,
1211 eSwitchAction,
1212 eNoLiveAttr,
1213 kGenericAccType,
1214 kNoReqStates,
1215 eARIASelectable
1217 { // table
1218 nsGkAtoms::table,
1219 roles::TABLE,
1220 kUseMapRole,
1221 eNoValue,
1222 eNoAction,
1223 eNoLiveAttr,
1224 eTable,
1225 kNoReqStates,
1226 eARIASelectable
1228 { // tablist
1229 nsGkAtoms::tablist,
1230 roles::PAGETABLIST,
1231 kUseMapRole,
1232 eNoValue,
1233 eNoAction,
1234 eNoLiveAttr,
1235 eSelect,
1236 states::HORIZONTAL,
1237 eARIAOrientation,
1238 eARIAMultiSelectable
1240 { // tabpanel
1241 nsGkAtoms::tabpanel,
1242 roles::PROPERTYPAGE,
1243 kUseMapRole,
1244 eNoValue,
1245 eNoAction,
1246 eNoLiveAttr,
1247 kGenericAccType,
1248 kNoReqStates
1250 { // term
1251 nsGkAtoms::term,
1252 roles::TERM,
1253 kUseMapRole,
1254 eNoValue,
1255 eNoAction,
1256 eNoLiveAttr,
1257 kGenericAccType,
1258 states::READONLY
1260 { // textbox
1261 nsGkAtoms::textbox,
1262 roles::ENTRY,
1263 kUseMapRole,
1264 eNoValue,
1265 eActivateAction,
1266 eNoLiveAttr,
1267 kGenericAccType,
1268 kNoReqStates,
1269 eARIAAutoComplete,
1270 eARIAMultiline,
1271 eARIAReadonlyOrEditable
1273 { // timer
1274 nsGkAtoms::timer,
1275 roles::NOTHING,
1276 kUseNativeRole,
1277 eNoValue,
1278 eNoAction,
1279 eOffLiveAttr,
1280 kNoReqStates
1282 { // toolbar
1283 nsGkAtoms::toolbar,
1284 roles::TOOLBAR,
1285 kUseMapRole,
1286 eNoValue,
1287 eNoAction,
1288 eNoLiveAttr,
1289 kGenericAccType,
1290 states::HORIZONTAL,
1291 eARIAOrientation
1293 { // tooltip
1294 nsGkAtoms::tooltip,
1295 roles::TOOLTIP,
1296 kUseMapRole,
1297 eNoValue,
1298 eNoAction,
1299 eNoLiveAttr,
1300 kGenericAccType,
1301 kNoReqStates
1303 { // tree
1304 nsGkAtoms::tree,
1305 roles::OUTLINE,
1306 kUseMapRole,
1307 eNoValue,
1308 eNoAction,
1309 eNoLiveAttr,
1310 eSelect,
1311 states::VERTICAL,
1312 eARIAReadonly,
1313 eARIAMultiSelectable,
1314 eFocusableUntilDisabled,
1315 eARIAOrientation
1317 { // treegrid
1318 nsGkAtoms::treegrid,
1319 roles::TREE_TABLE,
1320 kUseMapRole,
1321 eNoValue,
1322 eNoAction,
1323 eNoLiveAttr,
1324 eSelect | eTable,
1325 kNoReqStates,
1326 eARIAReadonly,
1327 eARIAMultiSelectable,
1328 eFocusableUntilDisabled,
1329 eARIAOrientation
1331 { // treeitem
1332 nsGkAtoms::treeitem,
1333 roles::OUTLINEITEM,
1334 kUseMapRole,
1335 eNoValue,
1336 eActivateAction, // XXX: should expose second 'expand/collapse' action based
1337 // on states
1338 eNoLiveAttr,
1339 kGenericAccType,
1340 kNoReqStates,
1341 eARIASelectable,
1342 eARIACheckedMixed
1344 // clang-format on
1347 static const nsRoleMapEntry sLandmarkRoleMap = {
1348 nsGkAtoms::_empty, roles::NOTHING, kUseNativeRole, eNoValue,
1349 eNoAction, eNoLiveAttr, kGenericAccType, kNoReqStates};
1351 nsRoleMapEntry aria::gEmptyRoleMap = {
1352 nsGkAtoms::_empty, roles::TEXT_CONTAINER, kUseMapRole, eNoValue,
1353 eNoAction, eNoLiveAttr, kGenericAccType, kNoReqStates};
1356 * Universal (Global) states:
1357 * The following state rules are applied to any accessible element,
1358 * whether there is an ARIA role or not:
1360 static const EStateRule sWAIUnivStateMap[] = {
1361 eARIABusy, eARIACurrent, eARIADisabled,
1362 eARIAExpanded, // Currently under spec review but precedent exists
1363 eARIAHasPopup, // Note this is a tokenised attribute starting in ARIA 1.1
1364 eARIAInvalid, eARIAModal,
1365 eARIARequired, // XXX not global, Bug 553117
1366 eARIANone};
1369 * ARIA attribute map for attribute characteristics.
1370 * @note ARIA attributes that don't have any flags are not included here.
1373 struct AttrCharacteristics {
1374 const nsStaticAtom* const attributeName;
1375 const uint8_t characteristics;
1378 static const AttrCharacteristics gWAIUnivAttrMap[] = {
1379 // clang-format off
1380 {nsGkAtoms::aria_activedescendant, ATTR_BYPASSOBJ },
1381 {nsGkAtoms::aria_atomic, ATTR_BYPASSOBJ_IF_FALSE | ATTR_VALTOKEN | ATTR_GLOBAL },
1382 {nsGkAtoms::aria_busy, ATTR_VALTOKEN | ATTR_GLOBAL },
1383 {nsGkAtoms::aria_checked, ATTR_BYPASSOBJ | ATTR_VALTOKEN }, /* exposes checkable obj attr */
1384 {nsGkAtoms::aria_colcount, ATTR_VALINT },
1385 {nsGkAtoms::aria_colindex, ATTR_VALINT },
1386 {nsGkAtoms::aria_controls, ATTR_BYPASSOBJ | ATTR_GLOBAL },
1387 {nsGkAtoms::aria_current, ATTR_BYPASSOBJ_IF_FALSE | ATTR_VALTOKEN | ATTR_GLOBAL },
1388 {nsGkAtoms::aria_describedby, ATTR_BYPASSOBJ | ATTR_GLOBAL },
1389 // XXX Ideally, aria-description shouldn't expose a description object
1390 // attribute (i.e. it should have ATTR_BYPASSOBJ). However, until the
1391 // description-from attribute is implemented (bug 1726087), clients such as
1392 // NVDA depend on the description object attribute to work out whether the
1393 // accDescription originated from aria-description.
1394 {nsGkAtoms::aria_description, ATTR_GLOBAL },
1395 {nsGkAtoms::aria_details, ATTR_BYPASSOBJ | ATTR_GLOBAL },
1396 {nsGkAtoms::aria_disabled, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
1397 {nsGkAtoms::aria_dropeffect, ATTR_VALTOKEN | ATTR_GLOBAL },
1398 {nsGkAtoms::aria_errormessage, ATTR_BYPASSOBJ | ATTR_GLOBAL },
1399 {nsGkAtoms::aria_expanded, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
1400 {nsGkAtoms::aria_flowto, ATTR_BYPASSOBJ | ATTR_GLOBAL },
1401 {nsGkAtoms::aria_grabbed, ATTR_VALTOKEN | ATTR_GLOBAL },
1402 {nsGkAtoms::aria_haspopup, ATTR_BYPASSOBJ_IF_FALSE | ATTR_VALTOKEN | ATTR_GLOBAL },
1403 {nsGkAtoms::aria_hidden, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL }, /* handled special way */
1404 {nsGkAtoms::aria_invalid, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
1405 {nsGkAtoms::aria_label, ATTR_BYPASSOBJ | ATTR_GLOBAL },
1406 {nsGkAtoms::aria_labelledby, ATTR_BYPASSOBJ | ATTR_GLOBAL },
1407 {nsGkAtoms::aria_level, ATTR_BYPASSOBJ }, /* handled via groupPosition */
1408 {nsGkAtoms::aria_live, ATTR_VALTOKEN | ATTR_GLOBAL },
1409 {nsGkAtoms::aria_modal, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
1410 {nsGkAtoms::aria_multiline, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
1411 {nsGkAtoms::aria_multiselectable, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
1412 {nsGkAtoms::aria_owns, ATTR_BYPASSOBJ | ATTR_GLOBAL },
1413 {nsGkAtoms::aria_orientation, ATTR_VALTOKEN },
1414 {nsGkAtoms::aria_posinset, ATTR_BYPASSOBJ }, /* handled via groupPosition */
1415 {nsGkAtoms::aria_pressed, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
1416 {nsGkAtoms::aria_readonly, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
1417 {nsGkAtoms::aria_relevant, ATTR_GLOBAL },
1418 {nsGkAtoms::aria_required, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
1419 {nsGkAtoms::aria_rowcount, ATTR_VALINT },
1420 {nsGkAtoms::aria_rowindex, ATTR_VALINT },
1421 {nsGkAtoms::aria_selected, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
1422 {nsGkAtoms::aria_setsize, ATTR_BYPASSOBJ }, /* handled via groupPosition */
1423 {nsGkAtoms::aria_sort, ATTR_VALTOKEN },
1424 {nsGkAtoms::aria_valuenow, ATTR_BYPASSOBJ },
1425 {nsGkAtoms::aria_valuemin, ATTR_BYPASSOBJ },
1426 {nsGkAtoms::aria_valuemax, ATTR_BYPASSOBJ },
1427 {nsGkAtoms::aria_valuetext, ATTR_BYPASSOBJ }
1428 // clang-format on
1431 const nsRoleMapEntry* aria::GetRoleMap(dom::Element* aEl) {
1432 return GetRoleMapFromIndex(GetRoleMapIndex(aEl));
1435 uint8_t aria::GetRoleMapIndex(dom::Element* aEl) {
1436 nsAutoString roles;
1437 if (!aEl || !nsAccUtils::GetARIAAttr(aEl, nsGkAtoms::role, roles) ||
1438 roles.IsEmpty()) {
1439 // We treat role="" as if the role attribute is absent (per aria spec:8.1.1)
1440 return NO_ROLE_MAP_ENTRY_INDEX;
1443 nsWhitespaceTokenizer tokenizer(roles);
1444 while (tokenizer.hasMoreTokens()) {
1445 // Do a binary search through table for the next role in role list
1446 const nsDependentSubstring role = tokenizer.nextToken();
1447 size_t idx;
1448 auto comparator = [&role](const nsRoleMapEntry& aEntry) {
1449 return Compare(role, aEntry.ARIARoleString(),
1450 nsCaseInsensitiveStringComparator);
1452 if (BinarySearchIf(sWAIRoleMaps, 0, ArrayLength(sWAIRoleMaps), comparator,
1453 &idx)) {
1454 return idx;
1458 // Always use some entry index if there is a non-empty role string
1459 // To ensure an accessible object is created
1460 return LANDMARK_ROLE_MAP_ENTRY_INDEX;
1463 const nsRoleMapEntry* aria::GetRoleMapFromIndex(uint8_t aRoleMapIndex) {
1464 switch (aRoleMapIndex) {
1465 case NO_ROLE_MAP_ENTRY_INDEX:
1466 return nullptr;
1467 case EMPTY_ROLE_MAP_ENTRY_INDEX:
1468 return &gEmptyRoleMap;
1469 case LANDMARK_ROLE_MAP_ENTRY_INDEX:
1470 return &sLandmarkRoleMap;
1471 default:
1472 return sWAIRoleMaps + aRoleMapIndex;
1476 uint8_t aria::GetIndexFromRoleMap(const nsRoleMapEntry* aRoleMapEntry) {
1477 if (aRoleMapEntry == nullptr) {
1478 return NO_ROLE_MAP_ENTRY_INDEX;
1479 } else if (aRoleMapEntry == &gEmptyRoleMap) {
1480 return EMPTY_ROLE_MAP_ENTRY_INDEX;
1481 } else if (aRoleMapEntry == &sLandmarkRoleMap) {
1482 return LANDMARK_ROLE_MAP_ENTRY_INDEX;
1483 } else {
1484 uint8_t index = aRoleMapEntry - sWAIRoleMaps;
1485 MOZ_ASSERT(aria::IsRoleMapIndexValid(index));
1486 return index;
1490 bool aria::IsRoleMapIndexValid(uint8_t aRoleMapIndex) {
1491 switch (aRoleMapIndex) {
1492 case NO_ROLE_MAP_ENTRY_INDEX:
1493 case EMPTY_ROLE_MAP_ENTRY_INDEX:
1494 case LANDMARK_ROLE_MAP_ENTRY_INDEX:
1495 return true;
1497 return aRoleMapIndex < ArrayLength(sWAIRoleMaps);
1500 uint64_t aria::UniversalStatesFor(mozilla::dom::Element* aElement) {
1501 uint64_t state = 0;
1502 uint32_t index = 0;
1503 while (MapToState(sWAIUnivStateMap[index], aElement, &state)) index++;
1505 return state;
1508 uint8_t aria::AttrCharacteristicsFor(nsAtom* aAtom) {
1509 for (uint32_t i = 0; i < ArrayLength(gWAIUnivAttrMap); i++) {
1510 if (gWAIUnivAttrMap[i].attributeName == aAtom) {
1511 return gWAIUnivAttrMap[i].characteristics;
1515 return 0;
1518 bool aria::HasDefinedARIAHidden(nsIContent* aContent) {
1519 return aContent && aContent->IsElement() &&
1520 nsAccUtils::ARIAAttrValueIs(aContent->AsElement(),
1521 nsGkAtoms::aria_hidden, nsGkAtoms::_true,
1522 eCaseMatters);
1525 ////////////////////////////////////////////////////////////////////////////////
1526 // AttrIterator class
1528 AttrIterator::AttrIterator(nsIContent* aContent)
1529 : mElement(dom::Element::FromNode(aContent)),
1530 mIteratingDefaults(false),
1531 mAttrIdx(0),
1532 mAttrCharacteristics(0) {
1533 mAttrs = mElement ? &mElement->GetAttrs() : nullptr;
1534 mAttrCount = mAttrs ? mAttrs->AttrCount() : 0;
1537 bool AttrIterator::Next() {
1538 while (mAttrIdx < mAttrCount) {
1539 const nsAttrName* attr = mAttrs->GetSafeAttrNameAt(mAttrIdx);
1540 mAttrIdx++;
1541 if (attr->NamespaceEquals(kNameSpaceID_None)) {
1542 mAttrAtom = attr->Atom();
1543 nsDependentAtomString attrStr(mAttrAtom);
1544 if (!StringBeginsWith(attrStr, u"aria-"_ns)) continue; // Not ARIA
1546 if (mIteratingDefaults) {
1547 if (mOverriddenAttrs.Contains(mAttrAtom)) {
1548 continue;
1550 } else {
1551 mOverriddenAttrs.Insert(mAttrAtom);
1554 // AttrCharacteristicsFor has to search for the entry, so cache it here
1555 // rather than having to search again later.
1556 mAttrCharacteristics = aria::AttrCharacteristicsFor(mAttrAtom);
1557 if (mAttrCharacteristics & ATTR_BYPASSOBJ) {
1558 continue; // No need to handle exposing as obj attribute here
1561 if ((mAttrCharacteristics & ATTR_VALTOKEN) &&
1562 !nsAccUtils::HasDefinedARIAToken(mAttrs, mAttrAtom)) {
1563 continue; // only expose token based attributes if they are defined
1566 if ((mAttrCharacteristics & ATTR_BYPASSOBJ_IF_FALSE) &&
1567 mAttrs->AttrValueIs(kNameSpaceID_None, mAttrAtom, nsGkAtoms::_false,
1568 eCaseMatters)) {
1569 continue; // only expose token based attribute if value is not 'false'.
1572 return true;
1576 mAttrCharacteristics = 0;
1577 mAttrAtom = nullptr;
1579 if (const auto* defaults = nsAccUtils::GetARIADefaults(mElement);
1580 !mIteratingDefaults && defaults) {
1581 mIteratingDefaults = true;
1582 mAttrs = defaults;
1583 mAttrCount = mAttrs->AttrCount();
1584 mAttrIdx = 0;
1585 return Next();
1588 return false;
1591 nsAtom* AttrIterator::AttrName() const { return mAttrAtom; }
1593 void AttrIterator::AttrValue(nsAString& aAttrValue) const {
1594 nsAutoString value;
1595 if (mAttrs->GetAttr(mAttrAtom, value)) {
1596 if (mAttrCharacteristics & ATTR_VALTOKEN) {
1597 nsAtom* normalizedValue =
1598 nsAccUtils::NormalizeARIAToken(mAttrs, mAttrAtom);
1599 if (normalizedValue) {
1600 nsDependentAtomString normalizedValueStr(normalizedValue);
1601 aAttrValue.Assign(normalizedValueStr);
1602 return;
1605 aAttrValue.Assign(value);
1609 bool AttrIterator::ExposeAttr(AccAttributes* aTargetAttrs) const {
1610 if (mAttrCharacteristics & ATTR_VALTOKEN) {
1611 nsAtom* normalizedValue = nsAccUtils::NormalizeARIAToken(mAttrs, mAttrAtom);
1612 if (normalizedValue) {
1613 aTargetAttrs->SetAttribute(mAttrAtom, normalizedValue);
1614 return true;
1616 } else if (mAttrCharacteristics & ATTR_VALINT) {
1617 int32_t intVal;
1618 if (nsCoreUtils::GetUIntAttrValue(mAttrs->GetAttr(mAttrAtom), &intVal)) {
1619 aTargetAttrs->SetAttribute(mAttrAtom, intVal);
1620 return true;
1622 if (mAttrAtom == nsGkAtoms::aria_colcount ||
1623 mAttrAtom == nsGkAtoms::aria_rowcount) {
1624 // These attributes allow a value of -1.
1625 if (mAttrs->AttrValueIs(kNameSpaceID_None, mAttrAtom, u"-1"_ns,
1626 eCaseMatters)) {
1627 aTargetAttrs->SetAttribute(mAttrAtom, -1);
1628 return true;
1631 return false; // Invalid value.
1633 nsAutoString value;
1634 if (mAttrs->GetAttr(mAttrAtom, value)) {
1635 aTargetAttrs->SetAttribute(mAttrAtom, std::move(value));
1636 return true;
1638 return false;