|
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 NS_IMPL_ISUPPORTS_INHERITED0(HTMLListAccessible, HyperTextAccessible) |
|
25 |
|
26 role |
|
27 HTMLListAccessible::NativeRole() |
|
28 { |
|
29 if (mContent->Tag() == nsGkAtoms::dl) |
|
30 return roles::DEFINITION_LIST; |
|
31 |
|
32 return roles::LIST; |
|
33 } |
|
34 |
|
35 uint64_t |
|
36 HTMLListAccessible::NativeState() |
|
37 { |
|
38 return HyperTextAccessibleWrap::NativeState() | states::READONLY; |
|
39 } |
|
40 |
|
41 |
|
42 //////////////////////////////////////////////////////////////////////////////// |
|
43 // HTMLLIAccessible |
|
44 //////////////////////////////////////////////////////////////////////////////// |
|
45 |
|
46 HTMLLIAccessible:: |
|
47 HTMLLIAccessible(nsIContent* aContent, DocAccessible* aDoc) : |
|
48 HyperTextAccessibleWrap(aContent, aDoc), mBullet(nullptr) |
|
49 { |
|
50 mType = eHTMLLiType; |
|
51 |
|
52 nsBlockFrame* blockFrame = do_QueryFrame(GetFrame()); |
|
53 if (blockFrame && blockFrame->HasBullet()) { |
|
54 mBullet = new HTMLListBulletAccessible(mContent, mDoc); |
|
55 Document()->BindToDocument(mBullet, nullptr); |
|
56 } |
|
57 } |
|
58 |
|
59 NS_IMPL_ISUPPORTS_INHERITED0(HTMLLIAccessible, HyperTextAccessible) |
|
60 |
|
61 void |
|
62 HTMLLIAccessible::Shutdown() |
|
63 { |
|
64 mBullet = nullptr; |
|
65 |
|
66 HyperTextAccessibleWrap::Shutdown(); |
|
67 } |
|
68 |
|
69 role |
|
70 HTMLLIAccessible::NativeRole() |
|
71 { |
|
72 if (mContent->Tag() == nsGkAtoms::dt) |
|
73 return roles::TERM; |
|
74 |
|
75 return roles::LISTITEM; |
|
76 } |
|
77 |
|
78 uint64_t |
|
79 HTMLLIAccessible::NativeState() |
|
80 { |
|
81 return HyperTextAccessibleWrap::NativeState() | states::READONLY; |
|
82 } |
|
83 |
|
84 NS_IMETHODIMP |
|
85 HTMLLIAccessible::GetBounds(int32_t* aX, int32_t* aY, |
|
86 int32_t* aWidth, int32_t* aHeight) |
|
87 { |
|
88 nsresult rv = AccessibleWrap::GetBounds(aX, aY, aWidth, aHeight); |
|
89 if (NS_FAILED(rv) || !mBullet || mBullet->IsInside()) |
|
90 return rv; |
|
91 |
|
92 int32_t bulletX = 0, bulletY = 0, bulletWidth = 0, bulletHeight = 0; |
|
93 rv = mBullet->GetBounds(&bulletX, &bulletY, &bulletWidth, &bulletHeight); |
|
94 NS_ENSURE_SUCCESS(rv, rv); |
|
95 |
|
96 *aWidth += *aX - bulletX; |
|
97 *aX = bulletX; // Move x coordinate of list item over to cover bullet as well |
|
98 return NS_OK; |
|
99 } |
|
100 |
|
101 //////////////////////////////////////////////////////////////////////////////// |
|
102 // HTMLLIAccessible: public |
|
103 |
|
104 void |
|
105 HTMLLIAccessible::UpdateBullet(bool aHasBullet) |
|
106 { |
|
107 if (aHasBullet == !!mBullet) { |
|
108 NS_NOTREACHED("Bullet and accessible are in sync already!"); |
|
109 return; |
|
110 } |
|
111 |
|
112 DocAccessible* document = Document(); |
|
113 if (aHasBullet) { |
|
114 mBullet = new HTMLListBulletAccessible(mContent, mDoc); |
|
115 document->BindToDocument(mBullet, nullptr); |
|
116 InsertChildAt(0, mBullet); |
|
117 } else { |
|
118 RemoveChild(mBullet); |
|
119 document->UnbindFromDocument(mBullet); |
|
120 mBullet = nullptr; |
|
121 } |
|
122 |
|
123 // XXXtodo: fire show/hide and reorder events. That's hard to make it |
|
124 // right now because coalescence happens by DOM node. |
|
125 } |
|
126 |
|
127 //////////////////////////////////////////////////////////////////////////////// |
|
128 // HTMLLIAccessible: Accessible protected |
|
129 |
|
130 void |
|
131 HTMLLIAccessible::CacheChildren() |
|
132 { |
|
133 if (mBullet) |
|
134 AppendChild(mBullet); |
|
135 |
|
136 // Cache children from subtree. |
|
137 AccessibleWrap::CacheChildren(); |
|
138 } |
|
139 |
|
140 //////////////////////////////////////////////////////////////////////////////// |
|
141 // HTMLListBulletAccessible |
|
142 //////////////////////////////////////////////////////////////////////////////// |
|
143 HTMLListBulletAccessible:: |
|
144 HTMLListBulletAccessible(nsIContent* aContent, DocAccessible* aDoc) : |
|
145 LeafAccessible(aContent, aDoc) |
|
146 { |
|
147 mStateFlags |= eSharedNode; |
|
148 } |
|
149 |
|
150 //////////////////////////////////////////////////////////////////////////////// |
|
151 // HTMLListBulletAccessible: Accessible |
|
152 |
|
153 nsIFrame* |
|
154 HTMLListBulletAccessible::GetFrame() const |
|
155 { |
|
156 nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame()); |
|
157 return blockFrame ? blockFrame->GetBullet() : nullptr; |
|
158 } |
|
159 |
|
160 ENameValueFlag |
|
161 HTMLListBulletAccessible::Name(nsString &aName) |
|
162 { |
|
163 aName.Truncate(); |
|
164 |
|
165 // Native anonymous content, ARIA can't be used. Get list bullet text. |
|
166 nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame()); |
|
167 if (blockFrame) { |
|
168 blockFrame->GetBulletText(aName); |
|
169 |
|
170 // Append space otherwise bullets are jammed up against list text. |
|
171 aName.Append(' '); |
|
172 } |
|
173 |
|
174 return eNameOK; |
|
175 } |
|
176 |
|
177 role |
|
178 HTMLListBulletAccessible::NativeRole() |
|
179 { |
|
180 return roles::STATICTEXT; |
|
181 } |
|
182 |
|
183 uint64_t |
|
184 HTMLListBulletAccessible::NativeState() |
|
185 { |
|
186 return LeafAccessible::NativeState() | states::READONLY; |
|
187 } |
|
188 |
|
189 void |
|
190 HTMLListBulletAccessible::AppendTextTo(nsAString& aText, uint32_t aStartOffset, |
|
191 uint32_t aLength) |
|
192 { |
|
193 nsAutoString bulletText; |
|
194 nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame()); |
|
195 if (blockFrame) |
|
196 blockFrame->GetBulletText(bulletText); |
|
197 |
|
198 aText.Append(Substring(bulletText, aStartOffset, aLength)); |
|
199 } |
|
200 |
|
201 //////////////////////////////////////////////////////////////////////////////// |
|
202 // HTMLListBulletAccessible: public |
|
203 |
|
204 bool |
|
205 HTMLListBulletAccessible::IsInside() const |
|
206 { |
|
207 nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame()); |
|
208 return blockFrame ? blockFrame->HasInsideBullet() : false; |
|
209 } |