Fix typo in 9b54bd30006c008b4a951331b273613d5bac3abf
[pm.git] / accessible / html / HTMLImageMapAccessible.cpp
blob2f6692b5c3e7ae972a3bff8b875a358ae0d1a90d
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/. */
6 #include "HTMLImageMapAccessible.h"
8 #include "ARIAMap.h"
9 #include "nsAccUtils.h"
10 #include "DocAccessible-inl.h"
11 #include "Role.h"
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"
22 using namespace mozilla::a11y;
24 ////////////////////////////////////////////////////////////////////////////////
25 // HTMLImageMapAccessible
26 ////////////////////////////////////////////////////////////////////////////////
28 HTMLImageMapAccessible::
29 HTMLImageMapAccessible(nsIContent* aContent, DocAccessible* aDoc) :
30 ImageAccessibleWrap(aContent, aDoc)
32 mType = eImageMapType;
35 ////////////////////////////////////////////////////////////////////////////////
36 // HTMLImageMapAccessible: nsISupports
38 NS_IMPL_ISUPPORTS_INHERITED0(HTMLImageMapAccessible, ImageAccessible)
40 ////////////////////////////////////////////////////////////////////////////////
41 // HTMLImageMapAccessible: Accessible public
43 role
44 HTMLImageMapAccessible::NativeRole()
46 return roles::IMAGE_MAP;
49 ////////////////////////////////////////////////////////////////////////////////
50 // HTMLImageMapAccessible: HyperLinkAccessible
52 uint32_t
53 HTMLImageMapAccessible::AnchorCount()
55 return ChildCount();
58 Accessible*
59 HTMLImageMapAccessible::AnchorAt(uint32_t aAnchorIndex)
61 return GetChildAt(aAnchorIndex);
64 already_AddRefed<nsIURI>
65 HTMLImageMapAccessible::AnchorURIAt(uint32_t aAnchorIndex)
67 Accessible* area = GetChildAt(aAnchorIndex);
68 if (!area)
69 return nullptr;
71 nsIContent* linkContent = area->GetContent();
72 return linkContent ? linkContent->GetHrefURI() : nullptr;
75 ////////////////////////////////////////////////////////////////////////////////
76 // HTMLImageMapAccessible: public
78 void
79 HTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
81 nsImageFrame* imageFrame = do_QueryFrame(mContent->GetPrimaryFrame());
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;
88 bool treeChanged = false;
89 AutoTreeMutation mut(this);
90 nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(this);
92 // Remove areas that are not a valid part of the image map anymore.
93 for (int32_t childIdx = mChildren.Length() - 1; childIdx >= 0; childIdx--) {
94 Accessible* area = mChildren.ElementAt(childIdx);
95 if (area->GetContent()->GetPrimaryFrame())
96 continue;
98 if (aDoFireEvents) {
99 nsRefPtr<AccHideEvent> event = new AccHideEvent(area, area->GetContent());
100 mDoc->FireDelayedEvent(event);
101 reorderEvent->AddSubMutationEvent(event);
104 RemoveChild(area);
105 treeChanged = true;
108 // Insert new areas into the tree.
109 uint32_t areaElmCount = imageMapObj->AreaCount();
110 for (uint32_t idx = 0; idx < areaElmCount; idx++) {
111 nsIContent* areaContent = imageMapObj->GetAreaAt(idx);
113 Accessible* area = mChildren.SafeElementAt(idx);
114 if (!area || area->GetContent() != areaContent) {
115 nsRefPtr<Accessible> area = new HTMLAreaAccessible(areaContent, mDoc);
116 mDoc->BindToDocument(area, aria::GetRoleMap(areaContent));
118 if (!InsertChildAt(idx, area)) {
119 mDoc->UnbindFromDocument(area);
120 break;
123 if (aDoFireEvents) {
124 nsRefPtr<AccShowEvent> event = new AccShowEvent(area, areaContent);
125 mDoc->FireDelayedEvent(event);
126 reorderEvent->AddSubMutationEvent(event);
129 treeChanged = true;
133 // Fire reorder event if needed.
134 if (treeChanged && aDoFireEvents)
135 mDoc->FireDelayedEvent(reorderEvent);
137 if (!treeChanged)
138 mut.mInvalidationRequired = false;
141 Accessible*
142 HTMLImageMapAccessible::GetChildAccessibleFor(const nsINode* aNode) const
144 uint32_t length = mChildren.Length();
145 for (uint32_t i = 0; i < length; i++) {
146 Accessible* area = mChildren[i];
147 if (area->GetContent() == aNode)
148 return area;
151 return nullptr;
154 ////////////////////////////////////////////////////////////////////////////////
155 // HTMLImageMapAccessible: Accessible protected
157 void
158 HTMLImageMapAccessible::CacheChildren()
160 UpdateChildAreas(false);
164 ////////////////////////////////////////////////////////////////////////////////
165 // HTMLAreaAccessible
166 ////////////////////////////////////////////////////////////////////////////////
168 HTMLAreaAccessible::
169 HTMLAreaAccessible(nsIContent* aContent, DocAccessible* aDoc) :
170 HTMLLinkAccessible(aContent, aDoc)
172 // Make HTML area DOM element not accessible. HTML image map accessible
173 // manages its tree itself.
174 mStateFlags |= eNotNodeMapEntry;
177 ////////////////////////////////////////////////////////////////////////////////
178 // HTMLAreaAccessible: Accessible
180 ENameValueFlag
181 HTMLAreaAccessible::NativeName(nsString& aName)
183 ENameValueFlag nameFlag = Accessible::NativeName(aName);
184 if (!aName.IsEmpty())
185 return nameFlag;
187 if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName))
188 Value(aName);
190 return eNameOK;
193 void
194 HTMLAreaAccessible::Description(nsString& aDescription)
196 aDescription.Truncate();
198 // Still to do - follow IE's standard here
199 nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(mContent));
200 if (area)
201 area->GetShape(aDescription);
204 ////////////////////////////////////////////////////////////////////////////////
205 // HTMLAreaAccessible: Accessible public
207 Accessible*
208 HTMLAreaAccessible::ChildAtPoint(int32_t aX, int32_t aY,
209 EWhichChildAtPoint aWhichChild)
211 // Don't walk into area accessibles.
212 return this;
215 ////////////////////////////////////////////////////////////////////////////////
216 // HTMLImageMapAccessible: HyperLinkAccessible
218 uint32_t
219 HTMLAreaAccessible::StartOffset()
221 // Image map accessible is not hypertext accessible therefore
222 // StartOffset/EndOffset implementations of Accessible doesn't work here.
223 // We return index in parent because image map contains area links only which
224 // are embedded objects.
225 // XXX: image map should be a hypertext accessible.
226 return IndexInParent();
229 uint32_t
230 HTMLAreaAccessible::EndOffset()
232 return IndexInParent() + 1;
235 ////////////////////////////////////////////////////////////////////////////////
236 // HTMLAreaAccessible: Accessible protected
238 void
239 HTMLAreaAccessible::CacheChildren()
241 // No children for aria accessible.
244 nsRect
245 HTMLAreaAccessible::RelativeBounds(nsIFrame** aBoundingFrame) const
247 nsIFrame* frame = GetFrame();
248 if (!frame)
249 return nsRect();
251 nsImageFrame* imageFrame = do_QueryFrame(frame);
252 nsImageMap* map = imageFrame->GetImageMap();
254 nsRect bounds;
255 nsresult rv = map->GetBoundsForAreaContent(mContent, bounds);
256 if (NS_FAILED(rv))
257 return nsRect();
259 // XXX Areas are screwy; they return their rects as a pair of points, one pair
260 // stored into the width and height.
261 *aBoundingFrame = frame;
262 bounds.width -= bounds.x;
263 bounds.height -= bounds.y;
264 return bounds;