Bumping manifests a=b2g-bump
[gecko.git] / accessible / generic / ImageAccessible.cpp
blob2d4b293c964180b33c2c98ae791bcd01a29880b0
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"
9 #include "Role.h"
10 #include "AccIterator.h"
11 #include "States.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"
23 #include "nsIURI.h"
25 using namespace mozilla::a11y;
27 ////////////////////////////////////////////////////////////////////////////////
28 // ImageAccessible
29 ////////////////////////////////////////////////////////////////////////////////
31 ImageAccessible::
32 ImageAccessible(nsIContent* aContent, DocAccessible* aDoc) :
33 LinkableAccessible(aContent, aDoc)
35 mType = eImageType;
38 ImageAccessible::~ImageAccessible()
42 NS_IMPL_ISUPPORTS_INHERITED(ImageAccessible, Accessible,
43 nsIAccessibleImage)
45 ////////////////////////////////////////////////////////////////////////////////
46 // Accessible public
48 uint64_t
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;
59 if (content)
60 content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
61 getter_AddRefs(imageRequest));
63 nsCOMPtr<imgIContainer> imgContainer;
64 if (imageRequest)
65 imageRequest->GetImage(getter_AddRefs(imgContainer));
67 if (imgContainer) {
68 bool animated;
69 imgContainer->GetAnimated(&animated);
70 if (animated)
71 state |= states::ANIMATED;
74 return state;
77 ENameValueFlag
78 ImageAccessible::NativeName(nsString& aName)
80 bool hasAltAttrib =
81 mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName);
82 if (!aName.IsEmpty())
83 return eNameOK;
85 ENameValueFlag nameFlag = Accessible::NativeName(aName);
86 if (!aName.IsEmpty())
87 return nameFlag;
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;
96 role
97 ImageAccessible::NativeRole()
99 return roles::GRAPHIC;
102 ////////////////////////////////////////////////////////////////////////////////
103 // nsIAccessible
105 uint8_t
106 ImageAccessible::ActionCount()
108 uint8_t actionCount = LinkableAccessible::ActionCount();
109 return HasLongDesc() ? actionCount + 1 : actionCount;
112 NS_IMETHODIMP
113 ImageAccessible::GetActionName(uint8_t aIndex, nsAString& aName)
115 aName.Truncate();
117 if (IsDefunct())
118 return NS_ERROR_FAILURE;
120 if (IsLongDescIndex(aIndex) && HasLongDesc()) {
121 aName.AssignLiteral("showlongdesc");
122 return NS_OK;
124 return LinkableAccessible::GetActionName(aIndex, aName);
127 NS_IMETHODIMP
128 ImageAccessible::DoAction(uint8_t aIndex)
130 if (IsDefunct())
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();
138 if (!uri)
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
158 NS_IMETHODIMP
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);
163 if (NS_FAILED(rv))
164 return rv;
166 nsAccUtils::ConvertScreenCoordsTo(aX, aY, aCoordType, this);
167 return NS_OK;
170 NS_IMETHODIMP
171 ImageAccessible::GetImageSize(int32_t* aWidth, int32_t* aHeight)
173 int32_t x, y;
174 return GetBounds(&x, &y, aWidth, aHeight);
177 // Accessible
178 already_AddRefed<nsIPersistentProperties>
179 ImageAccessible::NativeAttributes()
181 nsCOMPtr<nsIPersistentProperties> attributes =
182 LinkableAccessible::NativeAttributes();
184 nsAutoString src;
185 mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::src, src);
186 if (!src.IsEmpty())
187 nsAccUtils::SetAccAttr(attributes, nsGkAtoms::src, src);
189 return attributes.forget();
192 ////////////////////////////////////////////////////////////////////////////////
193 // Private methods
195 already_AddRefed<nsIURI>
196 ImageAccessible::GetLongDescURI() const
198 if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::longdesc)) {
199 nsGenericHTMLElement* element =
200 nsGenericHTMLElement::FromContent(mContent);
201 if (element) {
202 nsCOMPtr<nsIURI> uri;
203 element->GetURIAttr(nsGkAtoms::longdesc, nullptr, getter_AddRefs(uri));
204 return uri.forget();
208 DocAccessible* document = Document();
209 if (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));
219 return uri.forget();
224 return nullptr;
227 bool
228 ImageAccessible::IsLongDescIndex(uint8_t aIndex)
230 return aIndex == LinkableAccessible::ActionCount();