Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "HTMLListAccessible.h"
8 :
9 : #include "DocAccessible.h"
10 : #include "nsAccUtils.h"
11 : #include "Role.h"
12 : #include "States.h"
13 :
14 : #include "nsBlockFrame.h"
15 : #include "nsBulletFrame.h"
16 :
17 : using namespace mozilla;
18 : using namespace mozilla::a11y;
19 :
20 : ////////////////////////////////////////////////////////////////////////////////
21 : // HTMLListAccessible
22 : ////////////////////////////////////////////////////////////////////////////////
23 :
24 0 : NS_IMPL_ISUPPORTS_INHERITED0(HTMLListAccessible, HyperTextAccessible)
25 :
26 : role
27 0 : HTMLListAccessible::NativeRole()
28 : {
29 0 : a11y::role r = GetAccService()->MarkupRole(mContent);
30 0 : return r != roles::NOTHING ? r : roles::LIST;
31 : }
32 :
33 : uint64_t
34 0 : HTMLListAccessible::NativeState()
35 : {
36 0 : return HyperTextAccessibleWrap::NativeState() | states::READONLY;
37 : }
38 :
39 :
40 : ////////////////////////////////////////////////////////////////////////////////
41 : // HTMLLIAccessible
42 : ////////////////////////////////////////////////////////////////////////////////
43 :
44 0 : HTMLLIAccessible::
45 0 : HTMLLIAccessible(nsIContent* aContent, DocAccessible* aDoc) :
46 0 : HyperTextAccessibleWrap(aContent, aDoc), mBullet(nullptr)
47 : {
48 0 : mType = eHTMLLiType;
49 :
50 0 : nsBlockFrame* blockFrame = do_QueryFrame(GetFrame());
51 0 : if (blockFrame && blockFrame->HasBullet()) {
52 0 : mBullet = new HTMLListBulletAccessible(mContent, mDoc);
53 0 : Document()->BindToDocument(mBullet, nullptr);
54 0 : AppendChild(mBullet);
55 : }
56 0 : }
57 :
58 0 : NS_IMPL_ISUPPORTS_INHERITED0(HTMLLIAccessible, HyperTextAccessible)
59 :
60 : void
61 0 : HTMLLIAccessible::Shutdown()
62 : {
63 0 : mBullet = nullptr;
64 :
65 0 : HyperTextAccessibleWrap::Shutdown();
66 0 : }
67 :
68 : role
69 0 : HTMLLIAccessible::NativeRole()
70 : {
71 0 : a11y::role r = GetAccService()->MarkupRole(mContent);
72 0 : return r != roles::NOTHING ? r : roles::LISTITEM;
73 : }
74 :
75 : uint64_t
76 0 : HTMLLIAccessible::NativeState()
77 : {
78 0 : return HyperTextAccessibleWrap::NativeState() | states::READONLY;
79 : }
80 :
81 : nsIntRect
82 0 : HTMLLIAccessible::Bounds() const
83 : {
84 0 : nsIntRect rect = AccessibleWrap::Bounds();
85 0 : if (rect.IsEmpty() || !mBullet || mBullet->IsInside())
86 0 : return rect;
87 :
88 0 : nsIntRect bulletRect = mBullet->Bounds();
89 :
90 0 : rect.width += rect.x - bulletRect.x;
91 0 : rect.x = bulletRect.x; // Move x coordinate of list item over to cover bullet as well
92 0 : return rect;
93 : }
94 :
95 : bool
96 0 : HTMLLIAccessible::InsertChildAt(uint32_t aIndex, Accessible* aChild)
97 : {
98 : // Adjust index if there's a bullet.
99 0 : if (mBullet && aIndex == 0 && aChild != mBullet) {
100 0 : return HyperTextAccessible::InsertChildAt(aIndex + 1, aChild);
101 : }
102 :
103 0 : return HyperTextAccessible::InsertChildAt(aIndex, aChild);
104 : }
105 :
106 : ////////////////////////////////////////////////////////////////////////////////
107 : // HTMLLIAccessible: public
108 :
109 : void
110 0 : HTMLLIAccessible::UpdateBullet(bool aHasBullet)
111 : {
112 0 : if (aHasBullet == !!mBullet) {
113 0 : NS_NOTREACHED("Bullet and accessible are in sync already!");
114 0 : return;
115 : }
116 :
117 0 : TreeMutation mt(this);
118 0 : if (aHasBullet) {
119 0 : mBullet = new HTMLListBulletAccessible(mContent, mDoc);
120 0 : mDoc->BindToDocument(mBullet, nullptr);
121 0 : InsertChildAt(0, mBullet);
122 0 : mt.AfterInsertion(mBullet);
123 : }
124 : else {
125 0 : mt.BeforeRemoval(mBullet);
126 0 : RemoveChild(mBullet);
127 0 : mBullet = nullptr;
128 : }
129 0 : mt.Done();
130 : }
131 :
132 : ////////////////////////////////////////////////////////////////////////////////
133 : // HTMLListBulletAccessible
134 : ////////////////////////////////////////////////////////////////////////////////
135 0 : HTMLListBulletAccessible::
136 0 : HTMLListBulletAccessible(nsIContent* aContent, DocAccessible* aDoc) :
137 0 : LeafAccessible(aContent, aDoc)
138 : {
139 0 : mGenericTypes |= eText;
140 0 : mStateFlags |= eSharedNode;
141 0 : }
142 :
143 : ////////////////////////////////////////////////////////////////////////////////
144 : // HTMLListBulletAccessible: Accessible
145 :
146 : nsIFrame*
147 0 : HTMLListBulletAccessible::GetFrame() const
148 : {
149 0 : nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame());
150 0 : return blockFrame ? blockFrame->GetBullet() : nullptr;
151 : }
152 :
153 : ENameValueFlag
154 0 : HTMLListBulletAccessible::Name(nsString &aName)
155 : {
156 0 : aName.Truncate();
157 :
158 : // Native anonymous content, ARIA can't be used. Get list bullet text.
159 0 : nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame());
160 0 : if (blockFrame) {
161 0 : blockFrame->GetSpokenBulletText(aName);
162 : }
163 :
164 0 : return eNameOK;
165 : }
166 :
167 : role
168 0 : HTMLListBulletAccessible::NativeRole()
169 : {
170 0 : return roles::STATICTEXT;
171 : }
172 :
173 : uint64_t
174 0 : HTMLListBulletAccessible::NativeState()
175 : {
176 0 : return LeafAccessible::NativeState() | states::READONLY;
177 : }
178 :
179 : void
180 0 : HTMLListBulletAccessible::AppendTextTo(nsAString& aText, uint32_t aStartOffset,
181 : uint32_t aLength)
182 : {
183 0 : nsAutoString bulletText;
184 0 : nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame());
185 0 : if (blockFrame)
186 0 : blockFrame->GetSpokenBulletText(bulletText);
187 :
188 0 : aText.Append(Substring(bulletText, aStartOffset, aLength));
189 0 : }
190 :
191 : ////////////////////////////////////////////////////////////////////////////////
192 : // HTMLListBulletAccessible: public
193 :
194 : bool
195 0 : HTMLListBulletAccessible::IsInside() const
196 : {
197 0 : nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame());
198 0 : return blockFrame ? blockFrame->HasInsideBullet() : false;
199 : }
|