accessible/src/generic/ImageAccessible.cpp

branch
TOR_BUG_9701
changeset 3
141e0f1194b1
equal deleted inserted replaced
-1:000000000000 0:b198f8610c5d
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 "ImageAccessible.h"
7
8 #include "nsAccUtils.h"
9 #include "Role.h"
10 #include "AccIterator.h"
11 #include "States.h"
12
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"
24
25 using namespace mozilla::a11y;
26
27 ////////////////////////////////////////////////////////////////////////////////
28 // ImageAccessible
29 ////////////////////////////////////////////////////////////////////////////////
30
31 ImageAccessible::
32 ImageAccessible(nsIContent* aContent, DocAccessible* aDoc) :
33 LinkableAccessible(aContent, aDoc)
34 {
35 mType = eImageType;
36 }
37
38 NS_IMPL_ISUPPORTS_INHERITED(ImageAccessible, Accessible,
39 nsIAccessibleImage)
40
41 ////////////////////////////////////////////////////////////////////////////////
42 // Accessible public
43
44 uint64_t
45 ImageAccessible::NativeState()
46 {
47 // The state is a bitfield, get our inherited state, then logically OR it with
48 // states::ANIMATED if this is an animated image.
49
50 uint64_t state = LinkableAccessible::NativeState();
51
52 nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(mContent));
53 nsCOMPtr<imgIRequest> imageRequest;
54
55 if (content)
56 content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
57 getter_AddRefs(imageRequest));
58
59 nsCOMPtr<imgIContainer> imgContainer;
60 if (imageRequest)
61 imageRequest->GetImage(getter_AddRefs(imgContainer));
62
63 if (imgContainer) {
64 bool animated;
65 imgContainer->GetAnimated(&animated);
66 if (animated)
67 state |= states::ANIMATED;
68 }
69
70 return state;
71 }
72
73 ENameValueFlag
74 ImageAccessible::NativeName(nsString& aName)
75 {
76 bool hasAltAttrib =
77 mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName);
78 if (!aName.IsEmpty())
79 return eNameOK;
80
81 ENameValueFlag nameFlag = Accessible::NativeName(aName);
82 if (!aName.IsEmpty())
83 return nameFlag;
84
85 // No accessible name but empty 'alt' attribute is present. If further name
86 // computation algorithm doesn't provide non empty name then it means
87 // an empty 'alt' attribute was used to indicate a decorative image (see
88 // Accessible::Name() method for details).
89 return hasAltAttrib ? eNoNameOnPurpose : eNameOK;
90 }
91
92 role
93 ImageAccessible::NativeRole()
94 {
95 return roles::GRAPHIC;
96 }
97
98 ////////////////////////////////////////////////////////////////////////////////
99 // nsIAccessible
100
101 uint8_t
102 ImageAccessible::ActionCount()
103 {
104 uint8_t actionCount = LinkableAccessible::ActionCount();
105 return HasLongDesc() ? actionCount + 1 : actionCount;
106 }
107
108 NS_IMETHODIMP
109 ImageAccessible::GetActionName(uint8_t aIndex, nsAString& aName)
110 {
111 aName.Truncate();
112
113 if (IsDefunct())
114 return NS_ERROR_FAILURE;
115
116 if (IsLongDescIndex(aIndex) && HasLongDesc()) {
117 aName.AssignLiteral("showlongdesc");
118 return NS_OK;
119 }
120 return LinkableAccessible::GetActionName(aIndex, aName);
121 }
122
123 NS_IMETHODIMP
124 ImageAccessible::DoAction(uint8_t aIndex)
125 {
126 if (IsDefunct())
127 return NS_ERROR_FAILURE;
128
129 // Get the long description uri and open in a new window.
130 if (!IsLongDescIndex(aIndex))
131 return LinkableAccessible::DoAction(aIndex);
132
133 nsCOMPtr<nsIURI> uri = GetLongDescURI();
134 if (!uri)
135 return NS_ERROR_INVALID_ARG;
136
137 nsAutoCString utf8spec;
138 uri->GetSpec(utf8spec);
139 NS_ConvertUTF8toUTF16 spec(utf8spec);
140
141 nsIDocument* document = mContent->OwnerDoc();
142 nsCOMPtr<nsPIDOMWindow> piWindow = document->GetWindow();
143 nsCOMPtr<nsIDOMWindow> win = do_QueryInterface(piWindow);
144 NS_ENSURE_STATE(win);
145
146 nsCOMPtr<nsIDOMWindow> tmp;
147 return win->Open(spec, EmptyString(), EmptyString(),
148 getter_AddRefs(tmp));
149 }
150
151 ////////////////////////////////////////////////////////////////////////////////
152 // nsIAccessibleImage
153
154 NS_IMETHODIMP
155 ImageAccessible::GetImagePosition(uint32_t aCoordType, int32_t* aX, int32_t* aY)
156 {
157 int32_t width, height;
158 nsresult rv = GetBounds(aX, aY, &width, &height);
159 if (NS_FAILED(rv))
160 return rv;
161
162 nsAccUtils::ConvertScreenCoordsTo(aX, aY, aCoordType, this);
163 return NS_OK;
164 }
165
166 NS_IMETHODIMP
167 ImageAccessible::GetImageSize(int32_t* aWidth, int32_t* aHeight)
168 {
169 int32_t x, y;
170 return GetBounds(&x, &y, aWidth, aHeight);
171 }
172
173 // Accessible
174 already_AddRefed<nsIPersistentProperties>
175 ImageAccessible::NativeAttributes()
176 {
177 nsCOMPtr<nsIPersistentProperties> attributes =
178 LinkableAccessible::NativeAttributes();
179
180 nsAutoString src;
181 mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::src, src);
182 if (!src.IsEmpty())
183 nsAccUtils::SetAccAttr(attributes, nsGkAtoms::src, src);
184
185 return attributes.forget();
186 }
187
188 ////////////////////////////////////////////////////////////////////////////////
189 // Private methods
190
191 already_AddRefed<nsIURI>
192 ImageAccessible::GetLongDescURI() const
193 {
194 if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::longdesc)) {
195 nsGenericHTMLElement* element =
196 nsGenericHTMLElement::FromContent(mContent);
197 if (element) {
198 nsCOMPtr<nsIURI> uri;
199 element->GetURIAttr(nsGkAtoms::longdesc, nullptr, getter_AddRefs(uri));
200 return uri.forget();
201 }
202 }
203
204 DocAccessible* document = Document();
205 if (document) {
206 IDRefsIterator iter(document, mContent, nsGkAtoms::aria_describedby);
207 while (nsIContent* target = iter.NextElem()) {
208 if ((target->IsHTML(nsGkAtoms::a) || target->IsHTML(nsGkAtoms::area)) &&
209 target->HasAttr(kNameSpaceID_None, nsGkAtoms::href)) {
210 nsGenericHTMLElement* element =
211 nsGenericHTMLElement::FromContent(target);
212
213 nsCOMPtr<nsIURI> uri;
214 element->GetURIAttr(nsGkAtoms::href, nullptr, getter_AddRefs(uri));
215 return uri.forget();
216 }
217 }
218 }
219
220 return nullptr;
221 }
222
223 bool
224 ImageAccessible::IsLongDescIndex(uint8_t aIndex)
225 {
226 return aIndex == LinkableAccessible::ActionCount();
227 }
228

mercurial