summaryrefslogtreecommitdiffstats
path: root/third_party/WebKit/Source/modules/accessibility/AXObject.h
blob: e45fb1af30b130c1e9972ef923cfa00d3b4aae1c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
/*
 * Copyright (C) 2008, 2009, 2011 Apple Inc. All rights reserved.
 * Copyright (C) 2008 Nuanti Ltd.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef AXObject_h
#define AXObject_h

#include "core/editing/VisiblePosition.h"
#include "modules/ModulesExport.h"
#include "platform/geometry/FloatQuad.h"
#include "platform/geometry/LayoutRect.h"
#include "platform/graphics/Color.h"
#include "platform/inspector_protocol/TypeBuilder.h"
#include "wtf/Forward.h"
#include "wtf/Vector.h"

namespace blink {

class AXObject;
class AXObjectCache;
class AXObjectCacheImpl;
class Element;
class FrameView;
class IntPoint;
class NameSource;
class Node;
class LayoutObject;
class ScrollableArea;

typedef unsigned AXID;

enum AccessibilityRole {
    UnknownRole = 0,
    AbbrRole, // No mapping to ARIA role
    AlertDialogRole,
    AlertRole,
    AnnotationRole, // No mapping to ARIA role
    ApplicationRole,
    ArticleRole,
    BannerRole,
    BlockquoteRole, // No mapping to ARIA role
    BusyIndicatorRole, // No mapping to ARIA role
    ButtonRole,
    CanvasRole, // No mapping to ARIA role
    CaptionRole, // No mapping to ARIA role
    CellRole,
    CheckBoxRole,
    ColorWellRole, // No mapping to ARIA role
    ColumnHeaderRole,
    ColumnRole, // No mapping to ARIA role
    ComboBoxRole,
    ComplementaryRole,
    ContentInfoRole,
    DateRole, // No mapping to ARIA role
    DateTimeRole, // No mapping to ARIA role
    DefinitionRole,
    DescriptionListDetailRole, // No mapping to ARIA role
    DescriptionListRole, // No mapping to ARIA role
    DescriptionListTermRole, // No mapping to ARIA role
    DetailsRole, // No mapping to ARIA role
    DialogRole,
    DirectoryRole,
    DisclosureTriangleRole, // No mapping to ARIA role
    DivRole, // No mapping to ARIA role
    DocumentRole,
    EmbeddedObjectRole, // No mapping to ARIA role
    FigcaptionRole, // No mapping to ARIA role
    FigureRole, // No mapping to ARIA role
    FooterRole,
    FormRole,
    GridRole,
    GroupRole,
    HeadingRole,
    IframePresentationalRole, // No mapping to ARIA role
    IframeRole, // No mapping to ARIA role
    IgnoredRole, // No mapping to ARIA role
    ImageMapLinkRole, // No mapping to ARIA role
    ImageMapRole, // No mapping to ARIA role
    ImageRole,
    InlineTextBoxRole, // No mapping to ARIA role
    InputTimeRole, // No mapping to ARIA role
    LabelRole,
    LegendRole, // No mapping to ARIA role
    LinkRole,
    ListBoxOptionRole,
    ListBoxRole,
    ListItemRole,
    ListMarkerRole, // No mapping to ARIA role
    ListRole,
    LogRole,
    MainRole,
    MarkRole, // No mapping to ARIA role
    MarqueeRole,
    MathRole,
    MenuBarRole,
    MenuButtonRole,
    MenuItemRole,
    MenuItemCheckBoxRole,
    MenuItemRadioRole,
    MenuListOptionRole,
    MenuListPopupRole,
    MenuRole,
    MeterRole,
    NavigationRole,
    NoneRole, // No mapping to ARIA role
    NoteRole,
    OutlineRole, // No mapping to ARIA role
    ParagraphRole, // No mapping to ARIA role
    PopUpButtonRole,
    PreRole, // No mapping to ARIA role
    PresentationalRole,
    ProgressIndicatorRole,
    RadioButtonRole,
    RadioGroupRole,
    RegionRole,
    RootWebAreaRole, // No mapping to ARIA role
    RowHeaderRole,
    RowRole,
    RubyRole, // No mapping to ARIA role
    RulerRole, // No mapping to ARIA role
    SVGRootRole, // No mapping to ARIA role
    ScrollAreaRole, // No mapping to ARIA role
    ScrollBarRole,
    SeamlessWebAreaRole, // No mapping to ARIA role
    SearchRole,
    SearchBoxRole,
    SliderRole,
    SliderThumbRole, // No mapping to ARIA role
    SpinButtonPartRole, // No mapping to ARIA role
    SpinButtonRole,
    SplitterRole,
    StaticTextRole, // No mapping to ARIA role
    StatusRole,
    SwitchRole,
    TabGroupRole, // No mapping to ARIA role
    TabListRole,
    TabPanelRole,
    TabRole,
    TableHeaderContainerRole, // No mapping to ARIA role
    TableRole,
    TextFieldRole,
    TimeRole, // No mapping to ARIA role
    TimerRole,
    ToggleButtonRole,
    ToolbarRole,
    TreeGridRole,
    TreeItemRole,
    TreeRole,
    UserInterfaceTooltipRole,
    WebAreaRole, // No mapping to ARIA role
    LineBreakRole, // No mapping to ARIA role
    WindowRole, // No mapping to ARIA role
    NumRoles
};

enum AccessibilityTextSource {
    AlternativeText,
    ChildrenText,
    SummaryText,
    HelpText,
    VisibleText,
    TitleTagText,
    PlaceholderText,
    LabelByElementText,
};

enum AccessibilityState {
    AXBusyState,
    AXCheckedState,
    AXEnabledState,
    AXExpandedState,
    AXFocusableState,
    AXFocusedState,
    AXHaspopupState,
    AXHoveredState,
    AXInvisibleState,
    AXLinkedState,
    AXMultilineState,
    AXMultiselectableState,
    AXOffscreenState,
    AXPressedState,
    AXProtectedState,
    AXReadonlyState,
    AXRequiredState,
    AXSelectableState,
    AXSelectedState,
    AXVerticalState,
    AXVisitedState
};

class AccessibilityText final : public GarbageCollectedFinalized<AccessibilityText> {
public:
    DEFINE_INLINE_TRACE()
    {
        visitor->trace(m_textElement);
    }

private:
    AccessibilityText(const String& text, const AccessibilityTextSource& source, AXObject* element)
    : m_text(text)
    , m_textElement(element)
    { }

    String m_text;
    Member<AXObject> m_textElement;
};

enum AccessibilityOrientation {
    AccessibilityOrientationUndefined = 0,
    AccessibilityOrientationVertical,
    AccessibilityOrientationHorizontal,
};

enum AXObjectInclusion {
    IncludeObject,
    IgnoreObject,
    DefaultBehavior,
};

enum AccessibilityButtonState {
    ButtonStateOff = 0,
    ButtonStateOn,
    ButtonStateMixed,
};

enum AccessibilityTextDirection {
    AccessibilityTextDirectionLTR,
    AccessibilityTextDirectionRTL,
    AccessibilityTextDirectionTTB,
    AccessibilityTextDirectionBTT
};

enum SortDirection {
    SortDirectionUndefined = 0,
    SortDirectionNone,
    SortDirectionAscending,
    SortDirectionDescending,
    SortDirectionOther
};

enum AccessibilityExpanded {
    ExpandedUndefined = 0,
    ExpandedCollapsed,
    ExpandedExpanded,
};

enum AccessibilityOptionalBool {
    OptionalBoolUndefined = 0,
    OptionalBoolTrue,
    OptionalBoolFalse
};

enum InvalidState {
    InvalidStateUndefined = 0,
    InvalidStateFalse,
    InvalidStateTrue,
    InvalidStateSpelling,
    InvalidStateGrammar,
    InvalidStateOther
};

enum TextStyle {
    TextStyleNone = 0,
    TextStyleBold = 1 << 0,
    TextStyleItalic = 1 << 1,
    TextStyleUnderline = 1 << 2,
    TextStyleLineThrough = 1 << 3
};

enum TextUnderElementMode {
    TextUnderElementAll,
    TextUnderElementAny // If the text is unimportant, just whether or not it's present
};

// The source of the accessible name of an element. This is needed
// because on some platforms this determines how the accessible name
// is exposed.
enum AXNameFrom {
    AXNameFromUninitialized = -1,
    AXNameFromAttribute = 0,
    AXNameFromCaption,
    AXNameFromContents,
    AXNameFromPlaceholder,
    AXNameFromRelatedElement,
    AXNameFromValue,
    AXNameFromTitle,
};

// The potential native HTML-based text (name, description or placeholder) sources for an element.
// See http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessible-name-and-description-calculation
enum AXTextFromNativeHTML {
    AXTextFromNativeHTMLUninitialized = -1,
    AXTextFromNativeHTMLFigcaption,
    AXTextFromNativeHTMLLabel,
    AXTextFromNativeHTMLLabelFor,
    AXTextFromNativeHTMLLabelWrapped,
    AXTextFromNativeHTMLLegend,
    AXTextFromNativeHTMLTableCaption,
    AXTextFromNativeHTMLTitleElement,
};

// The source of the accessible description of an element. This is needed
// because on some platforms this determines how the accessible description
// is exposed.
enum AXDescriptionFrom {
    AXDescriptionFromUninitialized = -1,
    AXDescriptionFromAttribute = 0,
    AXDescriptionFromContents,
    AXDescriptionFromPlaceholder,
    AXDescriptionFromRelatedElement,
};

enum AXIgnoredReason {
    AXActiveModalDialog,
    AXAncestorDisallowsChild,
    AXAncestorIsLeafNode,
    AXAriaHidden,
    AXAriaHiddenRoot,
    AXEmptyAlt,
    AXEmptyText,
    AXInert,
    AXInheritsPresentation,
    AXLabelContainer,
    AXLabelFor,
    AXNotRendered,
    AXNotVisible,
    AXPresentationalRole,
    AXProbablyPresentational,
    AXStaticTextUsedAsNameFor,
    AXUninteresting
};

class IgnoredReason {
    DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
    AXIgnoredReason reason;
    Member<const AXObject> relatedObject;

    explicit IgnoredReason(AXIgnoredReason reason)
        : reason(reason)
        , relatedObject(nullptr)
    { }

    IgnoredReason(AXIgnoredReason r, const AXObject* obj)
        : reason(r)
        , relatedObject(obj)
    { }

    DEFINE_INLINE_TRACE()
    {
        visitor->trace(relatedObject);
    }
};

class NameSourceRelatedObject : public GarbageCollectedFinalized<NameSourceRelatedObject> {
public:
    WeakMember<AXObject> object;
    String text;

    NameSourceRelatedObject(AXObject* object, String text)
        : object(object)
        , text(text)
    {
    }

    DEFINE_INLINE_TRACE()
    {
        visitor->trace(object);
    }
};

typedef HeapVector<Member<NameSourceRelatedObject>> AXRelatedObjectVector;
class NameSource {
    DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
    String text;
    bool superseded = false;
    bool invalid = false;
    AXNameFrom type = AXNameFromUninitialized;
    const QualifiedName& attribute;
    AtomicString attributeValue;
    AXTextFromNativeHTML nativeSource = AXTextFromNativeHTMLUninitialized;
    AXRelatedObjectVector relatedObjects;

    NameSource(bool superseded, const QualifiedName& attr)
        : superseded(superseded)
        , attribute(attr)
    {
    }

    explicit NameSource(bool superseded)
        : superseded(superseded)
        , attribute(QualifiedName::null())
    {
    }

    DEFINE_INLINE_TRACE()
    {
        visitor->trace(relatedObjects);
    }
};

class DescriptionSource {
    DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
    String text;
    bool superseded = false;
    bool invalid = false;
    AXDescriptionFrom type = AXDescriptionFromUninitialized;
    const QualifiedName& attribute;
    AtomicString attributeValue;
    AXTextFromNativeHTML nativeSource = AXTextFromNativeHTMLUninitialized;
    AXRelatedObjectVector relatedObjects;

    DescriptionSource(bool superseded, const QualifiedName& attr)
        : superseded(superseded)
        , attribute(attr)
    {
    }

    explicit DescriptionSource(bool superseded)
        : superseded(superseded)
        , attribute(QualifiedName::null())
    {
    }

    DEFINE_INLINE_TRACE()
    {
        visitor->trace(relatedObjects);
    }
};

class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
public:
    typedef HeapVector<Member<AXObject>> AXObjectVector;

    struct AXRange {
        DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
        // The deepest descendant in which the range starts.
        // (nullptr means the current object.)
        Persistent<AXObject> anchorObject;
        // The number of characters and child objects in the anchor object
        // before the range starts.
        int anchorOffset;
        // The deepest descendant in which the range ends.
        // (nullptr means the current object.)
        Persistent<AXObject> focusObject;
        // The number of characters and child objects in the focus object
        // before the range ends.
        int focusOffset;

        AXRange()
            : anchorObject(nullptr)
            , anchorOffset(-1)
            , focusObject(nullptr)
            , focusOffset(-1)
        { }

        AXRange(int startOffset, int endOffset)
            : anchorObject(nullptr)
            , anchorOffset(startOffset)
            , focusObject(nullptr)
            , focusOffset(endOffset)
        { }

        AXRange(AXObject* anchorObject, int anchorOffset,
            AXObject* focusObject, int focusOffset)
            : anchorObject(anchorObject)
            , anchorOffset(anchorOffset)
            , focusObject(focusObject)
            , focusOffset(focusOffset)
        { }

        bool isValid() const
        {
            return ((anchorObject && focusObject)
                || (!anchorObject && !focusObject))
                && anchorOffset >= 0 && focusOffset >= 0;
        }

        // Determines if the range only refers to text offsets under the current object.
        bool isSimple() const
        {
            return anchorObject == focusObject || !anchorObject || !focusObject;
        }
    };

protected:
    AXObject(AXObjectCacheImpl&);

public:
    virtual ~AXObject();
    DECLARE_VIRTUAL_TRACE();

    static unsigned numberOfLiveAXObjects() { return s_numberOfLiveAXObjects; }

    // After constructing an AXObject, it must be given a
    // unique ID, then added to AXObjectCacheImpl, and finally init() must
    // be called last.
    void setAXObjectID(AXID axObjectID) { m_id = axObjectID; }
    virtual void init() { }

    // When the corresponding WebCore object that this AXObject
    // wraps is deleted, it must be detached.
    virtual void detach();
    virtual bool isDetached() const;

    // If the parent of this object is known, this can be faster than using computeParent().
    virtual void setParent(AXObject* parent) { m_parent = parent; }

    // The AXObjectCacheImpl that owns this object, and its unique ID within this cache.
    AXObjectCacheImpl& axObjectCache() const
    {
        ASSERT(m_axObjectCache);
        return *m_axObjectCache;
    }

    AXID axObjectID() const { return m_id; }

    // Determine subclass type.
    virtual bool isAXNodeObject() const { return false; }
    virtual bool isAXLayoutObject() const { return false; }
    virtual bool isAXListBox() const { return false; }
    virtual bool isAXListBoxOption() const { return false; }
    virtual bool isAXRadioInput() const { return false; }
    virtual bool isAXSVGRoot() const { return false; }

    // Check object role or purpose.
    virtual AccessibilityRole roleValue() const { return m_role; }
    bool isARIATextControl() const;
    virtual bool isARIATreeGridRow() const { return false; }
    virtual bool isAXTable() const { return false; }
    virtual bool isAnchor() const { return false; }
    bool isButton() const;
    bool isCanvas() const { return roleValue() == CanvasRole; }
    bool isCheckbox() const { return roleValue() == CheckBoxRole; }
    bool isCheckboxOrRadio() const { return isCheckbox() || isRadioButton(); }
    bool isColorWell() const { return roleValue() == ColorWellRole; }
    bool isComboBox() const { return roleValue() == ComboBoxRole; }
    virtual bool isControl() const { return false; }
    virtual bool isDataTable() const { return false; }
    virtual bool isEmbeddedObject() const { return false; }
    virtual bool isFieldset() const { return false; }
    virtual bool isHeading() const { return false; }
    virtual bool isImage() const { return false; }
    virtual bool isImageMapLink() const { return false; }
    virtual bool isInputImage() const { return false; }
    bool isLandmarkRelated() const;
    virtual bool isLink() const { return false; }
    virtual bool isList() const { return false; }
    virtual bool isMenu() const { return false; }
    virtual bool isMenuButton() const { return false; }
    virtual bool isMenuList() const { return false; }
    virtual bool isMenuListOption() const { return false; }
    virtual bool isMenuListPopup() const { return false; }
    bool isMenuRelated() const;
    virtual bool isMeter() const { return false; }
    virtual bool isMockObject() const { return false; }
    virtual bool isNativeSpinButton() const { return false; }
    virtual bool isNativeTextControl() const { return false; } // input or textarea
    virtual bool isNonNativeTextControl() const { return false; } // contenteditable or role=textbox
    virtual bool isPasswordField() const { return false; }
    virtual bool isPasswordFieldAndShouldHideValue() const;
    bool isPresentational() const { return roleValue() == NoneRole || roleValue() == PresentationalRole; }
    virtual bool isProgressIndicator() const { return false; }
    bool isRadioButton() const { return roleValue() == RadioButtonRole; }
    bool isRange() const { return roleValue() == ProgressIndicatorRole || roleValue() == ScrollBarRole || roleValue() == SliderRole || roleValue() == SpinButtonRole; }
    bool isScrollbar() const { return roleValue() == ScrollBarRole; }
    virtual bool isSlider() const { return false; }
    virtual bool isNativeSlider() const { return false; }
    virtual bool isSpinButton() const { return roleValue() == SpinButtonRole; }
    virtual bool isSpinButtonPart() const { return false; }
    bool isTabItem() const { return roleValue() == TabRole; }
    virtual bool isTableCell() const { return false; }
    virtual bool isTableRow() const { return false; }
    virtual bool isTextControl() const { return false; }
    virtual bool isTableCol() const { return false; }
    bool isTree() const { return roleValue() == TreeRole; }
    bool isWebArea() const { return roleValue() == WebAreaRole; }

    // Check object state.
    virtual bool isChecked() const { return false; }
    virtual bool isClickable() const;
    virtual bool isCollapsed() const { return false; }
    virtual bool isEnabled() const { return false; }
    virtual AccessibilityExpanded isExpanded() const { return ExpandedUndefined; }
    virtual bool isFocused() const { return false; }
    virtual bool isHovered() const { return false; }
    virtual bool isLinked() const { return false; }
    virtual bool isLoaded() const { return false; }
    virtual bool isMultiSelectable() const { return false; }
    virtual bool isOffScreen() const { return false; }
    virtual bool isPressed() const { return false; }
    virtual bool isReadOnly() const { return false; }
    virtual bool isRequired() const { return false; }
    virtual bool isSelected() const { return false; }
    virtual bool isSelectedOptionActive() const { return false; }
    virtual bool isVisible() const { return true; }
    virtual bool isVisited() const { return false; }

    // Check whether certain properties can be modified.
    virtual bool canSetFocusAttribute() const { return false; }
    virtual bool canSetValueAttribute() const { return false; }
    virtual bool canSetSelectedAttribute() const { return false; }

    // Whether objects are ignored, i.e. not included in the tree.
    bool accessibilityIsIgnored() const;
    typedef HeapVector<IgnoredReason> IgnoredReasons;
    virtual bool computeAccessibilityIsIgnored(IgnoredReasons* = nullptr) const { return true; }
    bool accessibilityIsIgnoredByDefault(IgnoredReasons* = nullptr) const;
    AXObjectInclusion accessibilityPlatformIncludesObject() const;
    virtual AXObjectInclusion defaultObjectInclusion(IgnoredReasons* = nullptr) const;
    bool isInertOrAriaHidden() const;
    const AXObject* ariaHiddenRoot() const;
    bool computeIsInertOrAriaHidden(IgnoredReasons* = nullptr) const;
    bool isDescendantOfLeafNode() const;
    AXObject* leafNodeAncestor() const;
    bool isDescendantOfDisabledNode() const;
    const AXObject* disabledAncestor() const;
    bool lastKnownIsIgnoredValue();
    void setLastKnownIsIgnoredValue(bool);
    bool hasInheritedPresentationalRole() const;
    bool isPresentationalChild() const;

    //
    // Accessible name calculation
    //

    // Retrieves the accessible name of the object, an enum indicating where the name
    // was derived from, and a list of objects that were used to derive the name, if any.
    virtual String name(AXNameFrom&, AXObjectVector* nameObjects) const;

    typedef HeapVector<NameSource> NameSources;
    // Retrieves the accessible name of the object and a list of all potential sources
    // for the name, indicating which were used.
    virtual String name(NameSources*) const;

    typedef HeapVector<DescriptionSource> DescriptionSources;
    // Takes the result of nameFrom from calling |name|, above, and retrieves the
    // accessible description of the object, which is secondary to |name|, an enum indicating
    // where the description was derived from, and a list of objects that were used to
    // derive the description, if any.
    virtual String description(AXNameFrom, AXDescriptionFrom&, AXObjectVector* descriptionObjects) const { return String(); }

    // Same as above, but returns a list of all potential sources for the description, indicating which were used.
    virtual String description(AXNameFrom, AXDescriptionFrom&, DescriptionSources*, AXRelatedObjectVector*) const { return String(); }

    // Takes the result of nameFrom and descriptionFrom from calling |name| and |description|,
    // above, and retrieves the placeholder of the object, if present and if it wasn't already
    // exposed by one of the two functions above.
    virtual String placeholder(AXNameFrom, AXDescriptionFrom) const { return String(); }

    // Internal functions used by name and description, above.
    typedef HeapHashSet<Member<const AXObject>> AXObjectSet;
    virtual String textAlternative(bool recursive, bool inAriaLabelledByTraversal, AXObjectSet& visited, AXNameFrom& nameFrom, AXRelatedObjectVector* relatedObjects, NameSources* nameSources) const { return String(); }
    virtual String textFromDescendants(AXObjectSet& visited, bool recursive) const { return String(); }

    // Returns result of Accessible Name Calculation algorithm.
    // This is a simpler high-level interface to |name| used by Inspector.
    String computedName() const;

    // Internal function used to determine whether the result of calling |name| on this object would
    // return text that came from the an HTML label element or not. This is intended to be faster than calling
    // |name| or |textAlternative|, and without side effects (it won't call axObjectCache->getOrCreate).
    virtual bool nameFromLabelElement() const { return false; }

    //
    // Properties of static elements.
    //

    virtual const AtomicString& accessKey() const { return nullAtom; }
    virtual RGBA32 backgroundColor() const { return Color::transparent; }
    virtual RGBA32 color() const { return Color::black; }
    // Used by objects of role ColorWellRole.
    virtual RGBA32 colorValue() const { return Color::transparent; }
    virtual bool canvasHasFallbackContent() const { return false; }
    virtual String fontFamily() const { return nullAtom; }
    // Font size is in pixels.
    virtual float fontSize() const { return 0.0f; }
    virtual int headingLevel() const { return 0; }
    // 1-based, to match the aria-level spec.
    virtual unsigned hierarchicalLevel() const { return 0; }
    virtual AccessibilityOrientation orientation() const;
    virtual String text() const { return String(); }
    virtual AccessibilityTextDirection textDirection() const { return AccessibilityTextDirectionLTR; }
    virtual int textLength() const { return 0; }
    virtual TextStyle getTextStyle() const { return TextStyleNone; }
    virtual KURL url() const { return KURL(); }

    // Load inline text boxes for just this node, even if
    // settings->inlineTextBoxAccessibilityEnabled() is false.
    virtual void loadInlineTextBoxes() { }

    // Walk the AXObjects on the same line. This is supported on any
    // object type but primarily intended to be used for inline text boxes.
    virtual AXObject* nextOnLine() const { return nullptr; }
    virtual AXObject* previousOnLine() const { return nullptr; }

    // For an inline text box.
    // The integer horizontal pixel offset of each character in the string; negative values for RTL.
    virtual void textCharacterOffsets(Vector<int>&) const { }
    // The start and end character offset of each word in the inline text box.
    virtual void wordBoundaries(Vector<AXRange>& words) const { }

    // Properties of interactive elements.
    String actionVerb() const;
    virtual AccessibilityButtonState checkboxOrRadioValue() const;
    virtual InvalidState getInvalidState() const { return InvalidStateUndefined; }
    // Only used when invalidState() returns InvalidStateOther.
    virtual String ariaInvalidValue() const { return String(); }
    virtual String valueDescription() const { return String(); }
    virtual float valueForRange() const { return 0.0f; }
    virtual float maxValueForRange() const { return 0.0f; }
    virtual float minValueForRange() const { return 0.0f; }
    virtual String stringValue() const { return String(); }

    // ARIA attributes.
    virtual AXObject* activeDescendant() const { return 0; }
    virtual String ariaAutoComplete() const { return String(); }
    virtual String ariaDescribedByAttribute() const { return String(); }
    virtual void ariaFlowToElements(AXObjectVector&) const { }
    virtual void ariaControlsElements(AXObjectVector&) const { }
    virtual void ariaOwnsElements(AXObjectVector& owns) const { }
    virtual void ariaDescribedbyElements(AXObjectVector&) const { }
    virtual void ariaLabelledbyElements(AXObjectVector&) const { }
    virtual bool ariaHasPopup() const { return false; }
    virtual bool isEditable() const { return false; }
    bool isMultiline() const;
    virtual bool isRichlyEditable() const { return false; }
    virtual String ariaLabelledbyAttribute() const { return String(); }
    bool ariaPressedIsPresent() const;
    virtual AccessibilityRole ariaRoleAttribute() const { return UnknownRole; }
    virtual bool ariaRoleHasPresentationalChildren() const { return false; }
    virtual AXObject* ancestorForWhichThisIsAPresentationalChild() const { return 0; }
    virtual bool shouldFocusActiveDescendant() const { return false; }
    bool supportsARIAAttributes() const;
    virtual bool supportsARIADragging() const { return false; }
    virtual bool supportsARIADropping() const { return false; }
    virtual bool supportsARIAFlowTo() const { return false; }
    virtual bool supportsARIAOwns() const { return false; }
    bool supportsRangeValue() const;
    virtual SortDirection getSortDirection() const { return SortDirectionUndefined; }

    // Returns 0-based index.
    int indexInParent() const;

    // Returns 1-based position in set.
    virtual int posInSet() const { return 0; }
    virtual int setSize() const { return 0; }
    bool supportsSetSizeAndPosInSet() const;

    // ARIA live-region features.
    bool isLiveRegion() const;
    const AXObject* liveRegionRoot() const;
    virtual const AtomicString& liveRegionStatus() const { return nullAtom; }
    virtual const AtomicString& liveRegionRelevant() const { return nullAtom; }
    virtual bool liveRegionAtomic() const { return false; }
    virtual bool liveRegionBusy() const { return false; }

    const AtomicString& containerLiveRegionStatus() const;
    const AtomicString& containerLiveRegionRelevant() const;
    bool containerLiveRegionAtomic() const;
    bool containerLiveRegionBusy() const;

    // Location and click point in frame-relative coordinates.
    virtual LayoutRect elementRect() const { return m_explicitElementRect; }
    void setElementRect(LayoutRect r) { m_explicitElementRect = r; }
    virtual void markCachedElementRectDirty() const;
    virtual IntPoint clickPoint();

    // Hit testing.
    // Called on the root AX object to return the deepest available element.
    virtual AXObject* accessibilityHitTest(const IntPoint&) const { return 0; }
    // Called on the AX object after the layout tree determines which is the right AXLayoutObject.
    virtual AXObject* elementAccessibilityHitTest(const IntPoint&) const;

    // High-level accessibility tree access. Other modules should only use these functions.
    const AXObjectVector& children();
    AXObject* parentObject() const;
    AXObject* parentObjectIfExists() const;
    virtual AXObject* computeParent() const = 0;
    virtual AXObject* computeParentIfExists() const { return 0; }
    AXObject* cachedParentObject() const { return m_parent; }
    AXObject* parentObjectUnignored() const;

    // Low-level accessibility tree exploration, only for use within the accessibility module.
    virtual AXObject* rawFirstChild() const { return 0; }
    virtual AXObject* rawNextSibling() const { return 0; }
    virtual void addChildren() { }
    virtual bool canHaveChildren() const { return true; }
    bool hasChildren() const { return m_haveChildren; }
    virtual void updateChildrenIfNecessary();
    virtual bool needsToUpdateChildren() const { return false; }
    virtual void setNeedsToUpdateChildren() { }
    virtual void clearChildren();
    virtual void detachFromParent() { m_parent = 0; }
    virtual AXObject* scrollBar(AccessibilityOrientation) { return 0; }

    // Properties of the object's owning document or page.
    virtual double estimatedLoadingProgress() const { return 0; }

    // DOM and layout tree access.
    virtual Node* getNode() const { return 0; }
    virtual LayoutObject* getLayoutObject() const { return 0; }
    virtual Document* getDocument() const;
    virtual FrameView* documentFrameView() const;
    virtual Element* anchorElement() const { return 0; }
    virtual Element* actionElement() const { return 0; }
    String language() const;
    bool hasAttribute(const QualifiedName&) const;
    const AtomicString& getAttribute(const QualifiedName&) const;

    // Methods that retrieve or manipulate the current selection.

    // Get the current selection from anywhere in the accessibility tree.
    virtual AXRange selection() const { return AXRange(); }
    // Gets only the start and end offsets of the selection computed using the
    // current object as the starting point. Returns a null selection if there is
    // no selection in the subtree rooted at this object.
    virtual AXRange selectionUnderObject() const { return AXRange(); }
    virtual void setSelection(const AXRange&) { }

    // Scrollable containers.
    bool isScrollableContainer() const;
    IntPoint scrollOffset() const;
    IntPoint minimumScrollOffset() const;
    IntPoint maximumScrollOffset() const;
    void setScrollOffset(const IntPoint&) const;

    // If this object itself scrolls, return its ScrollableArea.
    virtual ScrollableArea* getScrollableAreaIfScrollable() const { return 0; }

    // Modify or take an action on an object.
    virtual void increment() { }
    virtual void decrement() { }
    bool performDefaultAction() const { return press(); }
    virtual bool press() const;
    // Make this object visible by scrolling as many nested scrollable views as needed.
    void scrollToMakeVisible() const;
    // Same, but if the whole object can't be made visible, try for this subrect, in local coordinates.
    void scrollToMakeVisibleWithSubFocus(const IntRect&) const;
    // Scroll this object to a given point in global coordinates of the top-level window.
    void scrollToGlobalPoint(const IntPoint&) const;
    virtual void setFocused(bool) { }
    virtual void setSelected(bool) { }
    virtual void setValue(const String&) { }
    virtual void setValue(float) { }

    // Notifications that this object may have changed.
    virtual void childrenChanged() { }
    virtual void handleActiveDescendantChanged() { }
    virtual void handleAriaExpandedChanged() { }
    void notifyIfIgnoredValueChanged();
    virtual void selectionChanged();
    virtual void textChanged() { }
    virtual void updateAccessibilityRole() { }

    // Text metrics. Most of these should be deprecated, needs major cleanup.
    virtual VisiblePosition visiblePositionForIndex(int) const { return VisiblePosition(); }
    int lineForPosition(const VisiblePosition&) const;
    virtual int index(const VisiblePosition&) const { return -1; }
    virtual void lineBreaks(Vector<int>&) const { }

    // Static helper functions.
    static bool isARIAControl(AccessibilityRole);
    static bool isARIAInput(AccessibilityRole);
    static AccessibilityRole ariaRoleToWebCoreRole(const String&);
    static IntRect boundingBoxForQuads(LayoutObject*, const Vector<FloatQuad>&);
    static const AtomicString& roleName(AccessibilityRole);
    static const AtomicString& internalRoleName(AccessibilityRole);
    static bool isInsideFocusableElementOrARIAWidget(const Node&);

protected:
    AXID m_id;
    AXObjectVector m_children;
    mutable bool m_haveChildren;
    AccessibilityRole m_role;
    AXObjectInclusion m_lastKnownIsIgnoredValue;
    LayoutRect m_explicitElementRect;

    // Used only inside textAlternative():
    static String collapseWhitespace(const String&);
    static String recursiveTextAlternative(const AXObject&, bool inAriaLabelledByTraversal, AXObjectSet& visited);
    bool isHiddenForTextAlternativeCalculation() const;
    String ariaTextAlternative(bool recursive, bool inAriaLabelledByTraversal, AXObjectSet& visited, AXNameFrom&, AXRelatedObjectVector*, NameSources*, bool* foundTextAlternative) const;
    String textFromElements(bool inAriaLabelledByTraversal, AXObjectSet& visited, WillBeHeapVector<RawPtrWillBeMember<Element>>& elements, AXRelatedObjectVector* relatedObjects) const;
    void tokenVectorFromAttribute(Vector<String>&, const QualifiedName&) const;
    void elementsFromAttribute(WillBeHeapVector<RawPtrWillBeMember<Element>>& elements, const QualifiedName&) const;
    void ariaLabelledbyElementVector(WillBeHeapVector<RawPtrWillBeMember<Element>>& elements) const;
    String textFromAriaLabelledby(AXObjectSet& visited, AXRelatedObjectVector* relatedObjects) const;
    String textFromAriaDescribedby(AXRelatedObjectVector* relatedObjects) const;

    virtual const AXObject* inheritsPresentationalRoleFrom() const { return 0; }

    virtual bool nameFromContents() const;

    AccessibilityRole buttonRoleType() const;

    mutable Member<AXObject> m_parent;

    // The following cached attribute values (the ones starting with m_cached*)
    // are only valid if m_lastModificationCount matches AXObjectCacheImpl::modificationCount().
    mutable int m_lastModificationCount;
    mutable bool m_cachedIsIgnored : 1;
    mutable bool m_cachedIsInertOrAriaHidden : 1;
    mutable bool m_cachedIsDescendantOfLeafNode : 1;
    mutable bool m_cachedIsDescendantOfDisabledNode : 1;
    mutable bool m_cachedHasInheritedPresentationalRole : 1;
    mutable bool m_cachedIsPresentationalChild : 1;
    mutable Member<const AXObject> m_cachedLiveRegionRoot;

    Member<AXObjectCacheImpl> m_axObjectCache;

    // Updates the cached attribute values. This may be recursive, so to prevent deadlocks,
    // functions called here may only search up the tree (ancestors), not down.
    void updateCachedAttributeValuesIfNeeded() const;

private:
    static bool includesARIAWidgetRole(const String&);
    static bool hasInteractiveARIAAttribute(const Element&);

    static unsigned s_numberOfLiveAXObjects;
};

#define DEFINE_AX_OBJECT_TYPE_CASTS(thisType, predicate) \
    DEFINE_TYPE_CASTS(thisType, AXObject, object, object->predicate, object.predicate)

} // namespace blink

WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::IgnoredReason);
WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::NameSource);
WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::DescriptionSource);

#endif // AXObject_h