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"
9 #include "nsAccUtils.h"
10 #include "DocAccessible-inl.h"
13 #include "nsIDOMHTMLCollection.h"
14 #include "nsIServiceManager.h"
15 #include "nsIDOMElement.h"
16 #include "nsIDOMHTMLAreaElement.h"
18 #include "nsImageFrame.h"
19 #include "nsImageMap.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
44 HTMLImageMapAccessible::NativeRole()
46 return roles::IMAGE_MAP
;
49 ////////////////////////////////////////////////////////////////////////////////
50 // HTMLImageMapAccessible: HyperLinkAccessible
53 HTMLImageMapAccessible::AnchorCount()
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
);
71 nsIContent
* linkContent
= area
->GetContent();
72 return linkContent
? linkContent
->GetHrefURI() : nullptr;
75 ////////////////////////////////////////////////////////////////////////////////
76 // HTMLImageMapAccessible: public
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();
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())
99 nsRefPtr
<AccHideEvent
> event
= new AccHideEvent(area
, area
->GetContent());
100 mDoc
->FireDelayedEvent(event
);
101 reorderEvent
->AddSubMutationEvent(event
);
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
);
124 nsRefPtr
<AccShowEvent
> event
= new AccShowEvent(area
, areaContent
);
125 mDoc
->FireDelayedEvent(event
);
126 reorderEvent
->AddSubMutationEvent(event
);
133 // Fire reorder event if needed.
134 if (treeChanged
&& aDoFireEvents
)
135 mDoc
->FireDelayedEvent(reorderEvent
);
138 mut
.mInvalidationRequired
= false;
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
)
154 ////////////////////////////////////////////////////////////////////////////////
155 // HTMLImageMapAccessible: Accessible protected
158 HTMLImageMapAccessible::CacheChildren()
160 UpdateChildAreas(false);
164 ////////////////////////////////////////////////////////////////////////////////
165 // HTMLAreaAccessible
166 ////////////////////////////////////////////////////////////////////////////////
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
181 HTMLAreaAccessible::NativeName(nsString
& aName
)
183 ENameValueFlag nameFlag
= Accessible::NativeName(aName
);
184 if (!aName
.IsEmpty())
187 if (!mContent
->GetAttr(kNameSpaceID_None
, nsGkAtoms::alt
, aName
))
194 HTMLAreaAccessible::Description(nsString
& aDescription
)
196 aDescription
.Truncate();
198 // Still to do - follow IE's standard here
199 nsCOMPtr
<nsIDOMHTMLAreaElement
> area(do_QueryInterface(mContent
));
201 area
->GetShape(aDescription
);
204 ////////////////////////////////////////////////////////////////////////////////
205 // HTMLAreaAccessible: Accessible public
208 HTMLAreaAccessible::ChildAtPoint(int32_t aX
, int32_t aY
,
209 EWhichChildAtPoint aWhichChild
)
211 // Don't walk into area accessibles.
215 ////////////////////////////////////////////////////////////////////////////////
216 // HTMLImageMapAccessible: HyperLinkAccessible
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();
230 HTMLAreaAccessible::EndOffset()
232 return IndexInParent() + 1;
235 ////////////////////////////////////////////////////////////////////////////////
236 // HTMLAreaAccessible: Accessible protected
239 HTMLAreaAccessible::CacheChildren()
241 // No children for aria accessible.
245 HTMLAreaAccessible::RelativeBounds(nsIFrame
** aBoundingFrame
) const
247 nsIFrame
* frame
= GetFrame();
251 nsImageFrame
* imageFrame
= do_QueryFrame(frame
);
252 nsImageMap
* map
= imageFrame
->GetImageMap();
255 nsresult rv
= map
->GetBoundsForAreaContent(mContent
, bounds
);
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
;