accessible/src/html/HTMLImageMapAccessible.cpp

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:c788c75e47b9
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "HTMLImageMapAccessible.h"
7
8 #include "ARIAMap.h"
9 #include "nsAccUtils.h"
10 #include "DocAccessible-inl.h"
11 #include "Role.h"
12
13 #include "nsIDOMHTMLCollection.h"
14 #include "nsIServiceManager.h"
15 #include "nsIDOMElement.h"
16 #include "nsIDOMHTMLAreaElement.h"
17 #include "nsIFrame.h"
18 #include "nsImageFrame.h"
19 #include "nsImageMap.h"
20 #include "nsIURI.h"
21
22 using namespace mozilla::a11y;
23
24 ////////////////////////////////////////////////////////////////////////////////
25 // HTMLImageMapAccessible
26 ////////////////////////////////////////////////////////////////////////////////
27
28 HTMLImageMapAccessible::
29 HTMLImageMapAccessible(nsIContent* aContent, DocAccessible* aDoc) :
30 ImageAccessibleWrap(aContent, aDoc)
31 {
32 mType = eImageMapType;
33 }
34
35 ////////////////////////////////////////////////////////////////////////////////
36 // HTMLImageMapAccessible: nsISupports
37
38 NS_IMPL_ISUPPORTS_INHERITED0(HTMLImageMapAccessible, ImageAccessible)
39
40 ////////////////////////////////////////////////////////////////////////////////
41 // HTMLImageMapAccessible: Accessible public
42
43 role
44 HTMLImageMapAccessible::NativeRole()
45 {
46 return roles::IMAGE_MAP;
47 }
48
49 ////////////////////////////////////////////////////////////////////////////////
50 // HTMLImageMapAccessible: HyperLinkAccessible
51
52 uint32_t
53 HTMLImageMapAccessible::AnchorCount()
54 {
55 return ChildCount();
56 }
57
58 Accessible*
59 HTMLImageMapAccessible::AnchorAt(uint32_t aAnchorIndex)
60 {
61 return GetChildAt(aAnchorIndex);
62 }
63
64 already_AddRefed<nsIURI>
65 HTMLImageMapAccessible::AnchorURIAt(uint32_t aAnchorIndex)
66 {
67 Accessible* area = GetChildAt(aAnchorIndex);
68 if (!area)
69 return nullptr;
70
71 nsIContent* linkContent = area->GetContent();
72 return linkContent ? linkContent->GetHrefURI() : nullptr;
73 }
74
75 ////////////////////////////////////////////////////////////////////////////////
76 // HTMLImageMapAccessible: public
77
78 void
79 HTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
80 {
81 nsImageFrame* imageFrame = do_QueryFrame(mContent->GetPrimaryFrame());
82
83 // If image map is not initialized yet then we trigger one time more later.
84 nsImageMap* imageMapObj = imageFrame->GetExistingImageMap();
85 if (!imageMapObj)
86 return;
87
88 bool doReorderEvent = false;
89 nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(this);
90
91 // Remove areas that are not a valid part of the image map anymore.
92 for (int32_t childIdx = mChildren.Length() - 1; childIdx >= 0; childIdx--) {
93 Accessible* area = mChildren.ElementAt(childIdx);
94 if (area->GetContent()->GetPrimaryFrame())
95 continue;
96
97 if (aDoFireEvents) {
98 nsRefPtr<AccHideEvent> event = new AccHideEvent(area, area->GetContent());
99 mDoc->FireDelayedEvent(event);
100 reorderEvent->AddSubMutationEvent(event);
101 doReorderEvent = true;
102 }
103
104 RemoveChild(area);
105 }
106
107 // Insert new areas into the tree.
108 uint32_t areaElmCount = imageMapObj->AreaCount();
109 for (uint32_t idx = 0; idx < areaElmCount; idx++) {
110 nsIContent* areaContent = imageMapObj->GetAreaAt(idx);
111
112 Accessible* area = mChildren.SafeElementAt(idx);
113 if (!area || area->GetContent() != areaContent) {
114 nsRefPtr<Accessible> area = new HTMLAreaAccessible(areaContent, mDoc);
115 mDoc->BindToDocument(area, aria::GetRoleMap(areaContent));
116
117 if (!InsertChildAt(idx, area)) {
118 mDoc->UnbindFromDocument(area);
119 break;
120 }
121
122 if (aDoFireEvents) {
123 nsRefPtr<AccShowEvent> event = new AccShowEvent(area, areaContent);
124 mDoc->FireDelayedEvent(event);
125 reorderEvent->AddSubMutationEvent(event);
126 doReorderEvent = true;
127 }
128 }
129 }
130
131 // Fire reorder event if needed.
132 if (doReorderEvent)
133 mDoc->FireDelayedEvent(reorderEvent);
134 }
135
136 Accessible*
137 HTMLImageMapAccessible::GetChildAccessibleFor(const nsINode* aNode) const
138 {
139 uint32_t length = mChildren.Length();
140 for (uint32_t i = 0; i < length; i++) {
141 Accessible* area = mChildren[i];
142 if (area->GetContent() == aNode)
143 return area;
144 }
145
146 return nullptr;
147 }
148
149 ////////////////////////////////////////////////////////////////////////////////
150 // HTMLImageMapAccessible: Accessible protected
151
152 void
153 HTMLImageMapAccessible::CacheChildren()
154 {
155 UpdateChildAreas(false);
156 }
157
158
159 ////////////////////////////////////////////////////////////////////////////////
160 // HTMLAreaAccessible
161 ////////////////////////////////////////////////////////////////////////////////
162
163 HTMLAreaAccessible::
164 HTMLAreaAccessible(nsIContent* aContent, DocAccessible* aDoc) :
165 HTMLLinkAccessible(aContent, aDoc)
166 {
167 // Make HTML area DOM element not accessible. HTML image map accessible
168 // manages its tree itself.
169 mStateFlags |= eNotNodeMapEntry;
170 }
171
172 ////////////////////////////////////////////////////////////////////////////////
173 // HTMLAreaAccessible: nsIAccessible
174
175 ENameValueFlag
176 HTMLAreaAccessible::NativeName(nsString& aName)
177 {
178 ENameValueFlag nameFlag = Accessible::NativeName(aName);
179 if (!aName.IsEmpty())
180 return nameFlag;
181
182 if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName))
183 GetValue(aName);
184
185 return eNameOK;
186 }
187
188 void
189 HTMLAreaAccessible::Description(nsString& aDescription)
190 {
191 aDescription.Truncate();
192
193 // Still to do - follow IE's standard here
194 nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(mContent));
195 if (area)
196 area->GetShape(aDescription);
197 }
198
199 ////////////////////////////////////////////////////////////////////////////////
200 // HTMLAreaAccessible: Accessible public
201
202 Accessible*
203 HTMLAreaAccessible::ChildAtPoint(int32_t aX, int32_t aY,
204 EWhichChildAtPoint aWhichChild)
205 {
206 // Don't walk into area accessibles.
207 return this;
208 }
209
210 ////////////////////////////////////////////////////////////////////////////////
211 // HTMLImageMapAccessible: HyperLinkAccessible
212
213 uint32_t
214 HTMLAreaAccessible::StartOffset()
215 {
216 // Image map accessible is not hypertext accessible therefore
217 // StartOffset/EndOffset implementations of Accessible doesn't work here.
218 // We return index in parent because image map contains area links only which
219 // are embedded objects.
220 // XXX: image map should be a hypertext accessible.
221 return IndexInParent();
222 }
223
224 uint32_t
225 HTMLAreaAccessible::EndOffset()
226 {
227 return IndexInParent() + 1;
228 }
229
230 ////////////////////////////////////////////////////////////////////////////////
231 // HTMLAreaAccessible: Accessible protected
232
233 void
234 HTMLAreaAccessible::CacheChildren()
235 {
236 // No children for aria accessible.
237 }
238
239 void
240 HTMLAreaAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame)
241 {
242 nsIFrame* frame = GetFrame();
243 if (!frame)
244 return;
245
246 nsImageFrame* imageFrame = do_QueryFrame(frame);
247 nsImageMap* map = imageFrame->GetImageMap();
248
249 nsresult rv = map->GetBoundsForAreaContent(mContent, aBounds);
250 if (NS_FAILED(rv))
251 return;
252
253 // XXX Areas are screwy; they return their rects as a pair of points, one pair
254 // stored into the width and height.
255 aBounds.width -= aBounds.x;
256 aBounds.height -= aBounds.y;
257
258 *aBoundingFrame = frame;
259 }

mercurial