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 "ImageAccessible.h"
8 #include "nsAccUtils.h"
10 #include "AccIterator.h"
13 #include "imgIContainer.h"
14 #include "imgIRequest.h"
15 #include "nsGenericHTMLElement.h"
16 #include "nsIDocument.h"
17 #include "nsIImageLoadingContent.h"
18 #include "nsIPresShell.h"
19 #include "nsIServiceManager.h"
20 #include "nsIDOMHTMLImageElement.h"
21 #include "nsIPersistentProperties2.h"
22 #include "nsPIDOMWindow.h"
25 using namespace mozilla::a11y
;
27 ////////////////////////////////////////////////////////////////////////////////
29 ////////////////////////////////////////////////////////////////////////////////
32 ImageAccessible(nsIContent
* aContent
, DocAccessible
* aDoc
) :
33 LinkableAccessible(aContent
, aDoc
)
38 ImageAccessible::~ImageAccessible()
42 NS_IMPL_ISUPPORTS_INHERITED(ImageAccessible
, Accessible
,
45 ////////////////////////////////////////////////////////////////////////////////
49 ImageAccessible::NativeState()
51 // The state is a bitfield, get our inherited state, then logically OR it with
52 // states::ANIMATED if this is an animated image.
54 uint64_t state
= LinkableAccessible::NativeState();
56 nsCOMPtr
<nsIImageLoadingContent
> content(do_QueryInterface(mContent
));
57 nsCOMPtr
<imgIRequest
> imageRequest
;
60 content
->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST
,
61 getter_AddRefs(imageRequest
));
63 nsCOMPtr
<imgIContainer
> imgContainer
;
65 imageRequest
->GetImage(getter_AddRefs(imgContainer
));
69 imgContainer
->GetAnimated(&animated
);
71 state
|= states::ANIMATED
;
78 ImageAccessible::NativeName(nsString
& aName
)
81 mContent
->GetAttr(kNameSpaceID_None
, nsGkAtoms::alt
, aName
);
85 ENameValueFlag nameFlag
= Accessible::NativeName(aName
);
89 // No accessible name but empty 'alt' attribute is present. If further name
90 // computation algorithm doesn't provide non empty name then it means
91 // an empty 'alt' attribute was used to indicate a decorative image (see
92 // Accessible::Name() method for details).
93 return hasAltAttrib
? eNoNameOnPurpose
: eNameOK
;
97 ImageAccessible::NativeRole()
99 return roles::GRAPHIC
;
102 ////////////////////////////////////////////////////////////////////////////////
106 ImageAccessible::ActionCount()
108 uint8_t actionCount
= LinkableAccessible::ActionCount();
109 return HasLongDesc() ? actionCount
+ 1 : actionCount
;
113 ImageAccessible::GetActionName(uint8_t aIndex
, nsAString
& aName
)
118 return NS_ERROR_FAILURE
;
120 if (IsLongDescIndex(aIndex
) && HasLongDesc()) {
121 aName
.AssignLiteral("showlongdesc");
124 return LinkableAccessible::GetActionName(aIndex
, aName
);
128 ImageAccessible::DoAction(uint8_t aIndex
)
131 return NS_ERROR_FAILURE
;
133 // Get the long description uri and open in a new window.
134 if (!IsLongDescIndex(aIndex
))
135 return LinkableAccessible::DoAction(aIndex
);
137 nsCOMPtr
<nsIURI
> uri
= GetLongDescURI();
139 return NS_ERROR_INVALID_ARG
;
141 nsAutoCString utf8spec
;
142 uri
->GetSpec(utf8spec
);
143 NS_ConvertUTF8toUTF16
spec(utf8spec
);
145 nsIDocument
* document
= mContent
->OwnerDoc();
146 nsCOMPtr
<nsPIDOMWindow
> piWindow
= document
->GetWindow();
147 nsCOMPtr
<nsIDOMWindow
> win
= do_QueryInterface(piWindow
);
148 NS_ENSURE_STATE(win
);
150 nsCOMPtr
<nsIDOMWindow
> tmp
;
151 return win
->Open(spec
, EmptyString(), EmptyString(),
152 getter_AddRefs(tmp
));
155 ////////////////////////////////////////////////////////////////////////////////
156 // nsIAccessibleImage
159 ImageAccessible::GetImagePosition(uint32_t aCoordType
, int32_t* aX
, int32_t* aY
)
161 int32_t width
, height
;
162 nsresult rv
= GetBounds(aX
, aY
, &width
, &height
);
166 nsAccUtils::ConvertScreenCoordsTo(aX
, aY
, aCoordType
, this);
171 ImageAccessible::GetImageSize(int32_t* aWidth
, int32_t* aHeight
)
174 return GetBounds(&x
, &y
, aWidth
, aHeight
);
178 already_AddRefed
<nsIPersistentProperties
>
179 ImageAccessible::NativeAttributes()
181 nsCOMPtr
<nsIPersistentProperties
> attributes
=
182 LinkableAccessible::NativeAttributes();
185 mContent
->GetAttr(kNameSpaceID_None
, nsGkAtoms::src
, src
);
187 nsAccUtils::SetAccAttr(attributes
, nsGkAtoms::src
, src
);
189 return attributes
.forget();
192 ////////////////////////////////////////////////////////////////////////////////
195 already_AddRefed
<nsIURI
>
196 ImageAccessible::GetLongDescURI() const
198 if (mContent
->HasAttr(kNameSpaceID_None
, nsGkAtoms::longdesc
)) {
199 nsGenericHTMLElement
* element
=
200 nsGenericHTMLElement::FromContent(mContent
);
202 nsCOMPtr
<nsIURI
> uri
;
203 element
->GetURIAttr(nsGkAtoms::longdesc
, nullptr, getter_AddRefs(uri
));
208 DocAccessible
* document
= Document();
210 IDRefsIterator
iter(document
, mContent
, nsGkAtoms::aria_describedby
);
211 while (nsIContent
* target
= iter
.NextElem()) {
212 if ((target
->IsHTML(nsGkAtoms::a
) || target
->IsHTML(nsGkAtoms::area
)) &&
213 target
->HasAttr(kNameSpaceID_None
, nsGkAtoms::href
)) {
214 nsGenericHTMLElement
* element
=
215 nsGenericHTMLElement::FromContent(target
);
217 nsCOMPtr
<nsIURI
> uri
;
218 element
->GetURIAttr(nsGkAtoms::href
, nullptr, getter_AddRefs(uri
));
228 ImageAccessible::IsLongDescIndex(uint8_t aIndex
)
230 return aIndex
== LinkableAccessible::ActionCount();